当前位置: 首页 > news >正文

布隆筛选详解

布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否存在于集合中。其核心特点是:可能误判元素存在,但绝不会误判元素不存在

一、基本原理

1. 数据结构
  • 位数组(Bit Array):初始全部为0的数组,用于存储元素的哈希值。
  • 多个哈希函数:将元素映射到数组的不同位置。
2. 操作流程
  1. 插入元素
    • 用多个哈希函数计算元素的哈希值,将对应位数组位置置为1。
  2. 查询元素
    • 用相同哈希函数计算元素的哈希值,检查对应位是否全为1:
      • 若全为1,元素可能存在(有一定误判率)。
      • 若有任何一位为0,元素必定不存在
3. 误判率(False Positive Rate)
  • 当位数组被频繁插入元素后,可能出现“所有查询位都被其他元素置为1”的情况,导致误判。
  • 误判率与位数组大小哈希函数数量插入元素数量相关。

二、核心公式

  1. 最优哈希函数数量
    k = m n ln ⁡ 2 k = \frac{m}{n} \ln 2 k=nmln2
    其中, m m m 为位数组大小, n n n 为预期插入元素数量。

  2. 误判率
    P ≈ ( 1 − e − k n m ) k P \approx \left(1 - e^{-\frac{kn}{m}}\right)^k P(1emkn)k
    k k k 取最优值时,误判率可简化为:
    P ≈ ( 1 2 ) k ≈ 0.6185 m / n P \approx \left(\frac{1}{2}\right)^k \approx 0.6185^{m/n} P(21)k0.6185m/n

  3. 位数组大小计算
    若期望误判率为 P P P,则:
    m = − n ln ⁡ P ( ln ⁡ 2 ) 2 m = -\frac{n \ln P}{(\ln 2)^2} m=(ln2)2nlnP

三、代码实现示例

以下是一个简化的布隆过滤器实现:

#include <vector>
#include <string>
#include <functional>class BloomFilter {
private:std::vector<bool> bitArray;  // 位数组int m;                       // 位数组大小int k;                       // 哈希函数数量std::hash<std::string> hasher;  // 简化示例,实际需多个不同哈希函数public:BloomFilter(int expectedElements, double falsePositiveRate) {// 计算位数组大小和哈希函数数量m = - (expectedElements * std::log(falsePositiveRate)) / (std::log(2) * std::log(2));k = (m / expectedElements) * std::log(2);bitArray.resize(m, false);}// 插入元素void insert(const std::string& element) {for (int i = 0; i < k; ++i) {// 生成k个不同哈希值(简化示例)size_t hash = hasher(element + std::to_string(i)) % m;bitArray[hash] = true;}}// 查询元素是否可能存在bool mayContain(const std::string& element) {for (int i = 0; i < k; ++i) {size_t hash = hasher(element + std::to_string(i)) % m;if (!bitArray[hash]) return false;}return true;}
};

四、应用场景

  1. 缓存穿透防护

    • 在访问数据库前,用布隆过滤器判断数据是否存在。若不存在,直接拦截请求,避免数据库压力。
  2. 海量数据去重

    • 如爬虫URL去重、垃圾邮件过滤,用极小空间快速判断元素是否已存在。
  3. 分布式系统

    • 如Hadoop、Redis等系统中,用于快速判断数据是否存在于本地,减少网络IO。
  4. 区块链

    • 比特币等系统用布隆过滤器实现轻量级客户端(SPV),验证交易是否存在于区块中。

五、优缺点

优点缺点
空间效率极高(仅需位数组)存在误判率(无法100%准确)
插入和查询时间复杂度O(k)无法删除元素(因哈希冲突)
不存储原始数据,保护隐私参数(m、k)需预先设置

六、优化变种

  1. 计数布隆过滤器(Counting Bloom Filter)

    • 将位数组改为计数器数组,支持元素删除操作。
  2. 动态布隆过滤器(Dynamic Bloom Filter)

    • 当元素数量超过预期时,自动扩展位数组大小,调整哈希函数。
  3. 压缩布隆过滤器(Compressed Bloom Filter)

    • 对位数组进行压缩,进一步节省空间(如采用游程编码)。

七、选择建议

  1. 确定参数

    • 根据预期元素数量和可接受的误判率,计算合适的位数组大小和哈希函数数量。
  2. 选择哈希函数

    • 哈希函数需相互独立且分布均匀,避免相关性导致误判率升高。
  3. 权衡误判率和空间

    • 误判率每降低一半,位数组大小需翻倍。需根据业务需求平衡空间和准确性。
http://www.xdnf.cn/news/757783.html

相关文章:

  • Ansible自动化运维工具全面指南:从安装到实战应用
  • 【Go语言生态】
  • Vue初始化脚手架
  • 数据库,Spring Boot,数据源
  • 第13讲、Odoo 18 配置文件(odoo.conf)详细解读
  • 6.1 英语复习笔记 3
  • 如何利用大语言模型生成特定格式文风的报告类文章
  • Redis分布式锁实现指南
  • 《P3959 [NOIP 2017 提高组] 宝藏》
  • 继承与多态
  • 篇章七 数据结构——栈和队列
  • 查看make命令执行后涉及的预编译宏定义的值
  • Python数学可视化——环境搭建与基础绘图
  • 力扣刷题(第四十四天)
  • 主数据编码体系全景解析:从基础到高级的编码策略全指南
  • GEE:获取研究区的DEM数据
  • RocketMQ 学习
  • 性能优化 - 案例篇:数据一致性
  • 清理 pycharm 无效解释器
  • CVE-2021-28164源码分析与漏洞复现
  • DDD架构
  • 历年西安邮电大学计算机保研上机真题
  • 鸿蒙OS基于UniApp的区块链钱包开发实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp
  • 基于Dify实现各类报告文章的智能化辅助阅读
  • 攻防 FART 脱壳:特征检测识别 + 对抗绕过全解析
  • C++输入与输出技术详解
  • hot100 -- 5.普通数组系列
  • CFTel:一种基于云雾自动化的鲁棒且可扩展的远程机器人架构
  • Domain Adaptation in Vision-Language Models (2023–2025): A Comprehensive Review
  • 2022—2025年:申博之路及硕士阶段总结