处理大数据运算的利器 — 布隆过滤器原理以及设计
来源:互联网 发布:meta分析数据库 编辑:程序博客网 时间:2024/06/05 14:18
布隆过滤器
说到布隆过滤器千万别想到英雄联盟里面的布隆大叔. 我们今天认识的布隆过滤器是一个处理大数据问题的利器. 它可以进行粗略估计一个数据是否存
在在该集合当中.如果想判断一个元素是不是在一个集合当中,一般想到的是将所有元素保存起来,然后通过比较确定. 链表,树等等结构都是这种思
路.但是随着集合中元素的增多,我们需要的存储空间越来越大.检索的速度也越来越慢. 效果不错的就是我们的哈希表,当然我们的布隆过滤器其实也
是使用了我们的hash映射思想. 我们可以通过一个Hash函数将一个元素映射到一个位图当中,如果这个点被置为1,那么集合当中就是有她的.反之则没
有.这就是布隆过滤器的基本思想.
但是我们都知道的哈希表是有哈希冲突的. 况且你是使用位处理的那么也就不存在Hash开链法这种优化方式了. 那么当你好几个数据同时映射到一个位
怎么办?? 那你就映射呗 我对于映射真的没有办法改变? 但是布隆过滤器不会坐以待毙,如果这样我可不可以使用好几个Hash算法,然后让你映射不
同的位置当你过来检验的时候,必须这几个位都被置为1,那样你才能认定这个数字是存在的. 当然这里都是有数学建模的基础的,然而我又不是很理
解... 我就找到网上的一个图过来瞧瞧~
下图是布隆过滤器假正列概率p与位数大小m和集合中插入数据个数n的关系图. 假定Hash函数个数选取最优数目:K = (M/N)In
我们也看到了布隆过滤器是有缺陷的,他不够准确当数值足够大的时候误判率就会越来越大. 所以布隆过滤器只能够作为一个粗略的判断.我们目前为
止已经大概的了解到它的基本原理. 我们可以发现布隆过滤器的判断存在是不准确的. 但是它判断不存在一定是准确的.好了我们来缕一下布隆过滤器
的优缺点.
优点:相比于其他的数据结构,布隆过滤器在空间和时间方面都有巨大的优势.布隆过滤器存储空间和插入/查询时间都是常数.另外,Hash函数相互之间
没有关系,方便由硬件并行实现. 布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势. 布隆过滤器可以表示所有类型的数据,
其他任何数据结构都不能.
缺点: 首先误判率是一定要提出来的,如果存入的元素数量增加,误判率就会增加. 但是如果元素数量过少,那还不如使用Hash表呢 对吧.
还有,布隆过滤器当中不能随便删除元素. 因为同一个位有可能有好几个数据标记了它, 如果涉及一个引用计数却又太复杂啦.
现在我们理解清楚布隆过滤器的原理,那么我们尝试实现一个最简单的布隆过滤器试一试!
代码实现:
#include"BitMap.h"#include<string>template<class K>struct __HashFunc1{static size_t BKDRHash(const char * str){unsigned int seed = 131; // 31 131 1313 13131 131313unsigned int hash = 0;while (*str){hash = hash * seed + (*str++);}return (hash & 0x7FFFFFFF);}size_t operator()(const K& key){return BKDRHash(key.c_str());}};template<class K>struct __HashFunc2{size_t SDBMHash(const char *str){register size_t hash = 0;while (size_t ch = (size_t)*str++){hash = 65599 * hash + ch;//hash = (size_t)ch + (hash << 6) + (hash << 16) - hash; }return hash;}size_t operator()(const K& key){return SDBMHash(key.c_str());}};template<class K>struct __HashFunc3{size_t APHash(const char *str){register size_t hash = 0;size_t ch;for (long i = 0; ch = (size_t)*str++; i++){if ((i & 1) == 0){hash ^= ((hash << 7) ^ ch ^ (hash >> 3));}else{hash ^= (~((hash << 11) ^ ch ^ (hash >> 5)));}}return hash;}size_t operator()(const K& key){return APHash(key.c_str());}};template<class K = string, class HashFunc1 = __HashFunc1<K>, class HashFunc2 = __HashFunc2<K>, class HashFunc3 = __HashFunc3<K>>class BloomFilter{public:BloomFilter(size_t num):_bm(num * 5), _bitSize(num * 5){}void Set(const K& key){size_t index1 = HashFunc1()(key);_bm.SetBit(index1);size_t index2 = HashFunc2()(key);_bm.SetBit(index2);size_t index3 = HashFunc3()(key);_bm.SetBit(index3);}bool Test(const K& key){size_t index1 = HashFunc1()(key);if (_bm.TestBit(index1) == false){return false;}size_t index2 = HashFunc2()(key);if (_bm.TestBit(index2) == false){return false;}size_t index3 = HashFunc3()(key);if (_bm.TestBit(index3) == false){return false;}//所有位置都为真. 但是它是不准确的.return true;}private:BitMap _bm;size_t _bitSize;};void Test(){BloomFilter<> T(4000000000);T.Set("12312312411231215151251251252151251");T.Set("12312312411231215151251251252151252");T.Set("12312312411231215151251251252151253");T.Set("12312312411231215151251251252151254");T.Set("12312312411231215151251251252151255");T.Set("12312312411231215151251251252151256");T.Set("12312312411231215151251251252151257");cout << T.Test("12312312411231215151251251252151251") << endl;cout << T.Test("12312312411231215151251251252151252") << endl;cout << T.Test("12312312411231215151251251252151253") << endl;cout << T.Test("12312312411231215151251251252151254") << endl;cout << T.Test("12312312411231215151251251252151255") << endl;cout << T.Test("12312312411231215151251251252151256") << endl;cout << T.Test("12312312411231215151251251252151257") << endl;system("pause");}
用到的位图的代码在我的另外一个博客当中: 位图的原理以及设计
阅读全文
1 1
- 处理大数据运算的利器 — 布隆过滤器原理以及设计
- 处理大数据运算的利器 — 位图原理以及设计
- 从另一个角度看大数据量处理利器:布隆过滤器
- 从另一个角度看大数据量处理利器:布隆过滤器
- [算法系列之十]大数据量处理利器:布隆过滤器
- 从另一个角度看大数据量处理利器:布隆过滤器
- bloom filter(布隆过滤器)的算法设计与原理以及一些用例场景
- 大数据处理利器——Bloom Filter(布隆过滤器)要点分析
- 大数据处理--布隆过滤器的原理与实现
- bloom filter -- 处理大数据集的利器
- Ambari——大数据平台的搭建利器(Ambari 的架构和工作原理)
- Ambari——大数据平台的搭建利器
- Ambari——大数据平台的搭建利器
- Ambari——大数据平台的搭建利器
- Ambari——大数据平台的搭建利器
- 大数据的运算
- 海量数据处理利器之布隆过滤器
- 布隆过滤器--海量数据处理利器
- 安卓插件化中activity的生命周期管理及hook机制
- POJ 1251 Jungle Roads
- Linux PXE Under UEFI Mode
- 图片适配器
- Java homework7
- 处理大数据运算的利器 — 布隆过滤器原理以及设计
- C 语言连接数据库
- 杭电ACM OJ 1018 Big Number 两数相乘出一个大数,求大数的位数 注意log的使用
- 数字广告营销中的DSP、SSP、RTB是个什么概念
- python selenium模块学习
- mysql分页获取到重复数据
- 【十八掌●内功篇】第六掌:YARN之架构和原理
- 使用 C 语言打开浏览器
- 数据挖掘模型中的IV和WOE详解