Lec 1 全域哈希与完美哈希(Universal & Perfect Hashing)
TL;DR
- 全域哈希的随机化保证:通过从 2-全域哈希族 H 中随机选取哈希函数,保证对全域中任意两个不同元素发生碰撞的概率不超过 1/n,摆脱对输入分布的依赖。
- 两级哈希(FKS 结构)实现最坏 O(1) 查找:外层哈希将 m 个元素分入 n=m 个桶;内层对包含 Si 个元素的桶分配 Si2 大小的二级哈希表,总空间期望为 O(m)。
- 空间与碰撞的期望平衡:结合马尔可夫不等式,第一层总二级空间 ∑Si2≤4m 且第二层各桶完全无碰撞的概率均大于 1/2,可通过拉斯维加斯算法在线性期望时间内完成构造。
字典查找与负载均衡
字典查找问题与哈希碰撞挑战
字典查找(Dictionary Problem)与负载均衡(Load Balancing)是算法理论与系统设计的基石。在理想情况下,我们希望在 O(1) 时间内维护一个动态或静态集合:
- 插入(
Insert(x)):将元素 x 加入集合 S
- 删除(
Delete(x)):从集合 S 中移除元素 x
- 查询(
Query(x)):检查 x 是否在集合 S 中
假设全域为 U(例如所有 IPv6 地址,大小可达 2128),而实际存储的子集 S⊆U 规模为 ∣S∣=m≪∣U∣。我们希望用一个大小为 n(通常 n=O(m))的数组来存储。哈希函数 h:U→[n](其中 [n]={0,1,…,n−1})负责将全域元素映射到槽位中。
根据鸽巢原理,只要 ∣U∣>n,就必然存在 x=y 满足 h(x)=h(y),即发生碰撞(Collision)。在链式哈希(Hashing with Chaining)中,碰撞元素被挂接在同一个槽位的链表上。若哈希函数固定,恶意对手总能构造出全部映射到同一槽位的 m 个元素,导致查询退化为单链表遍历的 O(m)。
完全真随机的哈希函数需要存储每个元素的映射,占用 ∣U∣logn 比特空间,这在存储开销上是不可接受的。因此,核心问题在于:如何用极小的紧凑描述,构造一个在任意给定输入集合上都能表现得“足够随机”的哈希函数族?
2-全域哈希族(2-Universal Hashing)
形式化定义
Carter 与 Wegman(1979)提出了全域哈希(Universal Hashing)的概念。
设 H 是从全域 U 到 [n] 的一组哈希函数的集合。如果对于任意一对不同的元素 x,y∈U(x=y),当从 H 中均匀随机选取 h 时,满足:
h∈HPr[h(x)=h(y)]≤n1
则称哈希函数族 H 是 2-全域的(2-Universal)。这意味着,对于任意两个固定元素,它们发生碰撞的几率不大于将它们真随机独立投掷进 n 个桶的几率。
2-全域哈希族的基本碰撞界
考虑集合 S⊆U(∣S∣=m)。令指示随机变量 Ix,y=1 当且仅当 h(x)=h(y)。由 2-全域性质可知:
E[Ix,y]=Pr[h(x)=h(y)]≤n1
总碰撞对数记为 C=∑{x,y}⊆S,x=yIx,y。根据期望的线性性质:
E[C]={x,y}⊆S,x=y∑E[Ix,y]≤(2m)⋅n1=2nm(m−1)
查询元素 x 时所在链表长度 Lx 的期望值为:
E[Lx]=1+y∈S,y=x∑E[Ix,y]≤1+nm−1
当表大小取 n≥m 时,链表的期望长度不超过 2,即单次操作的期望时间为 O(1)。
此外,若分配 n≥m2 的空间,总碰撞数期望满足:
E[C]≤2m2m(m−1)<21
根据马尔可夫不等式(Markov's Inequality):
Pr[C≥1]≤1E[C]<21
这意味着,当空间为 m2 量级时,随机抽取一个函数 h∈H,有一半以上的概率没有任何碰撞!
FKS 两级完美哈希(Fredman-Komlós-Szemerédi)
单纯分配 m2 空间代价过高。Fredman, Komlós 与 Szemerédi(1984)提出了著名的 FKS 两级完美哈希,在保持 O(m) 线性空间的同时,实现最坏情况 O(1) 的无碰撞查询。
结构设计与空间核算
FKS 采用两级哈希表架构:
- 第一级(主表):大小取 n=m,从 2-全域哈希族中选取函数 h:U→[m]。记映射到第 i 个桶的元素集合为 Si,其大小为 Si=∣Si∣。
- 第二级(桶内子表):为每个桶 i 分配一个独立的二级哈希表,其大小设为 ni=Si2。二级哈希函数 hi 同样来自 2-全域族,映射到 [Si2]。
由前面的生日悖论界可知,在大小为 Si2 的二级表中,发生内部碰撞的概率严格小于 1/2。
关键在于总空间消耗 ∑i=1mni=∑i=1mSi2。注意到:
i=1∑mSi2=i=1∑m(Si(Si−1)+Si)=2i=1∑m(2Si)+i=1∑mSi=2C+m
其中 C 正是第一级哈希中所有元素的碰撞对数!因此总空间的数学期望为:
E[i=1∑mSi2]=2E[C]+m≤2⋅2mm(m−1)+m<2m
完美哈希的拉斯维加斯构造算法
利用马尔可夫不等式,可以设计出高效的静态表建表算法:
- 第一级建表:随机选择 h∈H。计算 ∑i=1mSi2。由于 E[∑Si2]<2m,满足 ∑i=1mSi2>4m 的概率小于 1/2。若超过 4m 则重新抽样 h。期望尝试次数不超过 2 次。
- 第二级建表:对于每个非空桶 i(Si>1),在大小为 Si2 的表上随机选择 hi。若产生碰撞则重新选择 hi。每次成功的概率均 >1/2,期望重选次数不超过 2 次。
整个构造算法是拉斯维加斯类型的(输出永远正确,运行时间为随机变量),总建表时间的期望为 O(m),空间最坏为 O(m),而查询任意元素只需计算 h(x) 和 hh(x)(x) 两次哈希,最坏时间保证为严格的 O(1)!
2-全域哈希族的代数构造
如何构造出占用描述空间极小、计算极快的 2-全域哈希函数族?
仿射变换构造法
选取一个大素数 p,使得全域大小 ∣U∣≤p。定义函数族:
H={ha,b(x)=((ax+b)modp)modn∣a∈{1,2,…,p−1},b∈{0,1,…,p−1}}
只需存储 a 和 b 两个整数(共约 2logp 比特),即可完全确定一个哈希函数。
全域性质证明
对于任意给定的不同键值 x=y(x,y∈[p]):
令 s=(ax+b)modp,t=(ay+b)modp。
由模素数 p 的有限域性质,由于 a=0 且 x=y(modp):
s−t≡a(x−y)≡0(modp)⟹s=t
根据线性同余方程组求解:
a≡(s−t)(x−y)−1(modp),b≡s−ax(modp)
对于每一对确定的不同 (s,t)(s=t,s,t∈[p]),恰好对应唯一确定的参数对 (a,b)。由于 (a,b) 共有 p(p−1) 种均匀等可能的取值,因此 (s,t) 也均匀分布在所有 p(p−1) 个有序非对角点上。
当且仅当 s≡t(modn) 时,发生最终碰撞 ha,b(x)=ha,b(y)。
对于任意固定的 s∈[p],满足 t=s 且 t≡s(modn) 的 t 的个数至多为 ⌈p/n⌉−1≤(p−1)/n。
因此发生碰撞的选法总数最多为:
p⋅np−1=np(p−1)
碰撞概率严格满足:
Pr[ha,b(x)=ha,b(y)]≤p(p−1)p(p−1)/n=n1
这便以构造性方式证明了 2-全域性。
一致性哈希的前瞻关联
在分布式存储与负载均衡场景中,桶数量 n 会随节点增减动态改变。传统的 h(x)modn 会导致几乎所有键值重新映射。
一致性哈希(Consistent Hashing,Karger et al. 1997)通过将节点和数据键映射到同一个连续哈希环上,使单个节点的加入或退出仅影响环上相邻区间的极少数键值(数据迁移期望比例为 O(1/n)),成为现代分布式系统与 CDN 缓存路由的基础。
我的理解
我的理解
随机化不是无序,而是剥夺最坏输入的对抗能力:
在确定性哈希中,任何单一哈希函数在巨大的全域空间面前都是透明的,对抗性输入总能击穿平均时间保证。Carter-Wegman 的核心洞见在于:算法的设计者应当掌握随机性的主动权。只要哈希族具备 2-独立性(Pairwise Independence),输入数据即使由恶意对手挑选,映射的期望行为也与独立投掷完全一致。
FKS 两级哈希则展现了极具美感的分层思想:一级粗分降低局部规模,二级平方空间彻底粉碎残余碰撞,通过期望的线性性(E[∑Si2]=O(m))巧妙解决了“最坏情况 O(1) 时间”与“线性空间”看似不可调和的矛盾。