Bloom Filter的用途:
1查询一个元素是否在一个集合中
2 判重
Bloom filter是一个包含m位的位数组
filter长度: m位
元素个数: n位
hash函数个数: k个
知道元素个数即n,如何确定m和k呢?这还和要求的错误率有关。
1 首先,我们会确定允许的错误率E。当hash函数个数k=(ln2)*(m/n) = 0.693*(m/n)时错误率最小。
2 在错误率不大于E的情况下,m至少要等于n*lg(1/E)才能表示任意n个元素的集合。但m还应该更大些,因为还要保证bit数组里至少一半为0,则m应该>=nlg(1/E)*lge 大概就是nlg(1/E)1.44倍(lg表示以2为底的对数)。
3 错误率E大概等于(0.6185)^m/n
举个例子:假设错误率为0.01,则此时m应该大概是n的lg(1/0.01)*1.44=10倍。这样k大概是7.
还有个重要的问题是:如何确定hash函数呢?
哈希函数的选择对性能的影响应该是很大的,一个好的哈希函数要能近似等概率的将字符串映射到各个Bit。选择k个不同的哈希函数比较麻烦,一种简单的方法是选择一个哈希函数,然后送入k个不同的参数。
哈希函数的选择对性能的影响应该是很大的,一个好的哈希函数要能近似等概率的将字符串映射到各个Bit。选择k个不同的哈希函数比较麻烦,一种简单的方法是选择一个哈希函数,然后送入k个不同的参数。
应用实例:
1 给你A,B两个文件,各存放50亿条URL,每条URL占用64字节,内存限制是4G,让你找出A,B文件共同的URL。如果是三个乃至n个文件呢? 根据这个问题我们来计算下内存的占用,4G=2^32大概是40亿*8大概是340亿,n=50亿。这样错误率大概是0.6185^(34/50) = 0.72
2 网络爬虫遇到一个网络地址类似于“http://mach.debagua.net”这样的,如何知道以前爬过没有?--通常这个问题以这样的形式出现:硬盘上有1M个文件,每个文件里面包含着大量URL,如何检测URL重复?