对于矩阵 A,B,C 判断是否有 AB=C :随机一个行向量 x 然后看 xAB 是否 等于 xC 。正确率约为 1 。
通过少量查询得到近似的中位数:如果要求排名误差在 2an 以内,只需要 O(a21) 次查询就可以做到很高的概率。
给定 k 维空间的若干点 A1,A2,…,An ,要求预处理之后高效进行查询:查询每次给定 B ,求 ∑dis(B,Ai) 。可以求近似解。
如果存在一个点 P 和一个常数 c 满足 ∀i,dis(Ai,P)∈[c,2c] ,那考虑以下算法:
直接在 n 个点里随 m 个取出来记为 C1,C2,…,Cm,估计答案为 mn∑dis(B,Ci) 即可。道理在哪儿呢,考虑令 Xi=dis(Ai,B) ,根据三角形不等式有 X 极差 ≤4c 。
Hoeffding inequality:
设独立随机变量 X1,X2,…,Xm∈[s,t] ,X:=∑Xi ,则 Pr[X−E[X]≥z]≤2exp(m(t−s)2−2z2) 。
看一下式子就可以发现:常数个 m 就能使误差极大概率控制在 ϵnc 以内。
具体的,需要 1−δ 的正确率时我们取 m=O(ϵ21log(δ1)) 。
看来误差的分析是跟每次查询的点关系不大的,无论查询如何,我们都能将误差控制在 ϵnc ,也即 ϵ∑dis(Ai,P) 内。
考虑一般的情况,考虑按 dis(Ai,P) 倍增分块,将这些点分成 log2V 层即可,我们仍然把误差控制在了 ϵ∑dis(Ai,P) 内。
看来,只需要选取合理的中心点 P 即可。
我们并不需要让 ∑dis(Ai,P) 严格最小:在最优值的常数倍以内都是能接受的。
直接在给出的点里随几个点,取最优的即可。
理由考虑计算这样随,∑dis(Ai,P) 的期望,是不超过 2 倍的最优值的。
Count-min Sketch
先看这样一个问题:输入 N 个 [n] 上的整数,结束后给定 i ,(近似)回答 i 出现次数。
Count-min Sketch 支持用 ϵpolylogn 的空间复杂度,查询、插入时间复杂度亦为 ϵpolylogn ,做到:估计值 C′ 和正式值 C 之间满足 C≤C′≤C+ϵN 。
考虑哈希,找一个哈希函数 h:[n]→[m] ,我们开个大小为 m 的桶 t ,算 i 出现次数就看 th(i) 即可。如果哈希函数足够均匀随机那容易分析出来 E[C′]≤C+mn 。
Markov inequality:
若随机变量 X≥0 ,则 Pr(X≥a)≤aE[x] 。
对 X=C′−C 用这个定理,就可以得到 Pr(X≥nϵ)≤mϵ1 。
看来取 m=ϵ2 就有 21 的成功率了。
取 O(logn) 个哈希函数,把求得的 C′ 取 min ,成功率就非常高了。
求绝对众数的一个算法:对每个二进制位求 0 和 1 谁出现的更多。
LSH
度量两个集合的相似度: J(A,B)=∣A∪B∣∣A∩B∣ 。
给定 n 个大小为 m 的集合 Si, q 次查询,给定 x,y 计算 J(Sx,Sy) 。
一个 O(T(nm+q)) 的近似算法(Minhash)
离线下来,做 T 轮,对每个元素随个哈希值,记一个集合 Si 的权值是所有元素的哈希值的 min ,记为 Vi。每个询问记录一个计数器 cnt ,若 Vx=Vy 则将 cnt 加上 1 。
定理:Pr(Vx=Vy)=J(Sx,Sy) 。挺显然的。
把 Tcnt 当做答案即可。
chernoff bound:n 个在 [0,1] 间随机且期望为 μ 的随机变量 x1,x2,…,xn ,有:
$Pr\left(|\frac{x_1+x_2+\dots+x_n}{n}-\mu|\geq \sqrt{\frac{\log(1/\delta)}{nt}}{\mu}\right)\le \delta $ 。其中 t 为 ≤μ 的常量。
看来 T 取 ϵ2J(Sx,Sy)log(1/δ) 就能以 $\delta $ 的失败概率将相对误差控制在 ϵ 内。然而 J(Sx,Sy) 很小时这个算法就很无力了,所以作业中绝对误差在一个范围内也是能接受的。
度量两个向量的相似度:σ(x,y)=1−πθ(x,y)。
Simhash:在 d 维单位球面上随一个点,取出原点到它的向量 w ,然后设 h(x)=sgn(<x,w>) ,其中 sgn(x)=[x>0] 。
则 Pr(h(x)=h(y))=σ(x,y) 。
上面两个方法都被称为 Locality Sensitive Hashing(LSH)(狭义)就是对于定义的相似度 sim(x,y) ,有哈希函数 h 使得 Pr[h(x)=h(y)]=sim(x,y) 。这个东西在工业界是有用的,用于进行重复检测。
Hamming 空间(Hd)的 c-近似 最近邻的专门算法
预处理 O(dn+n1+1/c) ,单次查询 O(n1/c) 。
算法流程:取 T=O(nc1) ,做 T 轮以下事情:
对 d 个二进制位做一个随机的置换,每次查询找到:二进制下与查询点 lcp 最大的给定点,用这个给定点更新答案即可。
误差分析:对查询 q 设 q∗ 是最近点,r=distH(q,q∗) 。
设 p1=1−dr,p2=1−dcr,k=Θ(logp2(n1)) 。
我们分析两件事情:
(1) 与 q 距离 >cr 的点很小概率能在 shuffle 后前 k 位相等
因为这个概率不超过 p2k=poly(n)1 。
(2) q∗ 很大概率能在 shuffle 后前 k 位相等
概率约为 p1k ,约为 n1/c1 ,这里分析比较麻烦。
所以 T 取 O(n1/c1) 就能让成功率做到 Ω(1) 了。
广义 LSH:Pr[h(x)=h(y)] 与 sim(x,y) 正相关。
处理 c-最近邻:
哈希函数 h 使得有参数 r,p1,p2 ,满足
∣∣x−y∣∣≤r→Pr[h(x)=h(y)]≥p1
$ ||x-y||>cr\rightarrow Pr[h(x)=h(y)]\le p_2$
令 ρ=log(p2)log(p1) ,那么存在 n1+ρ 预处理, nρ 做查询的算法。
令 k=O(logn/log(1/p2)),T=nρ 。
做 T 轮,每轮造 k 个独立的 LSH 然后拼起来。
查询直接找拼起来的哈希值与查询点相同的点,更新答案即可。
画格子
近似直径
首先容易 O(nd) 找到一个至少为最终直径 21 的答案,设之为 D′ ,真实答案为 D 。
画格子,以 dϵD′ 为块长,把两个点的距离近似为它们所在格子的中心的距离,可以计算得误差不超过 ϵD′ ,自然不超过 ϵD。这里格子个数 ≤(ϵD′Dd)d≤(ϵ2d)d ,所以总复杂度 O(ndlogn)+(d/ϵ)O(d) 。
最小包围球和 ϵ - Coreset
给定一个 Rd 上的点集 V,要找一个点 c 使得 f(V,c)=v∈Vmax∣c−v∣ 最小。设 f(V) 是这个最优值。
Welzl’s Algorithm(【模板】最小圆覆盖)
期望 O((d+1)(d+1)!n) 的时间复杂度。
相当于选 d+1 个点,由它们生成的球尽量小且能覆盖所有点。
观察:若 S 的最小包围球内没有 w ,那么 S∪{w} 的答案一定包括 w 。
考虑递归求解前 n−1 个点的答案,如果 n 被覆盖就结束了,否则说明 n 一定在答案中,
然后重新递归求解前 n−1 个点的答案。这第 n 个点是能随机选取的,那计算一下就是上面的式子了。
ϵ - Coreset:找尽量小的点集 P⊆V ,使得
∀c∈Rd,f(P,c)≥(1−ϵ)f(V,c) 。
考虑任取一个点找最远点,设它们距离是 D′ ,显然 f(V)≤D′≤2f(V) 。
考虑画格子,以 2dϵD′ 为块长,每个格子任取一个点即可,误差不超过 2ϵD′≤ϵf(V) 。
Coreset 的用处:可合并,考虑 Coreset(A)∪Coreset(B)=Coreset(A∪B) 。那如果点集会修改,就用线段树来处理,每个节点维护一个 Coreset ,上传就是直接合并,然后产生一点误差以减少这个点集。
四分树
近似最近邻查询
给定 [Δ]d 上的点集 V,每次查询给出一个 q∈[Δ]d ,问 V 中的最近邻。
可以做到预处理 O(ndlogΔ) ,查询 O(ϵ−dlogΔ) 。
考虑对 V 建四分树,查询直接在树上 bfs,然后考虑剪枝,设 diam(u) 是点 u 代表的范围的直径,repu 是节点 u 上任意一个节点,如果当前找到的最优答案 A≤∣q−repu∣−diam(u) 就可以直接剪掉 u 。显然是对的,复杂度证明比较麻烦。
WSPD
给定 [Δ]d 上的点集 V 。
一个 ϵ− WSPD 是两个等长的集合序列 A,B 。令 m=∣A∣=∣B∣ ,满足 ∀1≤i≤m,Ai,Bi⊆V,max(diam(Ai),diam(Bi))≤ϵ⋅dis(Ai,Bi) ,且 ∪Ai×Bi=V×V 。
换句话说, ∀u,v∈V,u=v,∃1≤i≤m ,使得 u∈Ai,v∈Bi。
结论:我们可以在 O(nϵ−O(d)logΔ) 的时间内找到大小为 O(nϵ−O(d)logΔ) 的 ϵ− WSPD。
考虑建四分树, 设 Ou 表示节点 u 子树内的输入点集合,Wu 表示这个节点代表的格子的点集。
设 sol(u,v) 表示现在需要覆盖 Ou×Ov 。令 δ(u)=diam(u)⋅[∣Ou∣≥2] 。不妨令 δ(u)≥δ(v) 。
如果 δ(u)≤ϵ⋅dis(Wu,Wv) 就直接把 {Ou,Ov} 加入答案;否则枚举 u 的儿子 u′ ,递归 sol(u′,v) 。显然是对的,复杂度证明比较麻烦。
最近点对精确求解
任取 ϵ<1 并构造 ϵ− WSPD,若 ∣Ai∣=∣Bi∣=1 则尝试更新答案。
近似直径:求 ϵ/2− WSPD,每对 Ai,Bi 中任取代表点 repiA,repiB 更新答案。
原因考虑令 dis(u,v) 是直径, u∈Ai,v∈Bi ,那么 dis(repiA,repiB)≥dis(u,v)−diam(Ai)−diam(Bi)≥(1−ϵ)dis(u,v) 。
感性理解一下,其实是每个 Ai,Bi 覆盖的点对的 dis 差距不大。
欧氏最小生成树
考虑依据输入点集 V 构造的完全图 G 满足两个点间的边权是欧氏距离。
t−Spanner G′ 是 G 的一个子图,使得
∀u,v∈V ,disG′(u,v)≤t∣∣u−v∣∣ 。
(1+ϵ)−Spanner 求解方法:求出 ϵ/8-WSPD ,每对 Ai,Bi 都找两个代表点连边,即可得到 G′ 。
考虑按照 ∣∣u−v∣∣ 从小到大归纳证明正确性。
令 u∈Ai,v∈Bi ,代表点为 u′,v′ , l=∣∣u′−v′∣∣ 。
∣∣u−v∣∣≥dis(Ai,Bi)≥ϵ8max(diam(Ai,Bi))
l≤dis(Ai,Bi)+diam(Ai)+diam(Bi)≤(1+4ϵ)∣∣u−v∣∣ 。
disG′(u,v)≤disG′(u,u′)+disG′(v,v′)+l≤(1+ϵ)(∣∣u−u′∣∣+∣∣v−v′∣∣)+l≤(2ϵ+4ϵ2+1)∣∣u−v∣∣≤(1+ϵ)∣∣u−v∣∣
由此可以求出 G 的近似最小生成树:在 G′ 上求生成树即可。
高维方法
随机平移四分树
例: O(d)−spanner
考虑对 n 个坐标加上一个相同的长为 d 的向量,然后再求四分树。接下来枚举树上每一个点,令一个点子树代表的坐标集合为 P ,则任取 P 中一个点 w ,∀x∈P 连边 (x,w) 。
进行 O(logn) 次随机平移。
首先这样边数就只有 O(nlognlogΔ) ,接下来分析正确性。
首先随机平移后,考虑估计两个点被边长 2i 的格子划分开的概率。设 f(x,y) 是 x,y 两个点的曼哈顿距离,则被划分开的概率 ≤2if(x,y) (Union Bound) ,而 f(x,y)≤d∣∣x−y∣∣2 。综上,被划分开的概率 ≤2i∣∣x−y∣∣2d 。
设 ixy 满足 2ixy 比 d∣∣x−y∣∣2 略大一点,那此时在一次平移后 x,y 在 2ixy 的格子被分到一起的概率 ≥21 。而这样的格子的直径也就是 O(d)∣∣x−y∣∣2 ,自然生成图就满足
disG(x,y)≤O(d)∣∣x−y∣∣2 了。
那 O(logn) 次平移,x,y 不合法的概率就 ≤poly(n)1 ,最后 Union bound 就结束了。
接下来介绍一个类似的方法。
Tree-Embedding
考虑直接建随机平移四分树,然后认为一条边的边权是 d2i 。
令这棵树是 T ,结论是 ∣∣x−y∣∣2≤disT(x,y),E[disT(x,y)]≤O(dlogΔ)∣∣x−y∣∣2 。
原因是 E[disT(x,y)]≤i∑O(d2i)∗2i∣∣x−y∣∣2d=O(dlogΔ)∣∣x−y∣∣2
用这个做高维 MST:直接求这棵树上所有叶子构成的虚树边权和即可。
高维欧式最小权匹配:从下往上贪心,遇到一起直接匹配。
Range Query
给定一些数据点和一个常数 R ,每次查询给一个点 u ,问有多少个数据点 vi 满足 ∣∣u−vi∣∣2≤R 。
考虑一种近似:允许计入 O(α)R 内的点。
直接随机平移,以 dαR 为边长划格子,枚举所有可能存在点与 u 距离 ≤R 的格子,把这个格子的所有点都加入答案即可。期望要搜的格子数:2α2/3dpoly(d) 。
降维
我们希望找到一种映射 f:Rd→Rm ,使得 ∀x,y∈P ,∣∣f(x)−f(y)∣∣2∈(1±ϵ)∣∣x−y∣∣2 ,其中 P 是一个大小为 n 的点集。
JL
随机 m 个独立的单位高斯向量 w1,w2,…,wm,然后令 f(v)=m1(<w1,v>,<w2,v>,…,<wm,v>) 。
m 取 O(ϵ−2logn) ,就大概率对任意点对都合法。
结论:Pr[∣∣f(v)∣∣2∈(1±ϵ)∣∣v∣∣2]≥1−exp(−O(ϵ2m)) 。
也就是说对于任意一对 x,y ,Pr[∣∣f(x)−f(y)∣∣2∈(1±ϵ)∣∣x−y∣∣2]≥1−exp(−O(ϵ2m)) 。
失败概率就是 exp(O(ϵ2m)) ,通过 union bound 我们希望 exp(−O(ϵ2m))O(n2)≤ 一个任意的常数。于是 m 就需要取 O(ϵ−2logn) 。
JL 是 Data oblivious 的。所谓 Data oblivious,即是这个算法的定义与具体的数据集无关。
线性回归
即给定 X∈Rn×d 和 y∈Rn ,需要找到 w 使得 ∣∣Xw−y∣∣2 最小。
求 w=(XTX)−1XTy ,复杂度 O(nd2) 。问题是 XTX 可以是不可逆的,而且这样也挺慢。
Subspace JL
考虑降维,尝试找到 A∈Rm×n 使得 ∣AXw−Ay∣∣2≤(1±ϵ)∣∣Xw−y∣∣2 。
令 A=f(v)=m1(w1,w2,…,wm) 即可。
证明考虑,首先这里的 Xw−y 其实构成了 Rn 的一个 d 维子空间。
设 U 是 Rn 的一个 d 维子空间,则 ∀v∈U ,有 Pr[∣∣Av∣∣2∈(1±ϵ)∣∣v∣∣2]≥1−δ ,其中 m=O(ϵ2dlog(ϵ−1)+log(δ−1)) 。这几乎就是 O(d) 。
这里的证明和之前的区别在于,不能直接 Union Bound 了。怎么处理
问题是这样的话算 AX 还是 O(nd2) 的。
接下来考虑 X 这个矩阵比较稀疏的时候该怎么做。设 nnz(X) 是 X 中非零元素的个数。
Sparse S
考虑这样构造矩阵 A :每一列随机一个位置为非零,其值在 {−1,1} 间随机。显然这样 AX 能直接在 O(nnz(X)) 的时间内计算。但 m=O(ϵ−2d2polylog(ϵ−1d)) 时才有类似保证,这几乎就是 O(d2) 。总复杂度是 O(nnz(X)+d4) 。
Fast JL
一种特殊构造的矩阵 A ,使得 AX 可以快速计算,这里略了。可以优化到 O(nnz(X)+d3) 。
降维-PCA
有缘再写。
Sparse Recovery
Linear sketch
称一个(数据流)算法是linear sketch,如果可以把算法看作如下形式:
• 设 x 是频数向量,则算法在数据流下维护的是一个线性操作后的结果 Ax 。
• 算法在回答查询时,仅需要利用 Ax 回答(f(Ax))
这个的好处是,对于两个数据流 P1,P2 维护的 Linear Sketch F1,F2 ,有 F1+F2 是 P1∪P2 的 Linear Sketch。我们可以做数据流间的加减法。
k-sparse
就是说有一个频数向量 x ,需要设计一个结构,使得:
判断是否 ∣∣x∣∣0≤k ,若 ∣∣x∣∣0≤k 则把 x 所有非零的位置找出来。
存在一个 O(kpoly(log(n))) 空间,单次修改 O(poly(log(n))) 的算法。
先考虑 k=1 怎么搞。
维护 s1=p∑xp,s2=p∑xp,s3=p∑rpxp ,r 是设定的一个常数。当然这里会让 s3 模一个质数。
查看一下 rs1s2s1 是否与 s3 相等即可。
拓展一下,取 T 个 [n]→[2k] 的随机哈希,我们维护 2k 个 1-sparse,每次 x 变化就修改对应的 1-sparse。
思考一下,如果最终 ∣∣x∣∣0≤k ,对于其中某一个非零元素,它在一个哈希中不被冲突的概率是 >21 的。也就是说,它成为某个 1-sparse 的唯一元素的概率 >1−(0.5)T 。
如果 T 取 O(logk) ,一个元素就有 O(k)1 的失败率,union bound 一下,失败率就是个常数了。于是直接把所有 1-sparse 提取的元素并在一起即可。
一个问题是怎么判断元素个数 ≤k ,维护单独的一个 1-sparse B ,在我们用上述算法提取了一些元素后,将这些元素从 B 中删除,看看 B 是否为空即可。
小空间求近似直径
你要维护一个点集,支持加点删点,在最后查直径。空间很小,不能和点集大小相关。
考虑维护 logΔ 个结构,每个结构相当于以 2i 为块长画格子后得到的点集做 k−sparse 。其中 k=O(ϵ1)d 。最后查直径就是找到最小的 i 使得非零位置个数 ≤k ,然后暴力求这些格子间的直径即可。
数据流 l0 采样
刚才这个 k-sparse 是要把所有非零位置(support)都给恢复。l0 - 采样要做的事:在 k 比较大的时候也有办法搞随机采样。
具体的,l0 采样希望均匀随机地返回 supp(x) 中的一个数。
结论:存在空间 O(polylog(n)) 的算法,以 1−1/poly(n) 概率成功。
但是这个采样是伪的:确实输出了一个均匀采样,但是反复运行算法无法生成新的独立采样。
考虑维护 logn 个 1-sparse S0,S1,… 。同时设一个哈希函数 hi 使得 Pr[hi(x)=1]=2i1 ,每次 u 频数修改时,若 hi(u)=1 则对 Si 进行修改。
最后找到任意一个输出 Yes 的 sparse,把这个看做我们的采样。首先这个采样确实均匀,那成功率如何呢,可以感到它是一个常数,所以维护常数个这样的结构即可。
求联通块个数
就是说你要维护一个算法支持无向图上加边删边,最后求出这个图的所有连通分量。空间希望是 O~(n) 。
考虑在每个点用 l0 采样维护频数向量 xu,v ,令 xu,v=[(u,v)∈E](−1+2[u≤v]) 。
然后用类似 borvuka 的方法,每个联通块找一条向外的边就好了。考虑这些的 x 的总和,发现内部的边都被抵消完了,所以直接采样就可以得到这样一条边。时空复杂度都是 O(nlogn) 。
求近似MST
就是说你要维护一个算法支持加边删边(带权),在最后求 MST,希望空间 O~(n/ϵ) 。
考虑把边权离散化到最近的 1+ϵ 的方幂,这样本质不同的边权只有 O(ϵlogn) 个,对每个边权维护上面那个题说的东西就好了。