【问题标题】:Cuckoo Hashing Collisions lead to overflowCuckoo Hashing Collisions 导致溢出
【发布时间】:2015-12-01 19:47:38
【问题描述】:

我正在尝试使用散列函数实现布谷鸟散列: hash1: key.hashcode() % 容量 hash2: key.hashcode()/容量%容量

使用无限循环检查和重新散列方法使容量增加一倍。该程序适用于少量数据,但当数据变大(大约 20k 个元素)时,程序会不断重新散列,直到容量溢出。

我认为无限重新散列主要是由具有完全相同哈希码的数据引起的。重新散列后,其他数据有可能得到相同的哈希码并再次引起重新散列。

我已经使用 Java 内置哈希码,但是当数据量很大时,相同哈希码的机会仍然很高。即使我修改了一点hashcode方法,最终仍然有相同hashcode的数据。

那么我应该使用哪种哈希方法来防止这种情况发生?

【问题讨论】:

  • 您确定您的数据元素是唯一的吗?
  • 它们不是唯一的,但我确信存在的元素会在不插入的情况下得到处理。此外,我已经通过打印数据(在本例中为 String 类型)进行了检查。由不同的字符串导致的问题,但具有相同的哈希码。
  • 好的,在这种情况下,使用自定义哈希函数。你的capacity 可以是什么?
  • 我做了一个自定义的,然后它仍然会遇到同样的问题,因为最终另一组数据使用 myHashCode 函数获得了相同的哈希码。我什至尝试将我的和内置的哈希码结合起来。还是行不通。我的能力可以是任何。我让它在每次重新散列时增长。

标签: java algorithm hash stack-overflow collision


【解决方案1】:

创建散列函数的常用方法通常是使用素数。我写了一个函数(如下),我不保证不会发生冲突,但应该减少它。

hashFunction1(String s){
    int k = 7;         //take a prime number, can be anything (I just chose 7)
    for(int i = 0; i < s.length(); i++){
        k *= (23 * (int)(s.charAt(i)));
        k %= capacity;
    }
}
//23 is another randomly chosen number.

您可以编写与 hashFunction2 类似的散列函数,选择两个不同的素数。但这里的主要问题是,对于字符串“stop”和“pots”,这给出了相同的哈希码。

因此,对该功能的即兴创作可以是:

hashFunction1(String s){
    int k = 7;         //take a prime number, can be anything (I just chose 7)
    for(int i = 0; i < s.length(); i++){
        k *= (23 * (int)(s.charAt(i)));
        k += (int)(s.charAt(i));
        k %= capacity;
    }
}

这将解决这个问题(对于大多数情况,如果不是全部)。

如果你仍然觉得这个函数不好,你可以使用映射到每个字符的唯一素数来代替 s.charAt(i),即。 a=3、b=5、c=7、d=11 等等。这应该可以更好地解决冲突。

编辑:

  1. 您使用的是+n,这是一个常量。
  2. 2 不是在这种情况下使用的素数。使用奇数素数,3 个有效。

【讨论】:

  • 这个有点像我的自定义函数。我使用素数 2。对于每个字符,我增加素数 n = 2; for(int i = 0; i
  • 不相似,你的有问题。我将编辑我的答案并指定这些问题,与此同时,请使用我的 hashFunction 并使用素数 (7,23) 第一和 (13,31) 第二。
  • 不错!!现在看来运作良好。但是你如何处理重新散列?我的 rehash 方法只是将容量加倍。它运行良好,但容量仍然很大,尽管负载率仍然很小(大约 10%)。
  • @concuagia,cuckoo hash 的通常实现使容量翻倍,但我不知道是否每次都需要这样做。您可以将容量增加约 10%,然后看看会发生什么。此外,在 cuckoo hashing 的 wiki 页面中,它引用:“无需为重新散列分配新表:我们可以简单地遍历表以删除所有发现不在其位置的键并执行通常的插入过程。表中的预期位置。”
  • 我已经阅读并尝试过。效果不太好,以后会努力改进的。关于容量,我尝试增加不到一倍,只是运行时间更长,但容量仍然很大。
猜你喜欢
  • 2011-11-15
  • 1970-01-01
  • 1970-01-01
  • 2019-10-11
  • 2015-05-21
  • 2014-02-14
  • 2016-09-12
  • 2011-10-31
  • 2020-09-05
相关资源
最近更新 更多