为什么最好在散列函数中使用质数作为mod?


57

如果我有一个从1到100的键值列表,并且想将它们组织成11个存储桶的数组,那么我会被教导如何形成mod函数

H=kmod 11

现在,所有值将在9行中一个接一个地放置。例如,在第一个存储桶中将有0,11,22。在第二个中,将有1,12,23等。

假设我决定成为一个坏孩子,并使用非质数作为我的哈希函数-以12为例。使用哈希函数

H=kmod 12

会导致哈希表的值在第一个存储桶中为0、12、24 0,12,24,在第二个存储桶中为1、13、25 1,13,25等,依此类推。

本质上,它们是同一件事。我没有减少冲突,也没有通过使用质数哈希码更好地进行扩展,而且我看不出它有什么好处。


相关问题,为什么我们在哈希函数stackoverflow.com/questions/5889238/…中
shuva

Answers:


62

考虑一组键和一个哈希表,其中存储桶数为。由于是一个因子,是的倍数的键将被散列到属于的倍数桶:K={0,1,...,100}m=1231233

  • 键将散列到存储区。{0,12,24,36,...}0
  • 键将散列到存储桶。{3,15,27,39,...}3
  • 键将散列到存储桶。{6,18,30,42,...}6
  • 键将散列到存储桶。{9,21,33,45,...}9

如果是均匀分布的(即,每个键都同样可能出现),则的选择不是那么关键。但是,如果不均匀分布会怎样?想象一下,最可能出现的密钥是的倍数。在这种情况下,所有不是倍数的存储桶都将很可能为空(这在哈希表性能方面确实很糟糕)。KKmK33

这种情况看起来更常见。例如,想象一下,您正在根据对象在内存中的存储位置来跟踪它们。如果计算机的字大小为4个字节,则您将使用倍数作为哈希键。不用说,将选为的倍数将是一个糟糕的选择:您将有存储桶完全为空,并且所有键都在其余的存储桶中碰撞。4m43m/4m/4

一般来说:

中与存储桶数共有一个公因数的每个密钥都将散列到该存储桶数倍的存储桶中。Km

因此,为了使冲突最小化,重要的是减少和元素之间的公因数。如何做到这一点?通过选择为具有很少因素的质数mKm


我刚刚看到我的查询与您的答案一致。您认为查询中的哈希函数是否有效?
外汇兑换,2016年

@overexchange:我回答了你的问题。这个问题的答案也可能是你的兴趣。
马里奥·切维拉

为什么只有在K偏斜的情况下m的选择才重要?即使K均匀分布,在m不好的情况下我们的性能也会变差吗?
vorou

这取决于您所说的“坏 ”。如果您的意思是“与哈希表中的元素数量相比要小”(即高负载因子),那么性能将很差。但是,如果您的意思是“不是素数”,那么如果所有键都具有相同的可能性,那么这一事实并不那么重要,因为它们将均匀分布在哈希表中。问题本身就是一个例子。m
马里奥·塞维拉

16

使用质数是否不太可能发生碰撞取决于密钥的分布。

如果您的许多键的形式为并且您的哈希函数为,则这些键将进入存储桶的一小部分,如果除以。因此,您应该最小化此类的数量,这可以通过选择质数来实现。a+kbH(n)=nmodmbnb

另一方面,如果您希望拥有到存储桶,并且知道倍数的差异比和倍数的差异更有可能,则可以为非常特殊的应用选择。1112112312


1
但是,如果我的键没有的形式,那么没关系吗?那正确吗?a+k×bm
CodyBugstein

1
@lmray,如果您的密钥是均匀分布的,则无关紧要。如果不是,则将取决于的精确度分布。mm
AProgrammer

刚刚恢复了最后一次编辑,我忘记了。12>11
frafl 2013年

3
您的意思是“去一小部分桶iff将划分为 ”?bm
米哈伊尔·杜波夫

8

是否影响(也)取决于您如何处理碰撞。使用开放式哈希的某些变体时,使用质数保证只要表足够为空,就可以找到空插槽。

例如,尝试显示以下内容:

假设我们要插入一个散列元素以解决并通过随后尝试对尝试位置来解决冲突。aa+i2i=1,2,

证明,如果哈希表的大小为,的素数大于,并且至少所有位置的一半是空闲的,则此过程始终会产生一个空位置。pp3

提示:如果为素数,则利用残基类环为字段的事实,因此最多具有解。ppi2=c2


2

如果您的哈希函数的形式为,其中为素数,并且是随机选择的,则2个不同的键哈希到同一存储桶的概率为。因此,对于,非常小。h(k)=a×kmodmma1mm=1009Pr{h(x)=h(y),xy}=0.00099108027

该方案称为:通用哈希。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.