【问题标题】:Hash code for array size 600 with least collisions数组大小为 600 且冲突最少的哈希码
【发布时间】:2017-03-22 07:01:17
【问题描述】:

所以我正在处理一个包含 400 个数据值的文件,这些数据值都是整数,值从 4 到 20,000 不等。我将所有这些加载到一个大小为 400 的数组中。还有另一个大小为 600 的 ListNodes 的空数组,我会将数据移动到其中,但使用的是自写的哈希码(我将在下面发布)。

因为长度为600的数组中的每个索引都有一个ListNode在里面,如果有冲突,那么数据值会添加到ListNode的后面。我还有一个方法可以返回空数组的百分比。但基本上由于我将 400 个数据值加载到大小为 600 的数组中,我可以拥有的最小百分比为 33.3%,因为如果没有冲突,则数组中的 400 个插槽被占用,200 个为空,但这不是这样的:

return (num+123456789/(num*9365))%600; //num is the value read from the array of 400

那个 hashCode 给了我 48.3% 空值的最佳结果,我需要它至少低于 47%。有什么建议或解决方案来改进这个 hashCode?我将不胜感激任何帮助。如果您需要更多信息或详细信息,请告诉我。谢谢!!!

【问题讨论】:

标签: java arrays hashcode


【解决方案1】:

我用随机数做了一些实验:在 [0, 599] 范围内生成 400 个均匀分布的随机数,并检查该范围内有多少值没有生成。事实证明,平均 51.3% 的值没有生成。所以你的 48.3% 已经好于预期了。 除非使用某种形式的完美散列,否则 47% 的目标似乎不切实际。

如果你想自己做一些实验,这里是程序。

public static void main(String[] args) {
    Random r = new Random();
    int[] counts = new int[600];
    for (int i = 0; i < 400; i++) {
        counts[r.nextInt(600)]++;
    }
    int n = 0;
    for (int i = 0; i < 600; i++) {
        if (counts[i] == 0) {
            n++;
        }
    }
    System.out.println(100.0 * n / 600);
}

【讨论】:

  • 这与小数定律有关。如果您在 [0;N] 范围内生成 N 个均匀分布的值,则大约有三分之一的值不会生成,三分之一会恰好生成一次,三分之一会多于一次。 (en.wikipedia.org/wiki/…)
  • 谢谢亨利,在等待回复时,我设法达到了 47.16666%,所以我将使用你的程序来看看我是否能得到更低的结果:
【解决方案2】:

我会使用哈希算法的 JAVA 实现:

Hava a look at open-jdk HashMap

static int hash(int h) {
     // This function ensures that hashCodes that differ only by
     // constant multiples at each bit position have a bounded
     // number of collisions (approximately 8 at default load factor).
     h ^= (h >>> 20) ^ (h >>> 12);
     return h ^ (h >>> 7) ^ (h >>> 4);
 }

请注意,您也必须添加一个模运算以确保该值不会大于 600


编辑 1

>>> is logical shift right

示例:

10000000 >>> 2 = 00100000

【讨论】:

  • 箭头有什么作用?我在java中从未见过。是的,我确实按 600/599 计算了模数,谢谢提醒!!
猜你喜欢
  • 2018-04-07
  • 2019-03-17
  • 1970-01-01
  • 2020-08-14
  • 2013-01-10
  • 1970-01-01
  • 2016-09-05
  • 2011-01-31
  • 2019-02-05
相关资源
最近更新 更多