【问题标题】:Bloom filters and its multiple hash functions布隆过滤器及其多个哈希函数
【发布时间】:2018-07-21 11:36:35
【问题描述】:

我正在实现一个简单的布隆过滤器作为练习。

布隆过滤器需要多个哈希函数,而出于实际目的,我没有。

假设我想要 3 个散列函数,仅仅获取我正在检查成员资格的对象的散列,散列它(使用 murmur3)然后添加 +1、+2、+3(对于 3 个不同的哈希值)在再次对它们进行哈希处理之前?

由于 murmur3 函数具有非常好的雪崩效应(确实分散了结果),这对于所有目的来说不是合理的吗?

伪代码:

function generateHashes(obj) {
  long hash = murmur3_hash(obj);
  long hash1 = murmur3_hash(hash+1);
  long hash2 = murmur3_hash(hash+2);
  long hash3 = murmur3_hash(hash+3);
  (hash1, hash2, hash3)
}

如果不是,那么有什么简单、有用的方法来解决这个问题?我想要一个解决方案,如果需要的话,我可以轻松地扩展更多的哈希函数。

谢谢

【问题讨论】:

    标签: algorithm hash bloom-filter murmurhash


    【解决方案1】:

    AFAIK,通常的方法是不实际使用多个哈希函数。相反,散列一次并将生成的散列拆分为 2、3 或您想要的 Bloom 过滤器的部分。因此,例如创建一个 128 位的散列并将其拆分为 2 个 64 位的散列。

    https://github.com/Claudenw/BloomFilter/wiki/Bloom-Filters----An-overview

    【讨论】:

    • 最佳答案和链接,谢谢。这就是我一直在寻找的。​​span>
    【解决方案2】:

    布隆过滤器的哈希函数应该足够独立和随机。 murmur hash 非常适合这个目的。所以你的方法是正确的,你可以按照自己的方式生成尽可能多的新哈希。出于教育目的,这很好。

    但在现实世界中,多次运行散列函数非常耗时,因此通常的方法是创建临时散列而不实际计算散列。

    要纠正@memo,这不是通过将散列拆分为多个部分来完成的,因为散列的宽度应该保持不变(并且您不能将 64 位散列拆分为超过 64 个部分;))。方法是获取两个独立的哈希并将它们组合起来。

    function generateHashes(obj) {
      // initialization phase
      long h1 = murmur3_hash(obj);
      long h2 = murmur3_hash(h1);
    
      int k = 3; // number of desired hash functions
      long hash[k];
    
      // generation phase
      for (int i=0; i<k; i++) {
          hash[i] = h1 + (i*h2);
    
      return hash;
    }
    

    如您所见,这种创建新哈希的方式是一个简单的乘加操作。

    【讨论】:

      【解决方案3】:

      这不是一个好方法。让我试着解释一下。布隆过滤器allows you to test if an element most likely belongs to a set, or if it absolutely doesn’t. In others words, false positives may occur, but false negatives won’t.

      参考:https://sc5.io/posts/what-are-bloom-filters-and-why-are-they-useful/

      让我们考虑一个例子:

      您有一个输入字符串“foo”,我们将它传递给多个哈希函数。 murmur3 哈希给出了输出 K,随后对该哈希值的哈希给出了 xyz

      现在假设你有另一个字符串'bar',碰巧它的murmur3哈希也是K。剩余的哈希值?它们将是xyz,因为在您提出的方法中,后续哈希函数不依赖于输入,而是依赖于第一个哈希函数的输出。

      long hash1 = murmur3_hash(hash+1);
      long hash2 = murmur3_hash(hash+2);
      long hash3 = murmur3_hash(hash+3);
      

      如链接中所述,目的是在集合中执行概率搜索。如果我们搜索“foo”或“bar”,我们会说它们“很可能”都存在。所以误报的百分比会增加。

      换句话说,这个布隆过滤器的行为就像一个简单的哈希函数。它的“绽放”方面不会出现,因为只有第一个哈希函数决定了搜索的结果。

      希望我能够充分解释。如果您有更多后续查询,请在 cmets 中告诉我。很乐意提供帮助。

      【讨论】:

        猜你喜欢
        • 2010-10-14
        • 2011-09-30
        • 1970-01-01
        • 2014-11-10
        • 1970-01-01
        • 2012-08-10
        • 1970-01-01
        • 1970-01-01
        • 2012-03-03
        相关资源
        最近更新 更多