原文请见:Load Balancing and the Power of Hashing
如果你参加一次软件工程师的面试并你被问到一个很难的有关算法的题目,那么你最好考虑使用散列函数(hash tables)?更简洁地说吧:谷歌喜欢散列函数(and BAT)。要想知道为什么散列函数如此有用,你多少应该知道它里面的数学。
load factor(装填因子)
n keys, m slots(键与槽) ⇒ α=nm , average # keys per slot
Expected unsuccessful search time(失败搜索(搜索的数据不在表中)的时间期望)
Θ(1+α)=Θ(1+nm)
1:hash and accessing the slot
α :the cost of the searching the list.
Expected search time == Θ(1) if n==Θ(m) (不会超过 m 的整数倍)
division method:
h(k)=kmodm
multiplication method:
m=2r , w 表示计算机的位数(之所以更推荐乘法,是因为计算机更擅长乘法,此时考虑计算机的位数,可见这时就牵涉计算机硬件体系结构的问题了)
h(k)=(A⋅kmod2w)>>(w−r)
A 是位于 [2w−r,2w] 之间的一个奇数,且不接近于 2w−1 或者 2w 。
我们不妨来分析这一hash函数式, A⋅kmod2w 共保留 w 位,再右移 w−r ,保留中间的 w−(w−r)==r 位,也正是最终得到的槽(slots)的个数,这一切都很convenient,对计算机而言。
我们来举一个实例,取 r=3,w=7,A=0b1011001 (7位的计算机,:-D),当 k=0b1101011 时, A⋅k=0b10010100110011 ,再进行取模运算,也即保留最后的 w=7 位, A⋅kmod2w 得 0b0110011 ,最后右移 w−r=7−3=4 位,即保留 0b011=3 ,也即 h(k)=3 。
首先我们需要一个均匀哈希的假设(Assumption of uniform hashing):each key equally likely to have any one of the m! perms as its probe seq,independence of other keys.
Theorem: E[#probes]≤11−α ,if α<1 (也即 n<m )
Pf (unsucc search):
1 probe always necessary with prob nm collision, ⇒ 2nd probe necessary, n−1m−1 collision ⇒ 3nd, n−2m−2
注意到 n−im−i<nm=α
α 不能太大,也即 hash table 不能太稠密;
Idea is:choose hash function at random independen t from keys,这正是所谓的 universal hashing(全域hash)
Def:
U 为键的全域(a universe of key)
H 为哈希函数的有限集(a finite collection of hash functions)将 U 映射到 {0,1,2,…,m−1}
H is universal if ∀x,y∈U,where x≠y,|{h∈H,h(x)=h(y)}|=|H|m (全域的定义), |{h∈H,h(x)=h(y)}| 表示的是 hash function 的数目,也即 |H|m 表示的不是概率而是某一集合的大小,如下图所示:
则从 H 中随机地选择一个 hash function h (我们是随机地选择 hash function,而不是随机地选择keys),发生 h(x)=h(y) 的概率为 |H|/m|H|=1m
Thm. Choose h randomly from H , suppose we’re hashing n keys into m slots in Table T , for given key x , the expected number of collisions with x :
Pf. Let Cx be r.v. denoting total(概率分析中常用到的一种手段,将某个total型的随机变量转换为一系列指标随机变量的总和) collisions of keys in T with x , 定义如下的指标随机变量:
E(Cxy)=Pr(h(x)=h(y))=1m , Cx=∑y=T−{x}Cxy :
此构造对 m 为质数时有效,将键 k 分解为 r+1 位, k=<k0,k1,…,kr>,where 0≤ki≤m−1 。(这种分解的思想在于,把 k 用某种m进制
表示)
构造我们的随机化策略(randomized strategy)。
随机化的对象是对哈希函数的选择。
选择 a=<a0,a1,…,ar> ,each ai is chosen randomly from [0,m−1] (也即每一 ai 都是 m 进制).
最终,我们定义 ha(k)=(∑i=0raiki)modm ,而 ∑i=0raiki 又可通过向量内积的形式得以计算,所以此时的全域 H 有多大, |H|=mr+1 ,每一位的取值为 [0,m−1] ( m 种可能),共 r+1 位;
Thm:此时的 H 是全域的。也即需证明 |{h∈H,h(x)=h(y)}|=|H|m ( x 与 y 互异)。注:同一个 hash function h(⋅) ,或者写作 ha(⋅) ,对不同的两个 key x,y ,映射到相同的槽slot,这样的哈希函数的个数。
证明:
分别将 x,y 分解,得 x=<x0,x1,…,xr> , y=<y0,y1,…,yr> , x 与 y 互异,如果 x≠y ,则 <x0,x1,…,xr> 比与 <y0,y1,…,yr> 在某位(至少一位)不同,不失一般性的,设该位为0,此时问有多少个 ha∈H 会使得 x 与 y 发生碰撞。
也即:
因为 x0≠y0 ,所以 x0−y0 的逆元,也即 (x0−y0)−1 一定存在,所以:
也即, a0 完全由 ai,i=1,…,ar 决定,或者说任何 ai,i=1,2,…,r 都存在一个 a0 ,使得 ha(x)≡ha(y) (发生碰撞),也即自由度为 (1+r)−1=r 。