Hash 通用散列的预期界限

Hash 通用散列的预期界限,hash,language-agnostic,Hash,Language Agnostic,我相信这是一个简单的问题,但我没有看到一个明显的解决办法。。。如果我有一个包含m个bin的哈希表,并将其散列到nn/m),我应该期望进行多少次再灰化操作。对于均匀分布,这与将球扔进垃圾箱是一样的,m.Raab和a.Steger对此进行了研究 这是一个有点相关的,但在这里你只使用一个哈希函数 这是stackoverflow.com,我给你一个模拟程序,可以用来验证你的公式。根据这一点,它还取决于球/桶的数量,而不仅仅取决于每个桶的平均球数 public static void main(Strin

我相信这是一个简单的问题,但我没有看到一个明显的解决办法。。。如果我有一个包含m个bin的哈希表,并将其散列到nn/m),我应该期望进行多少次再灰化操作。

对于均匀分布,这与将球扔进垃圾箱是一样的,m.Raab和a.Steger对此进行了研究

这是一个有点相关的,但在这里你只使用一个哈希函数

这是stackoverflow.com,我给你一个模拟程序,可以用来验证你的公式。根据这一点,它还取决于球/桶的数量,而不仅仅取决于每个桶的平均球数

public static void main(String... args) throws InterruptedException {
    for (int k = 1; k < 4; k++) {
        test(10, 30, k);
        test(100, 300, k);
    }
}

public static void test(int ballCount, int binCount, int k) {
    int rehashCount = 0;
    Random r = new Random(1);
    int testCount = 100000000 / ballCount;
    for(int test = 0; test < testCount; test++) {
        long[] balls = new long[ballCount];
        int[] bins = new int[binCount];
        for (int i = 0; i < ballCount; i++) {
            balls[i] = r.nextLong();
        }
        // it's very unlikely to get duplicates, but test
        Arrays.sort(balls);
        for (int i = 1; i < ballCount; i++) {
            if (balls[i - 1] == balls[i]) {
                throw new AssertionError();
            }
        }
        int universalHashId = 0;
        boolean rehashNeeded = false;
        for (int i = 0; i < ballCount; i++) {
            long x = balls[i];
            // might as well do y = x
            long y = supplementalHashWeyl(x, universalHashId);
            int binId = reduce((int) y, binCount);
            if (++bins[binId] > k) {
                rehashNeeded = true;
                break;
            }
        }
        if (rehashNeeded) {
            rehashCount++;
        }
    }
    System.out.println("balls: " + ballCount + " bins: " + binCount +
            " k: " + k + " rehash probability: " + (double) rehashCount / testCount);
}

public static int reduce(int hash, int n) {
    // http://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction/
    return (int) (((hash & 0xffffffffL) * n) >>> 32);
}

public static int supplementalHashWeyl(long hash, long index) {
    long x = hash + (index * 0xbf58476d1ce4e5b9L);
    x = (x ^ (x >>> 32)) * 0xbf58476d1ce4e5b9L;
    x = ((x >>> 32) ^ x);
    return (int) x;
}

假设你有一个有效的散列,你应该看看生日问题。
直到我在任何一个容器中看到的碰撞不超过k次(显然是k>n/m)。
上限是一个糟糕的度量,IMHO。相反,您可以使用平均(或预期)链长度,它与检索一个元素的工作量有关。对于n==m,给定一个合理的散列函数,这刚好低于1.5。我对k次以上碰撞的概率感兴趣的原因是,当一个箱子高于一个常数时,我想重新灰化,我希望重新灰化后的概率足够小,我可以得到一个几何级数,这样我就可以期望有限次的重新灰化。对于使用生日问题,我想我需要密钥均匀分布。拥有一个通用散列分布是否足以应用它?我想math.stackexchange.com是解决这个问题的一个更好的地方。我想我的问题是,“球和箱子”概率是否也适用于通用散列条件,它不像箱子上的随机分布那样严格。我对这个感兴趣的是我正在写的一些课堂讲稿,我想涵盖通用散列和重新散列。我还将写关于布谷鸟哈希的文章,但这是下一章的内容。我想先介绍一下更简单的重新洗牌的想法。我想知道的是,作为每个箱子的最大碰撞数的函数,我期望的重新灰化操作数之间的关系。如果钥匙以均匀分布放置在箱子中,我可以计算出来,但如果我有x!=y=>Pr[h(x)=h(y)]我有拉斯穆斯·帕赫,他是布谷鸟哈希法的两位作者之一,正在校对注释,因此,我相信如果我出错,他会理解的:)我只是想做一些简单设置的封底计算,如果在同一个容器中得到的球超过一个固定常数,那么你可以重新进行哈希运算。很抱歉,我不明白“使用位掩蔽而不是模的通用哈希构造”是什么意思。我很确定可以使用位屏蔽或模(或其他)进行通用哈希?对于信封背面的计算,我认为上面的公式应该很好。。。但我认为最好写一个小的模拟程序,这就是你想要的吗?对于数学方面的内容,您可以使用math.stackexchange.com创建通用族,该族使用的模数为Pr[h(x)=h(y)]
balls: 10 bins: 30 k: 1 rehash probability: 0.8153816
balls: 100 bins: 300 k: 1 rehash probability: 1.0
balls: 10 bins: 30 k: 2 rehash probability: 0.1098305
balls: 100 bins: 300 k: 2 rehash probability: 0.777381
balls: 10 bins: 30 k: 3 rehash probability: 0.0066018
balls: 100 bins: 300 k: 3 rehash probability: 0.107309