与散列冲突(CLRS)

时间:2016-04-09 15:15:46

标签: algorithm hash hashtable clrs

我正在努力解决这个问题(CLRS,第3版,练习11.2-1):

  

假设我们使用散列函数h将n个不同的键散列为长度为m的数组。假设简单的均匀散列,预期的碰撞次数是多少?

正确的解是n(n-1)/ 2m。这取自CLRS的教师手册。

我的解决方案如下:

  • 对于键1的插入:预期与前辈的碰撞次数= 0

  • 对于键2的插入:预期与前辈的碰撞次数= 1 / m

  • 对于键3的插入:预期与前驱的碰撞数#1 / m *(1 / m)+(m-1)/ m *(2 / m)=(2m-1)/ m ^ 2

我的理由:关键1和1的概率为1 / m。 2碰撞在1个槽中,这意味着键3的碰撞概率为1 / m。密钥1和密钥2没有碰撞的概率为(m-1)/ m,这意味着它们位于不同的槽中,密钥3的碰撞概率为2 / m。

3个键的预期碰撞次数,按期望线性度= 0 + 1 / m +(2m-1)/ m ^ 2 =(3m-1)/ m ^ 2

根据CLRS,3个键的预期碰撞次数应为3 / m。

我知道如何使用指标RV的 找到正确的解决方案。

我的问题是:我的解决方案在哪里出错?为什么会有所不同?

2 个答案:

答案 0 :(得分:0)

教员手册中的解决方案似乎已关闭。一个简单的例子,将12个键[0..11]通过h(k)= k mod 3散列为3个元素的数组。

我们有存储桶0,其键为0、3、6、9。值区1有键1,4,7,10。值区2具有键2,5,8,11。存储桶0的冲突为{(0,3),(0,6),(0、9),(3,6),(3,9),(6,9)},基数= 6。铲斗1和2也各造成6次碰撞。

因此,本示例中的总碰撞次数为18。如果期望的碰撞次数由n(n-1)/ 2m公式给出,则该碰撞次数将为12 * 11/6 = 22。

错。

通过这样的推理,我得出了另一个公式:

  1. 如果我们假设使用统一哈希,则每个存储桶中的键数应与其他任何键数相同,即n / m。因此,碰撞总数将为m * Collisions(单个存储桶)。

  2. 现在,我们如何获取每个存储桶中的碰撞次数?好吧,其中的每个键都与所有其他键发生冲突,并且通过一次将它们成对定义冲突集。因此,我们正在研究一次取两个(n / m)个元素的数量组合

C(n / m,2)=(n / m)!/ [2!(n / m -2)!] = [(n / m)(n / m -1)(n / m- 2)!] / [2 *(n / m -2)!]。

(n / m-2)!分子/分母中的各项互相抵消,我们得到

C(n / m,2)= [(n / m)(n / m-1] / 2 = n(n-m)/ 2m ^ 2

因此,碰撞总数为m * C(n / m,2)= n(n-m)/ 2m。

让我们将此应用于我们的示例,对吧?

12(12-3)/ 2 * 3 = 12 * 9/6 = 18

在我们的示例中,这恰好是一组碰撞的基数。

答案 1 :(得分:-1)

  

密钥1和1的概率为1 / m。 2碰撞在1个槽中,这意味着键3的碰撞概率是1 / m

这取决于如何处理碰撞。对于闭合哈希实现,将为密钥2选择备用存储桶,因此在插入密钥3时第一个哈希到存储桶发生冲突的可能性仍然是2 / m(那么第二选择可能还有机会)铲斗,第3选择铲斗等 - 见下文)。对于开放散列,碰撞元素将被链接在同一个桶中,因此如果密钥1和2发生冲突,则密钥3首次散列​​到同一个桶的概率减少1 / m(并且可能还有更多的机会在第二选择桶等上碰撞。)。

所以,一个很大的问题是你采用了不同的碰撞处理方法:封闭式和开放式散列。

那就是说,你提出的问题含糊不清 - 碰撞后如何增加价值会影响进一步碰撞的可能性。例如,使用另一个散列算法进行重新散列也可以实现简单的统一散列,这意味着每次碰撞后重新插入尝试时会出现另一个#insertition /#bucket冲突概率,所以系列会:

  • 密钥1:预期#claisions = 0

  • 键2:预期#collisions = 1 / m + 1 / m * 1 / m + 1 / m * 1 / m * 1 / m + ...

  • 键3:预期#collisions = 2 / m + 2 / m * 2 / m + 2 / m * 2 / m * 2 / m + ......

例如,它会有所不同。线性探测,二次探测等。