a man to whom the difference between a pasture and a meadow seemed important, who got excited about sky color, who wrote a little poetry but not much fiction.
考虑这样一个问题,有一个无限长的 data stream,里面都是[ 1 , n ] [1,n] [ 1 , n ] 中的整数。是否有一个算法,可以维护不同时刻的不同整数个数?
很显然,我们可以暴力存储下所有的整数并进行统计。但在 streaming 中,我们希望:
stream 只支持单次、单向扫描。除非把先前时刻的内容存储下来,否则无法获取 stream 中当前时刻之前的信息。
不考虑时间复杂性,希望获得尽可能需要存储空间小的算法。
事实上,目前比较成熟的 streaming 算法都是 probabilistic estimation 答案,但是可以获得一个很好的空间复杂度,一般为O ( poly ( log N ) ) O(\text{poly}(\log N)) O ( poly ( log N ) ) 的水平。
# Distinct Elements Counting Problem
目标:估计 stream 中不同元素个数D E DE D E 。我们希望给出一个答案D D D 使得:
Pr [ ( 1 − ε ) D E ≤ D ≤ ( 1 + ε ) D E ] = 1 − P \text{Pr}[(1-\varepsilon)DE\leq D\leq(1+\varepsilon)DE]=1-P
Pr [ ( 1 − ε ) D E ≤ D ≤ ( 1 + ε ) D E ] = 1 − P
其中P P P 是一个常数。我们理解为,给出的答案以1 − P 1-P 1 − P 的概率误差小于1 ± ε 1\pm \varepsilon 1 ± ε 。实际中常常会出现P P P 可以取任意小常数的情况,就容易见到Pr = 0.99 \text{Pr}=0.99 Pr = 0 . 9 9 这样的证明。
一个简单的 gap 版本:给定一个T > 0 T>0 T > 0 ,给出一个算法输出 YES/NO 使得:
If D E > ( 1 + ε ) T DE>(1+\varepsilon)T D E > ( 1 + ε ) T , then answer YES with probability 1 − P 1-P 1 − P .
If D E < ( 1 − ε ) T DE<(1-\varepsilon)T D E < ( 1 − ε ) T , then answer NO with probability 1 − P 1-P 1 − P .
很显然,我们可以并行地运行log 1 + ε n \log_{1+\varepsilon}n log 1 + ε n 个 gap 版本,其中
T = 1 , 1 + ε , ( 1 + ε ) 2 , . . . , n T=1,1+\varepsilon,(1+\varepsilon)^2,...,n
T = 1 , 1 + ε , ( 1 + ε ) 2 , . . . , n
然后就可以得到原问题的答案在[ ( 1 + ε ) k , ( 1 − ε ) ( 1 + ε ) k + t ] [(1+\varepsilon)^k,(1-\varepsilon)(1+\varepsilon)^{k+t}] [ ( 1 + ε ) k , ( 1 − ε ) ( 1 + ε ) k + t ] 中。其中,t t t 是使得( 1 − ε ) ( 1 + ε ) t ≥ 1 (1-\varepsilon)(1+\varepsilon)^t\geq 1 ( 1 − ε ) ( 1 + ε ) t ≥ 1 的最小的整数t t t ,即t = ⌈ − log ( 1 − ε ) log ( 1 + ε ) ⌉ t=\lceil \frac{-\log(1-\varepsilon)}{\log(1+\varepsilon)}\rceil t = ⌈ l o g ( 1 + ε ) − l o g ( 1 − ε ) ⌉ 。
这样就可以得到一个可接受的解。复杂性的话总的复杂性显然需要乘上O ( log 1 + ε n ) ≈ log n / ε O(\log_{1+\varepsilon}n)\approx\log n/\varepsilon O ( log 1 + ε n ) ≈ log n / ε ,因为并行地运行。然后也是因为并行,失败的概率也需要乘以这个数。
算法(gap 版本):
随机选择一个集合S ⊆ { 1 , . . . , n } S\subseteq \{1,...,n\} S ⊆ { 1 , . . . , n } 使得,对每个i ∈ { 1 , . . . , n } i\in\{1,...,n\} i ∈ { 1 , . . . , n } :
Pr [ i ∈ S ] = 1 T \text{Pr}[i\in S]=\frac{1}{T}
Pr [ i ∈ S ] = T 1
维护Sum S ( x ) = ∑ i x i \text{Sum}_S(x)=\sum_i x_i Sum S ( x ) = ∑ i x i 。其中,data stream 中每次得到i i i ,就把x i x_i x i 加一。x x x 本来是一个全 0 的n n n 维向量。
如果Sum S ( x ) > 0 \text{Sum}_S(x)>0 Sum S ( x ) > 0 ,则回答 YES,否则若Sum S ( x ) = 0 \text{Sum}_S(x)=0 Sum S ( x ) = 0 ,则回答 NO。
我们可以分析下这个算法。
首先很显然地,Pr [ Sum S ( x ) = 0 ] = ( 1 − 1 T ) D E \text{Pr}[\text{Sum}_S(x)=0]=(1-\frac{1}{T})^{DE} Pr [ Sum S ( x ) = 0 ] = ( 1 − T 1 ) D E 。即Sum S ( x ) = 0 \text{Sum}_S(x)=0 Sum S ( x ) = 0 时,当且仅当所有出现过的i i i 都没被选择进S S S 。
那么就有(因为( 1 − 1 / T ) D E ≈ e − D E / T (1-1/T)^{DE}\approx e^{-DE/T} ( 1 − 1 / T ) D E ≈ e − D E / T 若T T T 足够大):
当D E > ( 1 + ε ) T DE>(1+\varepsilon)T D E > ( 1 + ε ) T 时,输出 NO 的概率小于e − ( 1 + ε ) < 1 / e − ε / 3 e^{-(1+\varepsilon)}<1/e-\varepsilon/3 e − ( 1 + ε ) < 1 / e − ε / 3 。
当D E < ( 1 − ε ) T DE<(1-\varepsilon)T D E < ( 1 − ε ) T 时,输出 NO 的概率大于e − ( 1 − ε ) > 1 / e + ε / 3 e^{-(1-\varepsilon)}>1/e+\varepsilon/3 e − ( 1 − ε ) > 1 / e + ε / 3 。
这已经得到了一个 gap 的解。
我们可以进一步,选择一系列集合:
S 1 , . . . , S k , k = O ( log ( 1 / P ) / ε 2 ) S_1,...,S_k,k=O(\log(1/P)/\varepsilon^2)
S 1 , . . . , S k , k = O ( log ( 1 / P ) / ε 2 )
记Z Z Z 为k k k 个集合中,Sum S k ( x ) = 0 \text{Sum}_{S_k}(x)=0 Sum S k ( x ) = 0 的集合数量。那么根据 Chernoff bound,有:
若D E > ( 1 + ε ) T DE>(1+\varepsilon)T D E > ( 1 + ε ) T ,则Pr [ Z < k / e ] > 1 − P \text{Pr}[Z<k/e]>1-P Pr [ Z < k / e ] > 1 − P 。
若D E < ( 1 − ε ) T DE<(1-\varepsilon)T D E < ( 1 − ε ) T ,则Pr [ Z > k / e ] > 1 − P \text{Pr}[Z>k/e]>1-P Pr [ Z > k / e ] > 1 − P 。
实际上,这就像选择一个稀疏的 01 矩阵A k × n A_{k\times n} A k × n 。
其中,A ( i , j ) = 1 A(i,j)=1 A ( i , j ) = 1 代表j ∈ S i j\in S_i j ∈ S i 。那么最后的Sum S i ( x ) \text{Sum}_{S_i}(x) Sum S i ( x ) 构成了一个列向量,为A × x A\times x A × x 。
这个问题要的是统计x x x 中不为 0 的数量,即x x x 的l 0 l_0 l 0 -norm。
同样我们可以推广问题,如果想去估计x x x 的l p l_p l p -norm,即维护( ∑ i x i p ) 1 / p (\sum_ix_i^p)^{1/p} ( ∑ i x i p ) 1 / p ,是否有做法呢?目前已知结果:
p ∈ [ 0 , 2 ] p\in[0,2] p ∈ [ 0 , 2 ] ,那么只需要O ( poly ( log n ) ) O(\text{poly}(\log n)) O ( poly ( log n ) ) 的空间。
对p > 2 p>2 p > 2 ,需要O ( n 1 − 2 / p poly ( log n ) ) O(n^{1-2/p}\text{poly}(\log n)) O ( n 1 − 2 / p poly ( log n ) ) 的空间。