Algorithm 为什么哈希表的大小127(素数)比128好?

Algorithm 为什么哈希表的大小127(素数)比128好?,algorithm,hash,primes,Algorithm,Hash,Primes,假设简单的统一散列,也就是说,任何给定的值都类似于散列到散列的任何插槽中。为什么使用大小为127而不是128的表更好?我真的不明白2个数的幂有什么问题。或者它到底有什么不同 在使用除法时,, 我们通常避免使用某些值 m(表大小)。例如,m 不应该是2的幂,因为如果m =2^p,则h(k)只是k的p个最低阶位 假设可能的元素仅在1到10000之间,我选择表大小为128。怎样才能更好? 所以128是2^6(1000000),127是011111。这有什么区别?对于127,所有数字(散列时)仍然是k的

假设简单的统一散列,也就是说,任何给定的值都类似于散列到散列的任何插槽中。为什么使用大小为127而不是128的表更好?我真的不明白2个数的幂有什么问题。或者它到底有什么不同

在使用除法时,, 我们通常避免使用某些值 m(表大小)。例如,m 不应该是2的幂,因为如果m =2^p,则h(k)只是k的p个最低阶位

假设可能的元素仅在1到10000之间,我选择表大小为128。怎样才能更好? 所以128是2^6(1000000),127是011111。这有什么区别?对于127,所有数字(散列时)仍然是k的p个最低阶位。我做错什么了吗

我正在寻找一些例子,因为我真的不明白为什么这样不好。提前多谢

附:我知道:

如果你有一个均匀分布的完美散列函数,那么这并不重要。

首先,这不是挑选一个素数。例如,如果您知道您的数据集将在1到10000之间,那么选择127或128不会有什么区别,因为这是一个糟糕的设计选择

相反,最好为您的示例选择一个真正大的素数,如3967,以便每个数据都有自己唯一的键/值对。您只需要最小化碰撞。为您的示例选择127或128不会有什么区别,因为所有127/128存储桶都将被均匀填充(这很糟糕,会降低插入和查找运行时间O(1)到O(n)),而不是3967(这将保留O(1)运行时间)

编辑#4

介绍了“哈希函数”的设计 有点像黑人艺术。可能是 受以下数据的高度影响: 拟储存在 基于哈希的数据结构,因此 关于合理散列的讨论 功能经常会陷入一个混乱的状态 关于具体投入的讨论

至于素数为什么是“首选”的,人们已经知道了 考虑“对手”分析, 假设我设计了一个将军 基于散列的数据结构,如何 在输入最差的情况下,它会执行吗 来自对手。自演出以来 是由对冲突进行哈希处理决定的 问题变成了什么是散列 使用最大限度地减少碰撞的方法 最坏的情况。其中一个条件是 当输入总是数字时 可以被某个整数整除的,比如说4。如果 使用N=128,然后使用任意数字 可被4整除的模128仍然是 可以被4整除,这意味着 桶4、8、12。。。永远都是 已使用,导致资源利用率达到25% 数据结构。素数有效 降低了发生这种情况的可能性 场景发生,数字>N


维基百科实际上对此有一个很好的总结:

他们指出,一些散列函数被设计成只对素数进行运算。这篇文章解释了为什么两种力量是不好的:


尼克是对的,一般来说,哈希表的大小并不重要。但是,在使用带有双哈希的开放寻址的特殊情况下(其中探测之间的间隔由另一个哈希函数计算),最好使用素数大小的哈希表来确保所有哈希表条目都可用于新元素(如我们所述)

对于127,所有数字(散列时)仍然是k的p个最低阶位

这是错误的(或者我误解了…)<代码>k%127取决于k的所有位<代码>k%128仅取决于7个最低位


编辑:

如果你有一个1到10000之间的完美分布
10000%127
10000%128
这两个版本都将在一个非常小的发行版中实现这一点。所有存储桶将包含10000/128=78(或79)个项目

如果你的分布在1到10000之间,这是有偏差的,因为{x,2x,3x,…}更频繁地出现。然后一个素数大小将给出一个更好的分布,如本文所解释的。(除非x正好是该基本尺寸。)


因此,如果低位中的分布足够好,则切掉高位(使用128的大小)没有任何问题。但是,对于真实数据和设计糟糕的散列函数,您将需要这些高位。

我无法再证明这一点,尽管我记得一百万年前在大学的一次考试中必须这样做,但最佳散列大小不仅仅是素数。您希望选取一个质数N,使得
N=4*M− 1
(其中M也是一个整数)

这使得31个桶的数量比29个好。当N为31时,M为8,但当N为29时,不存在积分M

正如我所说,我已经不记得用数学来证明这一点了。大约25年前,Udi的妻子Rachel Manber教授了一门理论课。

除法 “在使用除法时,我们通常避免使用某些m值 (表大小)。例如,m不应是
2
的幂,因为如果m=
2p
,那么
h(k)
就是
p
k
的最低阶位

--CLRS

要理解为什么
m=2p
只使用
p
k的最低位,必须首先理解模散列函数
h(k)=k%m

可以用商
q
和余数
r
来编写键

k = nq + r
选择商为
q=m
允许我们将
k%m
简单地写为上述等式中的余数:

k % m = r = k - nm,  where r < m
让我们尝试用
m=24=16
散列键
k=91

  91 = 0101 1011
- 16 = 0001 0000
----------------
  75 = 0100 1011
- 16 = 0001 0000
----------------
  59 = 0011 1011
- 16 = 0001 0000
----------------
  43 = 0010 1011
- 16 = 0001 0000
----------------
  27 = 0001 1011
- 16 = 0001 0000
----------------
  11 = 0000 1011
因此,
91%24=11
只是
91
的二进制形式,只剩下
p=4
最低位


重要区别:
  91 = 0101 1011
- 16 = 0001 0000
----------------
  75 = 0100 1011
- 16 = 0001 0000
----------------
  59 = 0011 1011
- 16 = 0001 0000
----------------
  43 = 0010 1011
- 16 = 0001 0000
----------------
  27 = 0001 1011
- 16 = 0001 0000
----------------
  11 = 0000 1011