MAD(乘,加,除)散列函数如何工作?

时间:2019-05-19 16:22:36

标签: c++ hashmap hashtable

我已经被分配为大学项目的任务,该任务是从头开始创建数据结构(例如minheap,hashtable等)。但是Hashtable或更具体地说是Hash映射-函数给我带来了很多麻烦。我遇到过MAD(乘,加,除)函数,基本上是:h(x)= [(a * x + b)%p]%N,其中a,b:随机整数,p:大质数N:哈希表中元素的数量。

我的问题是此函数如何(以及为什么)准确地将哈希表中的值均匀分布。

1 个答案:

答案 0 :(得分:1)

  

h(x) = [(a*x + b) % p] % N

让我们首先单独查看a*x + b。如果您想象a分解为2的幂,则a*xx的总和向左偏移2的次幂,使得{ {1}}影响在x中设置的其他位的位置,当求和产生的其他一些位则携带特定的位。加a会混入另一组随机位:非常类似于XORing,但进位会有一些额外的复杂性。如果说b的值介于0到255之间,并且具有x位(每个都是0或1),那么到目前为止,我们已经得到:

abcdefgh

因此,在“ 1s”列中,我们对 (a&1 ? abcdefgh : 0) + (a&2 ? abcdefgh0 : 0) + (a&4 ? abcdefgh00 : 0) + (a&8 ? abcdefgh000 : 0) + ... + // continues for a&16, a&32 etc. ABCDEFGHIJKLMNOP // however many random bits in "b" h求和,它们可能与Pg和{ {1}},然后继续。

如果h等于37,即32 + 4 + 1,则我们要添加O本身,ax:{ {1}}因此会影响散列值中的更多位(这很好,的确具有密码强度散列函数,更改密钥中的任何位(无论是单个位,一半位还是全部位)都应该随机地翻转哈希值的一半)。

回到完整的公式,让我们假设我们跳过x << 2而只有x << 5,但是当前表的大小是2的幂:x相当于按位-AND运算一些不那么重要的位。换句话说,它丢弃了我们在% p计算的更高有效位中建立的许多随机性。因此,为了使散列函数可以安全地在任意数量的存储桶中使用,我们可以首先引入% N,这意味着从求和步骤开始,如果散列值中存在与二幂幂相关的模式,则它们有效地分散在0..p范围内的随机位置上。

请考虑说一个介于0到255之间的哈希-如果% N为200,则哈希到桶中0..55范围的可能性是原来的两倍。为了使这种影响不那么重要,我们希望散列值比MOD值具有更多的位,并且该原理以分层的方式应用于我们应为a * x + b% p选择的值:< / p>

  • N的值应倾向于明显大于p,并且分布在比N大得多的范围内,因此a * x + b将它们在桶,但是

  • p应该比p大得多,因此我们没有低索引的存储桶,其碰撞概率明显更高(如果您使用线性探测来解决冲突)。

例如,如果我们要支持% p的值,最大为2 24 ,并且我们使用32位无符号整数进行这些计算,那么p和{ {1}}在该范围内具有随机值,我们可以将差值拆分为大约2 28 的质数。