【问题标题】:Why does this hash table lookup probe like it does?为什么这个哈希表查找探测会像它一样呢?
【发布时间】:2014-06-19 15:01:54
【问题描述】:

这段代码(从未知来源的 LZW 压缩程序中提取)在大小为 5021 的哈希表中找到一个空槽,索引从 0 到 5020:

probe := <random 12-bit hash key>
// probe is initially 0 to 4095
repeat
  {
  if table[probe] is empty then return(probe);
  if probe == 0 then probe := -1 else dec(probe, 5021-probe);
  if probe < 0 then inc(probe, 5021);
  }

这不是典型的线性或二次探测。为什么要这样探?这是一种已知的探测算法吗?我在哪里可以找到更多关于它的信息?

【问题讨论】:

    标签: algorithm hash probing


    【解决方案1】:

    尽管看起来很丑,但计算新探针的算法很简单:

    if probe == 0
        probe <= 5020
    else
        probe <= (2*probe) % 5021
    

    目前还不太清楚为什么选择了这个函数,但它确实以一种看似随机的循环方式遍历了所有可能的位置 1..5020(并且 0 被发送回循环)。 (不,它没有,看到糟糕了!) 需要注意的是,在这种情况下,数字 5021 有点神奇。

    这个算法实际上是一个线性同余生成器(LCG)。见http://en.wikipedia.org/wiki/Linear_congruential_generator

    OOPS:它是一个 LCG,但不是具有最佳周期的,因为 2^1004 % 5021 == 1。有以下五个不同的周期:(1, 2, 4, 8, ...), (3, 6, 12, 24, ...), (7, 14, 28, 56, ...), (9, 18, 36, 72, ...) , 和 (11, 22, 44, 88, ...)。更奇怪的是有人选择使用这种算法。 (或者我分析错了。)

    【讨论】:

    • 这里的 5021 有什么神奇之处? 5021 是素数,但 2 似乎有 1004 模 5021...
    • 5021 在 LCG 中并不神奇,因为它只是哈希表的大小。另一方面,哈希表的大小可能很神奇。但是,另一件事:为什么它会遍历所有可能的位置?参数是 a = 2, c = 0, m = 5021,不符合 Hull-Dobell 定理的标准(a-1 不能被 m 整除,c 不能与 m 互质)。
    • @tmyklebu 我认为选择了 5021 以便 2^i % 5021 == 1 仅当 i 可被 5020 整除时。选择这样的数字是可能的,但并非微不足道。然而,事实证明我的假设是错误的。 5021 背后没有魔法。
    • @delnan 对于 c=0,问题当然可以归结为原始根源。但是我注意到有点晚了,2 不是 5021 的原始根。通过说“有点神奇”,我假设 5021 已被选中,因此 2 是它的原始根。在这种情况下,a=2 很可能由于算术限制(仅使用加法和减法)是固定的。
    猜你喜欢
    • 2010-11-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-25
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    • 2012-07-08
    相关资源
    最近更新 更多