http://blog.csdn.net/bitcarmanlee/article/details/51213390
在各种算法中,向量计算是最常用的一种操作之一。传统的向量计算,学过中学数学的同学也能明白怎么做。但在现在的大数据环境下,数据一般都会比较稀疏,因此稀疏向量的计算,跟普通向量计算,还是存在一些不同。
首先,我们定义两个向量:
A=[x1,x2,⋯,xn] B=[y1,y2,⋯,yn] 定义A、B的点积为A∗B,要求A∗B=?最简单粗暴的方式
最直接的方式,当然就是按中学时候就学过的方法:
A∗B=x1∗y1+x2∗y2+⋯+xn∗yn 先不考虑乘法与加法的区别,也不考虑计算精度问题。如果按上述方式进行计算,总共进行了n次乘法,n-1次加法,总复杂度为2n-1。矩阵乘法的基本计算单元是向量之间的乘法,复杂度为n3。 在现在的大数据环境之下,n可能会很大,比如在计算广告,或者文本分类中,上百万维都是很正常的。而且这种向量都有一个特点,那就是很稀疏。如果没有很稀疏这个特点,那后面自然就无从谈起了。。。第一种思路
对于稀疏向量,自然而然的可以想到按一下方式进行存储:
A:{ <x1:location1>,<x2:location2>,⋯,<xi,locationi>} B:{ <y1:location1>,<y2:location2>,⋯,<yj,locationj>} 因为是稀疏向量,所以 i≪n,j≪n具体在计算A*B的时候,可以在向量A中循环,然后在向量B中进行二分查找。例如,在向量A中取出第一个非零元素,假设为<x1,location1>,在B中对location1进行二分。如果找到,计算乘积,如果找不到,自然为0. 那我们来估算一下算法的复杂度。在B中二分的复杂度为logj,A的长度为i,则这部分的总复杂度为ilogj,加法的最大情况为min(i,j)−1,总的复杂度为ilogj+min(i,j)−1
继续优化
当然,如果我们知道i , j 的大小,可以在小的向量上循环,在大的向量上二分,这样复杂度可以降低为 min(i,j)log(max(i,j))+min(i,j)−1 如果咱们不用二分查找,而是使用hash,则二分查找部分可以变为hash。假设hash的复杂度为1,那么总的复杂度为2min(i,j)。当然,我们忽略了创建hash的复杂度,以及hash碰撞的复杂度。 这样,总的复杂度就由最初的2n−1降到了2min(i,j)。
并行
如果n特别特别大,比如凤巢系统动不动就是号称上亿维度。这样i,j也不会特别小。如果是两个矩阵相乘,咱们前面提到的,复杂度为n3,这样就必须上并行计算了。搞数据的同学,对并行肯定不陌生,这里不再细述了。
代码验证
以上都是理论分析,为了验证实际中的运行效果,特意编写了一部分测试代码。测试代码如下
#!/usr/bin/env python#coding:utf-8'''Created on 2016年4月22日@author: lei.wang'''import time#二分查找 def bin_search(num,list): low = 0 high = len(list) - 1 while(low <= high): middle = (low + high) / 2 if list[middle] > num: high = middle - 1 elif list[middle] < num: low = middle + 1 else: return middle return -1 def t1(): all = 1000000 sparse_rate = 1000 vec_a = [0 for i in range(all)] vec_b = [0 for i in range(all)] list_none_zero = [sparse_rate*i for i in range(all / sparse_rate)] for i in list_none_zero: vec_a[i] = vec_b[i] = 1 sum = 0 #a,b分别不为0的位置 location_a = [i for i in range(0,all,sparse_rate)] location_b = [i for i in range(0,all,sparse_rate)] start = time.clock() for i in location_a: location = bin_search(i, location_b) #对应a不为0的位置,在b不为0的位置数组中查找是否存在 if location != -1: sum += vec_a[i] * vec_b[location_b[location]] #如果存在,将结果相加 end = time.clock() print "cost time is:",(end-start) print "sum is:",sum def t2(): all = 1000000 sparse_rate = 1000 vec_a = [0 for i in range(all)] vec_b = [0 for i in range(all)] list_of_none_zero = [sparse_rate*i for i in range(all / sparse_rate)] for i in list_of_none_zero: vec_a[i] = vec_b[i] = 1 sum = 0 start = time.clock() for i in range(all): sum += vec_a[i] * vec_b[i] end = time.clock() print "cost time is:",(end-start) print "sum is:",sum if __name__ == '__main__': t1() print print t2()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
bin_search是自己实现的二分查找,t1方法是用上面说到的二分查找的方式,t2方法就是最简单的直接遍历相乘的方式。
在mac上运行以上代码,结果如下:cost time is: 0.002319sum is: 1000 cost time is: 0.123861 sum is: 1000
- 1
- 2
- 3
- 4
- 5
- 6
可以看出,遍历的方式是二分查找的方式的54倍!按上述咱们的分析方式,遍历的方式应该是2∗106 的复杂度,二分查找的方式应该是103∗log1000,即104 左右的复杂度。二分查找的方式比遍历的方式应该要快100倍左右。根据咱们实验的结果来看,数量级上来说基本是差不多的。如果采取一些优化方式,比如用python自带的binset模块,应该会有更快的速度。
如果改变上述代码中的稀疏度,即改变sparse_rate的数值,例如将sparse_rate由1000改为10000,运行的结果如下:
cost time is: 0.000227sum is: 100 cost time is: 0.118492 sum is: 100
- 1
- 2
- 3
- 4
- 5
- 6
如果将sparse_rate改为100,运行的结果为:
cost time is: 0.034885sum is: 10000 cost time is: 0.124176 sum is: 10000
- 1
- 2
- 3
- 4
- 5
- 6
很容易看出来,对于遍历的方式来说,不管稀疏度为多少,耗时都是基本不变的。但是对于我们采用二分查找的方式来说,稀疏度越高,节省的计算资源,就越可观。
水木讨论区内容:
发信人: zhaihq (*_*翟翟), 信区: SearchEngineTech
标 题: [合集] 稀疏向量的计算方法发信站: 水木社区 (Wed Oct 15 22:58:19 2008), 站内☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Sun Mar 16 09:09:12 2008) 提到: 鉴于很多网友来信问此问题,我一并答复一下。 首先,我们来看什么是向量计算 假定向量A:{x1,x2,....xn} 向量B:{y1,y2,....yn} 现在要想知道A*B=?(这里的*为向量的点乘) 最直接的计算方法就是 x1*y1+x2*y2+...xn*yn (这里的*为一般乘法) 这里假定乘法和加法代价相同,浮点计算不被考虑,这样的计算方法代价为2N-1次计算。N为向量维度。 然而,在实际环境中,N很大可能上百万,甚至亿万,而向量中大部分元素为0,因此0和0相乘是没有意义的。 于是第一个优化的想法是将向量变为这样的模式 向量A:{<x1',loc1'>,<x2',loc2'>...<xn',locn'>} 向量B:{<y1',loc1'>,<y2',loc2'>...<yn',locn'>},这里locx表示元素的位置信息。 每个向量都不含零元素,或者接近于零的浮点数。显然向量数量远小于n,且向量A,B的长度取决于各自的非零元,不妨设向量A长度为m,向量B长度为n. 那么计算A*B,可以采用在向量A中循环,在向量B中二分的方法,例如找到向量A的首原素,<x1',loc1'>,将其位置loc1'在向量B中折半查找,直到找到,或者失败。 这样计算代价为mlogn + min(m,n),前部为查找代价,后部为加法代价,加法代价必然比min(m,n)还要小,最大情况下为min(m,n)-1。 进一步来看,如果在计算向量A和向量B乘法时,我们已经知道了它们各自的长度,那么可以在小的向量上循环,在大向量上二分,这样代价为min(m,n)log(max(m,n))+min(m,n) 当然也可以不使用二分,采用哈希,假定认为哈希的代价为O(1),那么总代价为2min(m,n)这里创建哈希也需要代价。 至此,我们由原来2N-1的计算,降低到2min(m,n), 如果N极大,而m,n也不小,这样等待一次向量计算也不短,而如果是矩阵相乘,向量相乘只是其中的一部,那么速度也无法容忍的话,可以采用并行计算的方法,通过切分,把一个大计算的一部分派遣到某台机器,而另一部分派遣到另一台机器,最后综合计算结果。并行处理软件包有很多,比如MPI,都可以尝试使用。 本文只讨论思想,不涉及细节,希望给大家带来一些启发。最后我再次推销一下这几个思想 precomputing caching mirroring distributing once-computing 有了难题都从这几个方面考虑,就有解了。。。☆─────────────────────────────────────☆ kingdy (天下无双) 于 (Sun Mar 16 09:28:22 2008) 提到:orz 梁老师【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Sun Mar 16 09:28:43 2008) 提到:沙发被你拿到了,我坐板凳【 在 kingdy (天下无双) 的大作中提到: 】orz 梁老师【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ kingdy (天下无双) 于 (Sun Mar 16 09:29:16 2008) 提到:今天天气这么好 梁老师也不出去玩 在这里布道 真是泽被苍生啊【 在 pennyliang (pennyliang) 的大作中提到: 】: 沙发被你拿到了,我坐板凳: orz 梁老师☆─────────────────────────────────────☆ psm (阿肥) 于 (Sun Mar 16 09:29:18 2008) 提到:以后弄一个沙发算法【 在 pennyliang (pennyliang) 的大作中提到: 】: 沙发被你拿到了,我坐板凳: orz 梁老师☆─────────────────────────────────────☆ fervvac (高远) 于 (Sun Mar 16 12:40:08 2008) 提到:Nice article. Just add a few comments1) An importnt property is that dimensions are sorted according to a globalorder and all sparse vectors encoded in that order as well. Therefore, theplain binary search * m times (m < n) is redundant in that the key to probe inthe other vector is monotonically increasing. A simple rememdy is to keepa bookmark of the last matching position (if no match, the largest i s.t v[i]<x) and the next binary search only need to be done within v[i+1, |v|].This can be viewed as a nice marriage of index-based and merge-basedapproaches.More sophisticated methods and their analysis can be found in 2) many application actually only want those <x, y> >= t, where t is a threhsold(e.g., near duplicate detection)If the vector is of binary type (only 0 or 1), prefix filtering can be used toconsider only those pairs s.t. their intersection (in binary case, <x, y> isintersection) *may* exceed t.In the general case, one can keep tract of the maximum value among the suffixof the vector and use it to prune candidate pairs.For more details, see (they've also published their source code)【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Sun Mar 16 13:23:57 2008) 提到:【 在 fervvac (高远) 的大作中提到: 】Nice article. Just add a few comments1) An importnt property is that dimensions are sorted according to a globalorder and all sparse vectors encoded in that order as well. Therefore, theplain binary search * m times (m < n) is redundant in that the key to probe inthe other vector is monotonically increasing. A simple rememdy is to keepa bookmark of the last matching position (if no match, the largest i s.t v[i]<x) and the next binary search only need to be done within v[i+1, |v|].This can be viewed as a nice marriage of index-based and merge-basedapproaches.More sophisticated methods and their analysis can be found in ~~~~~~~~~~~~~~~~~赞细节,的确如此,这大概也算是interpolative的概念,随着计算的不断深入,二分查找的实际范围是在收缩的。2) many application actually only want those <x, y> >= t, where t is a threhsold(e.g., near duplicate detection)If the vector is of binary type (only 0 or 1), prefix filtering can be used toconsider only those pairs s.t. their intersection (in binary case, <x, y> isintersection) *may* exceed t.In the general case, one can keep tract of the maximum value among the suffixof the vector and use it to prune candidate pairs. ~~~~~~~~~~~~~~~在赞细节,prune的细节我本打算写的,呵呵,实际上如何prune要根据实际应用,失去了一般性。For more details, see (they've also published their source code)【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ areqi (阿琦) 于 (Sun Mar 16 19:10:08 2008) 提到:看到这篇文章我有想m的冲动..【 在 fervvac (高远) 的大作中提到: 】: Nice article. Just add a few comments: 1) An importnt property is that dimensions are sorted according to a global: order and all sparse vectors encoded in that order as well. Therefore, the: ...................☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Sat Mar 22 09:28:22 2008) 提到:注意这里向量A和向量B都是按照其位置有序的,也可以采用类似归并排序的方法,两个指针找匹配,这也是线性的。。。但在有些情况下,二分的优良特性使得其在现实中的表现很可能是最佳的。【 在 pennyliang (pennyliang) 的大作中提到: 】: 标 题: 稀疏向量的计算方法: 发信站: 水木社区 (Sun Mar 16 09:09:12 2008), 站内:: 鉴于很多网友来信问此问题,我一并答复一下。:: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: 向量B:{y1,y2,....yn}: 现在要想知道A*B=?(这里的*为向量的点乘): 最直接的计算方法就是 x1*y1+x2*y2+...xn*yn (这里的*为一般乘法): 这里假定乘法和加法代价相同,浮点计算不被考虑,这样的计算方法代价为2N-1次计算。N为向量维度。:: 然而,在实际环境中,N很大可能上百万,甚至亿万,而向量中大部分元素为0,因此0和0相乘是没有意义的。:: 于是第一个优化的想法是将向量变为这样的模式: 向量A:{<x1',loc1'>,<x2',loc2'>...<xn',locn'>}: 向量B:{<y1',loc1'>,<y2',loc2'>...<yn',locn'>},这里locx表示元素的位置信息。: 每个向量都不含零元素,或者接近于零的浮点数。显然向量数量远小于n,且向量A,B的长度取决于各自的非零元,不妨设向量A长度为m,向量B长度为n.:: 那么计算A*B,可以采用在向量A中循环,在向量B中二分的方法,例如找到向量A的首原素,<x1',loc1'>,将其位置loc1'在向量B中折半查找,直到找到,或者失败。: 这样计算代价为mlogn + min(m,n),前部为查找代价,后部为加法代价,加法代价必然比min(m,n)还要小,最大情况下为min(m,n)-1。:: 进一步来看,如果在计算向量A和向量B乘法时,我们已经知道了它们各自的长度,那么可以在小的向量上循环,在大向量上二分,这样代价为min(m,n)log(max(m,n))+min(m,n):: 当然也可以不使用二分,采用哈希,假定认为哈希的代价为O(1),那么总代价为2min(m,n)这里创建哈希也需要代价。:: 至此,我们由原来2N-1的计算,降低到2min(m,n),:: 如果N极大,而m,n也不小,这样等待一次向量计算也不短,而如果是矩阵相乘,向量相乘只是其中的一部,那么速度也无法容忍的话,可以采用并行计算的方法,通过切分,把一个大计算的一部分派遣到某台机器,而另一部分派遣到另一台机器,最后综合计算结果。并行处理软件包有很多,比如MPI,都可以尝试使用。:: 本文只讨论思想,不涉及细节,希望给大家带来一些启发。最后我再次推销一下这几个思想: precomputing: caching: mirroring: distributing: once-computing: 有了难题都从这几个方面考虑,就有解了。。。:::::: --: 硕士要啥自行车啊::: ※ 修改:·pennyliang 于 Mar 16 09:15:37 2008 修改本文·[FROM: 58.30.83.*]: ※ 来源:·水木社区 newsmth.net·[FROM: 58.30.83.*]☆─────────────────────────────────────☆ mo7 (Moqi) 于 (Sat Mar 22 20:45:28 2008) 提到:好文,先mark之。【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ wqfeng (wqfeng) 于 (Sun Mar 23 21:48:35 2008) 提到:好文章,问个土问题,大家见谅啊!怎么把它保存起来啊?【 在 pennyliang (pennyliang) 的大作中提到: 】: 鉴于很多网友来信问此问题,我一并答复一下。: 首先,我们来看什么是向量计算: 假定向量A:{x1,x2,....xn}: ...................☆─────────────────────────────────────☆ semibookworm (劣币驱逐良币) 于 (Mon Mar 24 12:37:34 2008) 提到:对于第一种情况有个疑问假设两个倒排A (|A| = m), B (|B| = n), m<n对于最坏的情况,用二分查找需要 log(n)+log(n-1)+...+log(n-m+1) (log以2为底)这样做的复杂度是高于 m+n 的呀【 在 fervvac (高远) 的大作中提到: 】: Nice article. Just add a few comments: 1) An importnt property is that dimensions are sorted according to a global: order and all sparse vectors encoded in that order as well. Therefore, the: ...................☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Mon Mar 24 13:27:40 2008) 提到:一般都采用skipped invert listor sometimes,using fix-blocked invert list for binary search【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 对于第一种情况有个疑问: 假设两个倒排A (|A| = m), B (|B| = n), m<n: 对于最坏的情况,用二分查找需要 log(n)+log(n-1)+...+log(n-m+1) (log以2为底): ...................☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Mon Mar 24 13:34:15 2008) 提到:A: 3,5,7,10,21B:1,2,3,4,5,6,7...nstep 1: lgn to 3,step 2: lg(n-3) to 5,step 3: lg(n-5) to 7ifstep 1: lgn find 3: from 1 to 3step 2: lg(n-3) find 21: from 21 to 10step 3: lg(18) find 5: from 3 to 5。。。不知道我有没有讲清楚。。。【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 标 题: Re: 稀疏向量的计算方法: 发信站: 水木社区 (Mon Mar 24 12:37:34 2008), 站内:: 对于第一种情况有个疑问: 假设两个倒排A (|A| = m), B (|B| = n), m<n: 对于最坏的情况,用二分查找需要 log(n)+log(n-1)+...+log(n-m+1) (log以2为底): 这样做的复杂度是高于 m+n 的呀::: 【 在 fervvac (高远) 的大作中提到: 】: : Nice article. Just add a few comments: : 1) An importnt property is that dimensions are sorted according to a global: : order and all sparse vectors encoded in that order as well. Therefore, the: : ...................:: --:: ※ 修改:·semibookworm 于 Mar 24 12:46:54 2008 修改本文·[FROM: 219.133.51.*]: ※ 来源:·水木社区 newsmth.net·[FROM: 219.133.51.*]☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Mon Mar 24 13:36:50 2008) 提到:看一下插值编码的方法就很好理解了,pls search interpolative coding【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 标 题: Re: 稀疏向量的计算方法: 发信站: 水木社区 (Mon Mar 24 12:37:34 2008), 站内:: 对于第一种情况有个疑问: 假设两个倒排A (|A| = m), B (|B| = n), m<n: 对于最坏的情况,用二分查找需要 log(n)+log(n-1)+...+log(n-m+1) (log以2为底): 这样做的复杂度是高于 m+n 的呀::: 【 在 fervvac (高远) 的大作中提到: 】: : Nice article. Just add a few comments: : 1) An importnt property is that dimensions are sorted according to a global: : order and all sparse vectors encoded in that order as well. Therefore, the: : ...................:: --:: ※ 修改:·semibookworm 于 Mar 24 12:46:54 2008 修改本文·[FROM: 219.133.51.*]: ※ 来源:·水木社区 newsmth.net·[FROM: 219.133.51.*]☆─────────────────────────────────────☆ semibookworm (劣币驱逐良币) 于 (Mon Mar 24 16:33:15 2008) 提到:嗯,从两头找,区间缩减的可能会更快些但是只是对一个变形,并不能证明这么做会快啊最坏的情况依然存在【 在 pennyliang (pennyliang) 的大作中提到: 】: A: 3,5,7,10,21: B:1,2,3,4,5,6,7...n: step 1: lgn to 3,: ...................☆─────────────────────────────────────☆ semibookworm (劣币驱逐良币) 于 (Mon Mar 24 16:34:26 2008) 提到:这是图像、视频压缩方面的方法?【 在 pennyliang (pennyliang) 的大作中提到: 】: 看一下插值编码的方法就很好理解了,pls search interpolative coding☆─────────────────────────────────────☆ fervvac (高远) 于 (Mon Mar 24 17:34:15 2008) 提到:Sure, there is no overall winner. The worst case for naive binary searchis that everything you search for is right next down the array. The worstcase for sequential merge is that both lists needs to be scanned once, evenif there arre few matches in between.In practice, a hybrid method usually works better in general. There areexperiemntal study already. It was shown that galloping search usually isthe winner (a hybrid method). Richardo's divide-and-conquer method workswell when two lists are of similar sizes too. {these are right off the topof my head, better double check the references}【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 嗯,从两头找,区间缩减的可能会更快些: 但是只是对一个变形,并不能证明这么做会快啊: 最坏的情况依然存在: ...................☆─────────────────────────────────────☆ semibookworm (劣币驱逐良币) 于 (Tue Mar 25 17:52:16 2008) 提到:对于一个中等规模的稀疏向量问题,能否用位图来求交、求并呢?和这个方法相比,孰优孰劣?【 在 fervvac (高远) 的大作中提到: 】: Sure, there is no overall winner. The worst case for naive binary search: is that everything you search for is right next down the array. The worst: case for sequential merge is that both lists needs to be scanned once, even: ...................☆─────────────────────────────────────☆ fervvac (高远) 于 (Tue Mar 25 19:32:09 2008) 提到:Can you describe your scheme in more details? Are you paritioning the domainand index the partitions using bitmaps? I think people did use a similarparitioning idea to deal with teh case where the vectors are huge and mainlydisk-resident.I think you've touched a fine point: perhaps the only way we can break thelower bound of this problem is to use index (aka trading space for time). Avariant of this problem in XML query processing is to find pairs of objectsin two arrays, where o1.s < o2.s and o2.e < o1.e (a special kind of bandjoin). Both B+-trees and specialized indices were used to acclerate thejoin.【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 对于一个中等规模的稀疏向量问题,能否用位图来求交、求并呢?: 和这个方法相比,孰优孰劣?☆─────────────────────────────────────☆ pennyliang (pennyliang) 于 (Tue Mar 25 20:36:15 2008) 提到:位图很强大的。但越稀疏就越不适合于用位图结合到倒排,很多hybrid的方法,是把common term放在位图中,当然要看多common了,太comon就stop了。【 在 semibookworm (劣币驱逐良币) 的大作中提到: 】: 标 题: Re: 稀疏向量的计算方法: 发信站: 水木社区 (Tue Mar 25 17:52:16 2008), 站内::: 对于一个中等规模的稀疏向量问题,能否用位图来求交、求并呢?: 和这个方法相比,孰优孰劣?:: 【 在 fervvac (高远) 的大作中提到: 】: : Sure, there is no overall winner. The worst case for naive binary search: : is that everything you search for is right next down the array. The worst: : case for sequential merge is that both lists needs to be scanned once, even: : ...................:: --:: ※ 来源:·水木社区 newsmth.net·[FROM: 219.133.51.*]