广告
返回顶部
首页 > 资讯 > 后端开发 > Python >PythonCountingBloomFilter原理与实现详细介绍
  • 571
分享到

PythonCountingBloomFilter原理与实现详细介绍

2024-04-02 19:04:59 571人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录前言原理一、BF 为什么不支持删除二、什么是 Counting Bloom Filter三、Counter 大小的选择简单的实现总结前言 标准的 Bloom Filter 是一种

前言

标准的 Bloom Filter 是一种比较简单的数据结构,只支持插入和查找两种操作。在所要表达的集合是静态集合的时候,标准 Bloom Filter 可以很好地工作,但是如果要表达的集合经常变动,标准Bloom Filter的弊端就显现出来了,因为它不支持删除操作。这就引出来了本文要谈的 Counting Bloom Filter,后文简写为 CBF。

原理

一、BF 为什么不支持删除

BF 为什么不能删除元素?我们可以举一个例子来说明。

比如要删除集合中的成员 dantezhao,那么就会先用 k 个哈希函数对其计算,因为 dantezhao 已经是集合成员,那么在位数组的对应位置一定是 1,我们如要要删除这个成员 dantezhao,就需要把计算出来的所有位置上的 1 置为 0,即将 5 和 16 两位置为 0 即可。

问题来了!现在,先假设 yyj 本身是属于集合的元素,如果需要查询 yyj 是否在集合中,通过哈希函数计算后,我们会去判断第 16 和 第 26 位是否为 1, 这时候就得到了第 16 位为 0 的结果,即 yyj 不属于集合。 显然这里是误判的。

二、什么是 Counting Bloom Filter

Counting Bloom Filter 的出现,解决了上述问题,它将标准 Bloom Filter 位数组的每一位扩展为一个小的计数器(Counter),在插入元素时给对应的 k (k 为哈希函数个数)个 Counter 的值分别加 1,删除元素时给对应的 k 个 Counter 的值分别减 1。Counting Bloom Filter 通过多占用几倍的存储空间的代价, 给 Bloom Filter 增加了删除操作。基本原理是不是很简单?看下图就能明白它和 Bloom Filter 的区别在哪。

三、Counter 大小的选择

CBF 和 BF 的一个主要的不同就是 CBF 用一个 Counter 取代了 BF 中的一位,那么 Counter 到底取多大才比较合适呢?这里就要考虑到空间利用率的问题了,从使用的角度来看,当然是越大越好,因为 Counter 越大就能表示越多的信息。但是越大的 Counter 就意味着更多的资源占用,而且在很多时候会造成极大的空间浪费。

因此,我们在选择 Counter 的时候,可以看 Counter 取值的范围多小就可以满足需求。

根据论文中描述,某一个 Counter 的值大于或等于 i 的概率可以通过如下公式描述,其中 n 为集合的大小,m 为 Counter 的数量,k 为 哈希函数的个数。

在之前的文章《Bloom Filter 的数学背景》中已经得出,k 的最佳取值为 k = m/n * ln2,将其带入公式后可得。

如果每个 Counter 分配 4 位,那么当 Counter 的值达到 16 时就会溢出。这个概率如下,这个值足够小,因此对于大多数应用程序来说,4位就足够了。

关于 CBF 中 Counter 大小的选择,主要参考这篇论文:《Summary Cache: A Scalable Wide-Area WEB Cache Sharing Protocol》,在论文的第 6、7 两页专门对其做了一番阐述。这里不再推导细节,只给出一个大概的说明,感兴趣的童鞋可以参考原论文。

简单的实现

还是实现一个简单的程序来熟悉 CBF 的原理,这里和 BF 的区别有两个:

  • 一个是我们没有用 bitarray 提供的位数组,而是使用了 bytearray 提供的一个 byte数组,因此每一个 Counter 的取值范围在 0~255。
  • 另一个是多了一个 remove 方法来删除集合中的元素。

代码很简单,只是为了理解概念,实际中使用的库会有很大差别。

