布隆过滤器设计

时间:2012-01-08 09:05:34

标签: algorithm hash bloom-filter

我想知道在哪里可以找到Bloom过滤器的实现,并提供有关散列函数选择的一些解释。

此外,我还有以下问题:
1)已知布隆过滤器具有误报。是否可以通过使用两个过滤器来减少它们,一个用于已使用的元素,一个用于未使用的元素(假设该集合是有限的并且已知先验)并比较两者? 2)CS文献中还有其他类似的算法吗?

4 个答案:

答案 0 :(得分:1)

我的直觉是,通过使用反滤波器占用的额外空间来扩展正滤波器,可以更好地减少误报。

至于资源方面,3月8日从my course syllabus引用的论文会很有用。

答案 1 :(得分:0)

可以从here找到Bloom过滤器的Java实现。如果您无法查看,我将粘贴以下代码(中文注释)。

import java.util.BitSet;

publicclass BloomFilter 
{
    /* BitSet初始分配2^24个bit */ 
    privatestaticfinalint DEFAULT_SIZE =1<<25; 
    /* 不同哈希函数的种子,一般应取质数 */
    privatestaticfinalint[] seeds =newint[] { 5, 7, 11, 13, 31, 37, 61 };
    private BitSet bits =new BitSet(DEFAULT_SIZE);
    /* 哈希函数对象 */ 
    private SimpleHash[] func =new SimpleHash[seeds.length];

    public BloomFilter() 
    {
        for (int i =0; i < seeds.length; i++)
        {
            func[i] =new SimpleHash(DEFAULT_SIZE, seeds[i]);
        }
    }

    // 将字符串标记到bits中
    publicvoid add(String value) 
    {
        for (SimpleHash f : func) 
        {
            bits.set(f.hash(value), true);
        }
    }

    //判断字符串是否已经被bits标记
    publicboolean contains(String value) 
    {
        if (value ==null) 
        {
            returnfalse;
        }
        boolean ret =true;
        for (SimpleHash f : func) 
        {
            ret = ret && bits.get(f.hash(value));
        }
        return ret;
    }

    /* 哈希函数类 */
    publicstaticclass SimpleHash 
    {
        privateint cap;
        privateint seed;

        public SimpleHash(int cap, int seed) 
        {
            this.cap = cap;
            this.seed = seed;
        }

        //hash函数,采用简单的加权和hash
        publicint hash(String value) 
        {
            int result =0;
            int len = value.length();
            for (int i =0; i < len; i++) 
            {
                result = seed * result + value.charAt(i);
            }
            return (cap -1) & result;
        }
    }
}

在设计布隆过滤器方面,布隆过滤器所需的哈希函数的数量可以在here中确定,同时引用Wikipedia article about Bloom filters,然后您会找到误差概率的部分。本节介绍散列函数的数量如何影响误报的概率,并为您提供从期望的预期概率确定 k 的公式。误报。


来自维基百科的文章:

  显然,虚假的概率   正数减少为m(数字   数组中的位数增加,并且   增加为n(插入的数量)   元素)增加。对于给定的m和   n,k的值(散列数   函数)最小化   概率是

     

formula

答案 2 :(得分:0)

使用Java 8功能实现Bloom过滤器非常容易。您只需要long[]来存储这些位,以及一些哈希函数,您可以使用ToIntFunction<T>来表示这些函数。我在doing this from scratch上做了简短的写作。

要注意的部分是从数组中选择正确的位。

public class BloomFilter<T> {

     private final long[] array;
     private final int size;
     private final List<ToIntFunction<T>> hashFunctions;

     public BloomFilter(long[] array, int logicalSize, List<ToIntFunction<T>> hashFunctions) {
         this.array = array;
         this.size = logicalSize;
         this.hashFunctions = hashFunctions;
     }

     public void add(T value) {
         for (ToIntFunction<T> function : hashFunctions) {
              int hash = mapHash(function.applyAsInt(value));
              array[hash >>> 6] |= 1L << hash;
         }
     }

     public boolean mightContain(T value) {
         for (ToIntFunction<T> function : hashFunctions) {
              int hash = mapHash(function.applyAsInt(value));
              if ((array[hash >>> 6] & (1L << hash)) == 0) {
                   return false;
              }
         }
         return true;
    }

    private int mapHash(int hash) {
         return hash & (size - 1);
    }


    public static <T> Builder<T> builder() {
         return new Builder<>();
    }

    public static class Builder<T> {
         private int size;
         private List<ToIntFunction<T>> hashFunctions;

         public Builder<T> withSize(int size) {
             this.size = size;
             return this;
         }

         public Builder<T> withHashFunctions(List<ToIntFunction<T>> hashFunctions) {
              this.hashFunctions = hashFunctions;
              return this;
          }

         public BloomFilter<T> build() {
              return new BloomFilter<>(new long[size >>> 6], size, hashFunctions);
         }
     }  
}

答案 3 :(得分:-1)

我认为我们应该看一下Bloom Filters的应用,而秘密在于名称,它是一个过滤器而不是数据结构。它主要用于通过检查项目是否不属于集合来节省资源。如果你想将误报最小化为0,你将不得不插入所有不属于集合的项目,因为设计良好的布隆过滤器没有假阴性,除了布隆过滤器将是巨大的和不实用的,也许只是将项目存储在跳过列表:)我写了一个关于Bloom Filters的简单教程,如果有人感兴趣的话。

http://techeffigy.wordpress.com/2014/06/05/bloom-filter-tutorial/