`

从哈希存储到Bloom Filter

    博客分类:
  • Java
 
阅读更多

 

先解释一下什么是哈希函数。哈希函数简单来说就是一种映射,它可取值的范围(定义域)通常很大,但值域相对较小。哈希函数所作的工作就是将一个很大定义域内的值映射到一个相对较小的值域内。

传统的哈希存储

 

假设要哈希的集合为S,它有n个元素。传统的哈希方法是,将哈希区域组织成hh > n)个格子的列表,每一个格子都能存储S中的一个元素。存储时将S中的每一个元素映射到{0, 1, … , h-1}的范围内,然后以这个值为索引将此元素存储到对应的格子内。由于哈希函数将一个大集合映射到一个小集合中,所以存在将大集合中的多个元素映射到同一位置的情况,这就是所谓的碰撞(Collision)。当碰撞发生时,有多种策略可供选择,比如用链表将映射到同一位置的元素串起来,或者在碰撞发生时再进行哈希映射直到找到空位为止等等。

 

 

传统的哈希方法不会发生错误,而且存储的元素还可以复原。如果哈希函数选择得当,碰撞出现的情况比较少,那么查找某一个元素也很快。但是,如果你哈希某个集合只是为了判断某个元素是否在这个集合中,那么你会发现好像存储整个集合有点浪费。按传统的哈希方法判断某个元素是否属于集合时,会把这个元素和它映射位置上的元素进行匹配,如果完全匹配则说明属于集合,如果不匹配则不属于。在绝大部分查找都不能匹配的情况下(这常常是实际中的情况),我们会发现匹配的过程经常用不到整个元素,因为元素的一部分就可以判断不匹配了。基于“部分信息就能判断不匹配”这个思路,Burton BloomBloom Filter的发明者)提出了一种改进的方法。

改进的哈希存储

 

在这种改进的方法中,哈希区域和前面一样仍然被组织成格子的列表。但这次并不直接将集合元素存在格子里,而是将每一个元素编码然后将编码存在格子里。假设每个集合元素要占b位,编码后要占cc < b)位。由于编码位数少于元素位数,不同元素的编码有可能相同,因此在查找元素时可能会出现错误。编码位数取决于你期望的错误率:编码位数越多,错误就越少,反之则越大;当错误少到一定程度(大约2-b),编码位数就足以存下整个元素,因此就变回了传统的哈希存储。

 

 

这种方法对传统的哈希存储进行了改良,允许用户在错误率和存储空间之间作权衡。这里我们已经能够看到Bloom Filter的一点端倪。如果说这种方法已经孕育了“正确率换空间”的思想的话,那么Bloom Filter更是这个思想的大胆实践,它完全摆脱了传统的哈希存储方法,在存储空间使用和减少错误率方面又进了一步。

Bloom Filter

 

Bloom Filter中,哈希区域的每一位都被当成是独立的可寻址的单元。在对集合元素进行编码时,同时使用若干个独立的哈希函数,将每一个哈希函数映射的地址都置为1。这种编码方法可谓是另辟蹊径,摆脱了原来一个格子一个格子的存储方法。在改进的哈希存储中,编码位数是和正确率交换的筹码,而在Bloom Filter中,筹码变成了哈希函数的个数以及整个哈希区域(即位数组)的大小。如果想具体知道合适的哈希函数个数和位数组大小,请参阅第一篇Bloom Filter概念和原理

 

和前面两种哈希存储方法相比,Bloom Filter最大的优势自然是它的空间效率。另外,由于Bloom Filter不用处理碰撞(Collision),因此它在增加或查找集合元素时所用的时间完全恒定(哈希函数的计算时间),无论集合元素本身有多大,也无论多少集合元素已经加入到了位数组中。由于Bloom Filter和改进的哈希存储都对集合元素进行了编码,因此想要从哈希区域中恢复集合元素并不容易。但同时,如果你不想让别人直接看到集合元素,这样的编码处理倒可以看成是一种加密,有效保护了你的隐私。

 

Bloom Filter很大的一个缺点就是不能删除元素。由于Bloom Filter不处理碰撞,有可能多个哈希函数都映射到了同一位,因此不能简单地在删除时将1置为0。后面我们会看到,Counting Bloom Filter通过将每一位扩展为一个Counter来解决这一问题。

参考资

 

[1] B. Bloom. Space/Time Tradeoffs in Hash Coding with Allowable Errors. Communications of the ACM 13:7 (1970), 422—426.

[2] http://www.cs.berkeley.edu/~pbg/cs270/notes/lec27.pdf

[3] http://security.riit.tsinghua.edu.cn/seminar/2006_11_16/hash_function_yaxuan.ppt

分享到:
评论

相关推荐

    Bloom Filter概念和原理

    2. **插入操作**:当一个元素被加入到集合中时,Bloom Filter使用k个不同的哈希函数将该元素映射到位数组中的k个位置上,并将这些位置上的位设置为1。 3. **查询操作**:查询一个元素是否存在时,同样使用这k个哈希...

    bloom filter

    当一个元素被加入到Bloom Filter时,它会被通过这些哈希函数映射到数组中的几个位置,并在这些位置设置为1。查询一个元素是否存在时,该元素同样会通过相同的哈希函数计算其位置,如果这些位置都为1,则认为该元素...

    Python-bloomfilter过滤器

    **Python-bloomfilter过滤器详解** Bloom Filter是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。在Python开发中,尤其是在处理大量数据时,Bloom Filter可以有效地节省内存空间,尤其适用...

    java-bloomfilter

    BloomFilter&lt;String&gt; bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), 100000, 0.0001); // 添加元素 bloomFilter.put("element1"); bloomFilter.put("element2"); // 检查元素 ...

    Java版本的BloomFilter (布隆过滤器)

    BloomFilter&lt;String&gt; bloomFilter = BloomFilter.create(funnel, 100000, 0.03); bloomFilter.put("element1"); bloomFilter.put("element2"); System.out.println(bloomFilter.mightContain("element1")); //...

    多字段矩阵型bloomfilter(支持砍维度)

    在传统的Bloom Filter中,它通常处理单一的关键字,而在“多字段矩阵型Bloom Filter”中,这一概念被扩展到了支持多个字段的情况,这使得它在处理复杂数据集时更具灵活性。 首先,我们要理解Bloom Filter的基本原理...

    BloomFilter算法

    1. **不可逆**:一旦元素被添加到Bloom Filter中,无法删除,因为可能会删除其他元素的哈希位。 2. **误判**:可能会将不存在的元素判断为存在,但不会将存在的元素判断为不存在。 **C#实现** 在C#中,我们可以...

    bloom filter(C#版自制布隆过滤器)

    它是由 Burton Howard Bloom 在1970年提出的,主要应用于大数据存储和检索,尤其在数据库、缓存系统和网络搜索等领域有广泛应用。C# 版本的布隆过滤器实现了这一概念,通过使用八种不同的哈希函数来提高准确性和减少...

    Go-Go中的CuckooFilter实现比BloomFilter更好

    总的来说,Go中的Cuckoo Filter通过引入动态哈希和删除功能,提供了比Bloom Filter更优的解决方案,尤其在处理大量数据且对误报率和删除操作有要求的场景下。然而,选择哪种数据结构取决于具体的应用场景和需求。在...

    如何使用bloomfilter构建大型Java缓存系统Ja

    Guava的BloomFilter构造器会根据这些参数计算出合适的哈希函数数量和位数组大小。 接下来,我们可以将要缓存的元素添加到Bloom Filter中,使用`put()`方法。这个过程会通过内部的哈希函数将元素映射到位数组的特定...

    bloom filter布隆过滤器学习资料大全

    布隆过滤器的核心思想是通过多个哈希函数将元素映射到一个位数组中,如果位数组中的对应位置都被设置为1,那么可以认为这个元素可能存在于集合中。由于可能会出现误判(false positive),即位数组上所有位都是1的...

    Bloom Filter用于url去重

    与传统的哈希表相比,Bloom Filter最大的优势在于它占用的空间小,并且可以支持快速的查询操作。 Bloom Filter的基本结构包括: 1. **位数组**:一个很长的二进制位向量(通常称为位数组),初始状态下所有位都是0...

    Go-一个CuckooFilter的Go库BloomFilter的替代物

    它通过多个哈希函数将元素映射到一个固定大小的位数组中,避免了存储元素本身的空间开销。然而,Bloom Filter的主要缺点在于它的误判率,即当位数组中的某位被多个元素同时设置时,可能会导致不存在的元素被认为是...

    Go-bloom-Bloomfilters在Go中的实现

    - **不可删除**:一旦元素添加到Bloom Filter,无法从滤波器中移除。 ### 五、总结 Go语言中的Bloom Filter实现结合了Go的并发特性,能够高效处理大数据集。尽管存在误判问题,但在许多场景下,这一特性是可以接受...

    C语言实现的Bloomfilter算法。.zip

    在C语言中实现Bloom Filter涉及到多个关键知识点,包括哈希函数、位数组和概率计算。 1. **哈希函数**:Bloom Filter通常使用多个不同的哈希函数将元素映射到位数组的不同位置。哈希函数的选择至关重要,因为它们...

    Bloom filter 的研究和应用

    Bloom Filter的核心思想是在初始化时使用一个位数组和多个独立的哈希函数,当一个元素加入集合时,该元素会通过多个哈希函数映射到位数组中的不同位置,并将这些位置标记为“已存在”。 ##### 2. 工作原理 - **...

    LDFD-BloomFilter-master.zip

    为了解决这个问题,"LDFD-BloomFilter-master.zip"提供了一种基于Bloom Filter的高效解决方案。 Bloom Filter是一种空间效率极高的概率数据结构,用于判断一个元素是否在一个集合中。它可能会产生假阳性(False ...

Global site tag (gtag.js) - Google Analytics