Bloom Filter 原理 及C++ 实现

本文介绍了布隆过滤器的基本原理和用途,它是一种用于检索元素是否在集合中的数据结构,具有空间效率高但存在误识别率。内容包括布隆过滤器的构成、错误率估算、最优哈希函数数量和位数组大小的确定,以及C++实现的示例。常见应用包括大数据处理、邮箱过滤、分布式数据库等。

布隆过滤器[1](Bloom Filter)是由布隆(Burton Howard Bloom)在1970年提出的。
它实际上是由一个很长的二进制向量和一系列随机映射函数组成,布隆过滤器可以用于检索一个元素是否在一个集合中。

它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率(假正例False positives,即Bloom Filter报告某一元素存在于某集合中,但是实际上该元素并不在集合中)和删除困难,但是没有识别错误的情形(即假反例False negatives,如果某个元素确实没有在该集合中,那么Bloom Filter 是不会报告该元素存在于集合中的,所以不会漏报)。

 

主要思路是

1. 使用位图或者位数组表示m个0的集合M;

2. 使用K个hash函数将N个元素映射到集合M中的某一位,并使这位为1;

3. 查询时候当给一个query 使用K个hash函数映射后,对应的m为都为1,则存在,否则不存在。

具体思路使用M 位数组表示集合

Bloom filter 会使用K个hash函数 将某一个元素x_i, 映射到M中,如下图所示

判断给定一个元素y在不在这个集合,则用K个hash函数对y做映射,所有位都为1 则存在,否则不存在。

错误率估计

在Chapter 4 “Mining of Massive data”-CMU Anand Rajaraman的书中把错误率的计算:

If a key value is in S, then the element will surely pass through the Bloom filter. However, if the key value is not inS, it might still pass. We need to
understand how to calculate the probability of afalse positive, as a function of n, the bit-array length, mthe number of members of S, and k, the number of
hash functions.
The model to use is throwing darts at targets. Suppose we havextargets
andy darts. Any dart is equally likely to hit any target. After throwing the
darts, how many targets can we expect to be hit at least once?

主要的思路是计算转化为一个飞镖问题,有m个靶位,有n个飞镖,假设每个飞镖有k次机会,(相当于n*k个镖)投中某个特定靶位的概率。

假设我们将hash函数认为是随机的,投镖的过程也是随机的,

那么每次我们投不中特定的靶位的概率为(1-1/m)

投n*k次的话 (1-1/m)^(n*k), 使用

当n*k个镖都投完某一位还为0的概率是p = e^(-kn/m)

 

最优的hash函数个数及位数组的个数:

对于某个y元素经过k个hash函数映射后 都为1的概率是f =(1-p)^k. 对这个式子取ln,可以得到 g = k ln(1 − e−kn/m)

这样使得

### 布隆过滤器的原理 布隆过滤器是一种空间效率高的概率型数据结构,用于测试某个元素是否属于一个集合。它通过多个哈希函数将元素映射到一个位数组上,并利用这些位置来判断该元素是否存在于集合中[^5]。 #### 工作机制 1. **初始化**:创建一个长度为 m 的二进制向量(初始值全为0),并选择 k 个独立的哈希函数。 2. **插入操作**:对于每一个新加入的元素 x,计算其对应的 k 个哈希值 h₁(x), h₂(x)...hₖ(x),并将这 k 个索引上的比特位设置为1。 3. **查询操作**:对于待查元素 y,同样计算其 k 个哈希值 h₁(y), h₂(y)...hₖ(y)。如果所有对应的位置都为1,则认为该元素可能存在于集合中;如果有任意一位不为1,则可以肯定该元素不在集合中。 由于可能存在不同的输入产生相同的哈希值的情况,因此布隆过滤器存在一定的误判率,即可能会错误地判定某些不属于集合中的元素为“可能属于”。 ```java import java.util.BitSet; public class BloomFilter { private BitSet bitset; private int size; // Bit array size private int hashCount; // Number of hash functions public BloomFilter(int size, int hashCount){ this.size = size; this.hashCount = hashCount; this.bitset = new BitSet(size); } public void add(String s){ for (int i=0;i<hashCount;i++) { int index = Math.abs(s.hashCode() * i % size); bitset.set(index); } } public boolean mightContain(String s){ for (int i=0;i<hashCount;i++) { int index = Math.abs(s.hashCode()*i%size); if (!bitset.get(index)) return false; } return true; } } ``` ### 应用场景 布隆过滤器因其高效的空间利用率和快速的操作时间,在许多实际应用场景中有广泛的应用价值: - **网络爬虫**:用来记录已经访问过的URL地址,避免重复抓取同一页面的内容[^6]。 - **缓存系统**:帮助数据或其他存储服务减少不必要的磁盘I/O请求,先通过布隆过滤器筛选掉那些一定不存在的数据项后再发起真实查找。 - **拼写检查工具**:作为字典的一部分,加速单词合法性验证过程的同时节省内存开销。 ### 面试常见问题分析 在技术面试过程中,关于布隆过滤器的问题往往围绕以下几个方面展开: - 对基本概念的理解程度; - 实际工程环境中如何权衡参数选取(比如bit vector大小m、hash function数量k等)以达到最佳性能表现; - 如何处理假阳性问题以及改进措施讨论。 ### 八股文解析 所谓八股文式的解答方式是指按照固定的模板框架组织答案内容,使得表达更加条理清晰且易于理解接受。针对布隆过滤器这一主题可采用如下形式进行阐述说明: 首先概述什么是布隆过滤器及其特点优势所在;接着详细介绍内部运作机理包括各个组成部分的作用关系描述;最后列举若干典型实例展示其强大功能用途同时提及局限性和优化方向思考建议。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值