import mmh3
class CountingBloomFilter:
    def __init__(self, size, hash_num):
        self.size = size
        self.hash_num = hash_num
        self.byte_array = bytearray(size)
    def add(self, s):
        for seed in range(self.hash_num):
            result = mmh3.hash(s, seed) % self.size
            if self.bit_array[result] < 256:
                self.bit_array[result] += 1
    def lookup(self, s):
        for seed in range(self.hash_num):
            result = mmh3.hash(s, seed) % self.size
            if self.bit_array[result] == 0:
                return "Nope"
        return "Probably"
    def remove(self, s):
        for seed in range(self.hash_num):
            result = mmh3.hash(s, seed) % self.size
            if self.bit_array[result] > 0:
                self.bit_array[result] -= 1
cbf = CountingBloomFilter(500000, 7)
cbf.add("dantezhao")
cbf.add("yyj")
cbf.remove("dantezhao")
print (cbf.lookup("dantezhao"))
print (cbf.lookup("yyj"))

总结

CBF 虽说解决了 BF 的不能删除元素的问题,但是自身仍有不少的缺陷有待完善,比如 Counter 的引入就会带来很大的资源浪费,CBF 的 FP 还有很大可以降低的空间, 因此在实际的使用场景中会有很多 CBF 的升级版。

比如 SBF(Spectral Bloom Filter)在 CBF 的基础上提出了元素出现频率查询的概念,将CBF的应用扩展到了 multi-set 的领域;dlCBF(d-Left Counting Bloom Filter)利用 d-left hashing 的方法存储 fingerprint,解决哈希表的负载平衡问题;ACBF(Accurate Counting Bloom Filter)通过 offset indexing 的方式将 Counter 数组划分成多个层级,来降低误判率。这些内容,有机会再分享。

到此这篇关于python Counting Bloom Filter原理与实现详细介绍的文章就介绍到这了,更多相关Python Counting Bloom Filter内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: PythonCountingBloomFilter原理与实现详细介绍

本文链接: https://www.lsjlt.com/news/120714.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • PythonCountingBloomFilter原理与实现详细介绍
    目录前言原理一、BF 为什么不支持删除二、什么是 Counting Bloom Filter三、Counter 大小的选择简单的实现总结前言 标准的 Bloom Filter 是一种...
    99+
    2022-11-11
  • Node.js模块化原理与应用详细介绍
    目录什么是模块化模块化规范node.js中的模块分类加载模块node.js的模块作用域什么是模块作用域模块作用域的好处向外共享模块作用域中的成员module对象module.expo...
    99+
    2022-11-13
  • Android组件化原理详细介绍
    目录什么是组件化?为什么使用组件化?一步步搭建组件化1.新建模块2.统一Gradle版本号3.创建基础库4.组件模式和集成模式转换5.AndroidManifest的切换6.*业务A...
    99+
    2022-11-13
  • 详细介绍PHP接口的定义与实现
    随着Web应用程序的不断发展,越来越多的开发者在接触PHP开发语言,特别是在web开发领域中使用PHP来实现API接口。接口是面向对象编程中一种非常重要的概念,其主要作用是为各种不同的实现提供一个规范的接口。在PHP语言中,接口的定义非常容...
    99+
    2023-05-14
    php 接口
  • 非常详细的 Ceph 介绍、原理、架构
    非常详细的 Ceph 介绍、原理、架构 1. Ceph架构简介及使用场景介绍 1.1 Ceph简介 Ceph是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。 Ceph项目最早起源于Sage就读博士期间的工作(最...
    99+
    2023-09-05
    ceph
  • golang RPC包原理和使用详细介绍
    目录工作流程工作模式http模式服务器模式本篇文章旨在通过学习rpc包和github上的一个rpc小项目,熟悉和学习golang中各个包的使用 工作流程 通过阅读官方文档,了解了rp...
    99+
    2022-11-11
  • JavaScript原始值与包装对象的详细介绍
    目录前言正文原始类型 (Primitive types)原始值 (Primitive values)包装对象 (Wrapper objects)对象 (Object)构造函数 (Co...
    99+
    2022-11-12
  • OAuth2.0详细介绍与实践(通俗易懂)
    一、OAuth2.0介绍 1.1 概述 OAUTH协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是OAUTH的授权不会使第三方触及到用户的帐号信息(如用户名与密码)...
    99+
    2023-09-16
    java
  • C++函数重载介绍与原理详解
    目录函数重载函数重载的概念函数重载的原理(名字修饰)总结:extern “C”函数重载 函数重载的概念 函数重载是函数的一种特殊情况,C++允许在同一作用域中...
    99+
    2022-11-12
  • 详细介绍Golang编译的过程及其原理
    Golang是一种新的编程语言,十分快速的发展,得到越来越多开发者的关注和使用。Golang除了拥有诸如并发编程、垃圾回收、强类型等自身特性外,还具有编译速度快、能生成单独静态链接的可执行文件等优势。但是,Golang的编译过程却不简单。在...
    99+
    2023-05-14
  • React使用Context与router实现权限路由详细介绍
    目录前言思路实现向根组件注入权限列表抽离ContextHOC实现权限路由组件实现实现使用方法实现类似react-router-config的集中式权限路由配置实现使用方法前言 之前使...
    99+
    2023-01-28
    React权限路由 React Context权限路由 React router权限路由
  • Kotlin类的继承实现详细介绍
    1.在kotlin中,默认类都是封闭的closed的。如果要让某个类开放继承,必须用open关键字修饰 类中的方法默认也是关闭的。如果需要子类复写父类的方法,也必须用open修饰。 ...
    99+
    2022-11-13
  • Spring的Ioc模拟实现详细介绍
    简单来说就是当自己需要一个对象的时候不需要自己手动去new一个,而是由其他容器来帮你提供;Spring里面就是IOC容器。例如:在Spring里面经常需要在Service这个装配一个Dao,一般是使用@Autowired注解:类似如下pub...
    99+
    2023-05-30
    spring ioc sprin
  • Android增量升级的方法和原理详细介绍
    总结:我们使用delta编码算法减少Android应用升级程序的大小。我们通过bsdiff和bspatch工具在android上实现delta编码算法。服务器软件和androi...
    99+
    2022-06-06
    方法 Android
  • TiDB-Wasm 原理与实现 | Hackathon 优秀项目介绍
    作者:Ti-Cool 上周我们推送了《让数据库运行在浏览器里?TiDB + WebAssembly 告诉你答案》,向大家展示了 TiDB-Wasm 的魅力:TiDB-Wasm 项目是 TiDB Hackathon 2019 中诞生的二等奖...
    99+
    2019-08-25
    TiDB-Wasm 原理与实现 | Hackathon 优秀项目介绍
  • PostgreSQL游标与索引选择实例详细介绍
    之前有写过一个案例,order by limit因为数据分布不均而选择了错误的索引,这是由于优化器没法判断数据的分布关系,默认认为数据分布是均匀的所导致的。 而除了limit,当我们在使用游标时也要注意有可能会出现类似的...
    99+
    2022-09-15
  • Docker exec 的实现原理介绍
    我使用了 docker exec 命令进入到了容器当中。在了解了Linux Namespace 的隔离机制后,你应该会很自然地想到一个问题:docker exec 是怎么做到进入容器...
    99+
    2022-11-13
  • 详解pytest实现mark标记功能详细介绍
    mark标记 ​在实际工作中,我们要写的自动化用例会比较多,也不会都放在一个py文件中,如果有几十个py文件,上百个方法,而我们只想运行当中部分的用例时怎么办? R...
    99+
    2022-11-12
  • Vue指令的实现原理介绍
    这篇文章主要介绍“Vue指令的实现原理介绍”,在日常操作中,相信很多人在Vue指令的实现原理介绍问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue指令的实现原理介绍”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-20
  • SpringBootJWT接口验证实现流程详细介绍
    目录添加pom.xml修改配置文件创建简单的测试接口使用拦截器实现需求:只有用户登录成功后,才能访问其它接口,否则提示需要进行登录 项目仓库地址:https://gitee.com/...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作