- 浏览: 609969 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
kangh:
转载的也拿出来 都不试一下 完全错误
Nginx+ffmpeg的HLS开源服务器搭建配置及开发详解 -
wangtxlz:
#cd builders/cmake#cmake .系统提示命 ...
crtmpserver流媒体服务器的介绍与搭建 -
hnraysir:
支持支持支持
手机Android音视频采集与直播推送,实现单兵、移动监控类应用 -
wuent:
把web服务器和php框架绑定到一起?真不建议这样。。。
Swoole(PHP高级Web开发框架) -
wuent:
有更详细的性能比较吗?php,python,java
PHP中的(伪)多线程与多进程
在日常生活中,包括在设计计算机软件时,我们经常要判断一个元素是否在一个集合中。比如在字处理软件中,需要检查一个英语单词是否拼写正确(也就是要判断它是否在已知的字典中);在 FBI,一个嫌疑人的名字是否已经在嫌疑名单上;在网络爬虫里,一个网址是否被访问过等等。最直接的方法就是将集合中全部的元素存在计算机中,遇到一个新元素时,将它和集合中的元素直接比较即可。一般来讲,计算机中的集合是用哈希表(hash table)来存储的。它的好处是快速准确,缺点是费存储空间。当集合比较小时,这个问题不显著,但是当集合巨大时,哈希表存储效率低的问题就显现出来了。比如说,一个象 Yahoo,Hotmail 和 Gmai 那样的公众电子邮件(email)提供商,总是需要过滤来自发送垃圾邮件的人(spamer)的垃圾邮件。一个办法就是记录下那些发垃圾邮件的 email 地址。由于那些发送者不停地在注册新的地址,全世界少说也有几十亿个发垃圾邮件的地址,将他们都存起来则需要大量的网络服务器。如果用哈希表,每存储一亿个 email 地址, 就需要 1.6GB 的内存(用哈希表实现的具体办法是将每一个 email 地址对应成一个八字节的信息指纹 googlechinablog.com/2006/08/blog-post.html,然后将这些信息指纹存入哈希表,由于哈希表的存储效率一般只有 50%,因此一个 email 地址需要占用十六个字节。一亿个地址大约要 1.6GB, 即十六亿字节的内存)。因此存贮几十亿个邮件地址可能需要上百 GB 的内存。除非是超级计算机,一般服务器是无法存储的。
今天,我们介绍一种称作布隆过滤器的数学工具,它只需要哈希表 1/8 到 1/4 的大小就能解决同样的问题。
布隆过滤器是由巴顿.布隆于一九七零年提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。我们通过上面的例子来说明起工作原理。
假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8) 产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到 1 到十六亿中的八个自然数 g1, g2, ...,g8。现在我们把这八个位置的二进制全部设置为一。当我们对这一亿个 email 地址都进行这样的处理后。一个针对这些 email 地址的布隆过滤器就建成了。
现在,让我们看看如何用布隆过滤器来检测一个可疑的电子邮件地址 Y 是否在黑名单中。我们用相同的八个随机数产生器(F1, F2, ..., F8)对这个地址产生八个信息指纹 s1,s2,...,s8,然后将这八个指纹对应到布隆过滤器的八个二进制位,分别是 t1,t2,...,t8。如果 Y 在黑名单中,显然,t1,t2,..,t8 对应的八个二进制一定是一。这样在遇到任何在黑名单中的电子邮件地址,我们都能准确地发现。
布隆过滤器决不会漏掉任何一个在黑名单中的可疑地址。但是,它有一条不足之处。也就是它有极小的可能将一个不在黑名单中的电子邮件地址判定为在黑名单中,因为有可能某个好的邮件地址正巧对应个八个都被设置成一的二进制位。好在这种可能性很小。我们把它称为误识概率。在上面的例子中,误识概率在万分之一以下。
布隆过滤器的好处在于快速,省空间。但是有一定的误识别率。常见的补救办法是在建立一个小的白名单,存储那些可能别误判的邮件地址。
====================================================================
具体实现:
今天,我们介绍一种称作布隆过滤器的数学工具,它只需要哈希表 1/8 到 1/4 的大小就能解决同样的问题。
布隆过滤器是由巴顿.布隆于一九七零年提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。我们通过上面的例子来说明起工作原理。
假定我们存储一亿个电子邮件地址,我们先建立一个十六亿二进制(比特),即两亿字节的向量,然后将这十六亿个二进制全部设置为零。对于每一个电子邮件地址 X,我们用八个不同的随机数产生器(F1,F2, ...,F8) 产生八个信息指纹(f1, f2, ..., f8)。再用一个随机数产生器 G 把这八个信息指纹映射到 1 到十六亿中的八个自然数 g1, g2, ...,g8。现在我们把这八个位置的二进制全部设置为一。当我们对这一亿个 email 地址都进行这样的处理后。一个针对这些 email 地址的布隆过滤器就建成了。
现在,让我们看看如何用布隆过滤器来检测一个可疑的电子邮件地址 Y 是否在黑名单中。我们用相同的八个随机数产生器(F1, F2, ..., F8)对这个地址产生八个信息指纹 s1,s2,...,s8,然后将这八个指纹对应到布隆过滤器的八个二进制位,分别是 t1,t2,...,t8。如果 Y 在黑名单中,显然,t1,t2,..,t8 对应的八个二进制一定是一。这样在遇到任何在黑名单中的电子邮件地址,我们都能准确地发现。
布隆过滤器决不会漏掉任何一个在黑名单中的可疑地址。但是,它有一条不足之处。也就是它有极小的可能将一个不在黑名单中的电子邮件地址判定为在黑名单中,因为有可能某个好的邮件地址正巧对应个八个都被设置成一的二进制位。好在这种可能性很小。我们把它称为误识概率。在上面的例子中,误识概率在万分之一以下。
布隆过滤器的好处在于快速,省空间。但是有一定的误识别率。常见的补救办法是在建立一个小的白名单,存储那些可能别误判的邮件地址。
====================================================================
具体实现:
import java.util.BitSet; public class bloomFilter implements java.io.Serializable { private int defaultSize = 5000 << 10000; private int basic = defaultSize -1; private String key = null; private BitSet bits = new BitSet(defaultSize); public bloomFilter(){ } public bloomFilter(String key){ this.key = key; } private int[] lrandom(String key){ int[] randomsum = new int[8]; int random1 = hashCode(key,1); int random2 = hashCode(key,2); int random3 = hashCode(key,3); int random4 = hashCode(key,4); int random5 = hashCode(key,5); int random6 = hashCode(key,6); int random7 = hashCode(key,7); int random8 = hashCode(key,8); randomsum[0] = random1; randomsum[1] = random2; randomsum[2] = random3; randomsum[3] = random4; randomsum[4] = random5; randomsum[5] = random6; randomsum[6] = random7; randomsum[7] = random8; return randomsum; } private int[] sameLrandom(String key){ int[] randomsum = new int[8]; int random1 = hashCode(key,1); int random2 = hashCode(key,1); int random3 = hashCode(key,1); int random4 = hashCode(key,1); int random5 = hashCode(key,1); int random6 = hashCode(key,1); int random7 = hashCode(key,1); int random8 = hashCode(key,1); randomsum[0] = random1; randomsum[1] = random2; randomsum[2] = random3; randomsum[3] = random4; randomsum[4] = random5; randomsum[5] = random6; randomsum[6] = random7; randomsum[7] = random8; return randomsum; } public void add(String key){ if(exist(key)){ System.out.println("已经包含("+key+")"); return; } int keyCode[] = lrandom(key); getBits().set(keyCode[0]); getBits().set(keyCode[1]); getBits().set(keyCode[2]); getBits().set(keyCode[3]); getBits().set(keyCode[4]); getBits().set(keyCode[5]); getBits().set(keyCode[6]); getBits().set(keyCode[7]); } public boolean exist(String key){ int keyCode[] = lrandom(key); if(getBits().get(keyCode[0])&& getBits().get(keyCode[1]) &&getBits().get(keyCode[2]) &&getBits().get(keyCode[3]) &&getBits().get(keyCode[4]) &&getBits().get(keyCode[5]) &&getBits().get(keyCode[6]) &&getBits().get(keyCode[7])){ return true; } return false; } private boolean set0(String key){ if(exist(key)){ int keyCode[] = lrandom(key); getBits().clear(keyCode[0]); getBits().clear(keyCode[1]); getBits().clear(keyCode[2]); getBits().clear(keyCode[3]); getBits().clear(keyCode[4]); getBits().clear(keyCode[5]); getBits().clear(keyCode[6]); getBits().clear(keyCode[7]); return true; } return false; } public int hashCode(String key,int Q){ int h = 0; int off = 0; char val[] = key.toCharArray(); int len = key.length(); for (int i = 0; i < len; i++) { h = (30 + Q) * h + val[off++]; } return changeInteger(h); } private int changeInteger(int h) { return basic & h; } //碰撞测试 public static void main(String[] args) { // TODO Auto-generated method stub bloomFilter f = new bloomFilter(); int err=0; for(int i=1;i<2100000000;i++) { if(f.exist(String.valueOf(i))) { err++; }else { f.add(String.valueOf(i)); } System.out.println("Error "+i+" :"+err/i*100+"%"); } f.add(String.valueOf(23482734)); //f.add("http://www.agrilink.cn/"); //System.out.println(f.exist("http://www.agrilink.cn/")); //f.set0("http://www.agrilink.cn/"); //System.out.println(f.exist("http://www.agrilink.cn/")); } /** * @return the bits */ public BitSet getBits() { return bits; } /** * @param bits the bits to set */ public void setBits(BitSet bits) { this.bits = bits; } }
发表评论
-
hash算法 (hashmap 实现原理)
2015-06-12 11:33 0Hash ,一般翻译做“ 散列” ,也有直接音译为 ... -
数据挖掘十大经典算法
2015-05-15 14:27 1160国际权威的学术组织the IEEE Internationa ... -
京东个性化推荐系统持续优化的奥秘
2015-04-20 11:03 0京东基于大数据和个性化推荐算法,实现了向不同用户展示不同的内 ... -
php 经典的算法题你懂的
2015-03-31 12:31 0有5个人偷了一堆苹果,准备在第二天分赃。晚上,有一人遛出来, ... -
并发队列ConcurrentLinkedQueue和阻塞队列LinkedBlockingQueue用法
2015-03-17 11:01 1154在Java多线程应用中,队列的使用率很高,多数生产消费模型的 ... -
RabbitMQ (五)主题(Topic)
2015-02-27 17:05 0转载请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (四) 路由选择 (Routing)
2015-02-27 17:04 0上一篇博客我们建立了一个简单的日志系统,我们能够广播日志消 ... -
RabbitMQ (三) 发布/订阅
2015-02-27 17:02 1248转发请标明出处:http://blog.csdn.net/l ... -
RabbitMQ (二)工作队列
2015-02-27 17:01 1294转载请标明出处:http:/ ... -
RabbitMQ 入门 Helloworld
2015-02-27 17:00 1190转载请标明出处:http://blog.csdn.net/l ... -
PHP实现常见查找和排序算法
2015-01-09 15:40 0下面分享一些最常见的算法,用PHP如何实现。 1、冒泡排序 ... -
B树、B-树、B+树、B*树
2015-01-09 15:10 703B树 即二叉搜索树: 1.所 ... -
TF-IDF与余弦相似性的应用(三):自动摘要
2014-05-25 23:24 0有时候,很简单的数学方法,就可以完成很复杂的任务。 这个 ... -
TF-IDF与余弦相似性的应用(二):找出相似文章
2014-05-25 23:23 751上一次,我用TF-IDF算法自动提取关键词。 今天,我们再 ... -
TF-IDF与余弦相似性的应用(一):自动提取关键词
2014-05-25 23:22 764这个标题看上去好像很复杂,其实我要谈的是一个很简单的问题。 ... -
生成文本聚类java实现 (3)
2014-05-25 22:25 771很多网友看到我的聚类的研究,到后来基本上都是到car ... -
生成文本聚类java实现 (2)
2014-05-25 22:23 1417Java代码 4.从剩余的词中提取文本 ... -
生成文本聚类java实现 (1)
2014-05-25 22:23 1110本章主要的学习是中文分词 和两种统计词频(传统词频和T ... -
贝叶斯推断及其互联网应用(二):过滤垃圾邮件[转]
2013-09-11 15:42 875上一次,我介绍了贝叶斯推断的原理,今天讲如何将它用于垃 ... -
基于用户投票的排名算法(一):Delicious和Hacker News[转]
2013-09-11 15:30 791互联网的出现,意味着 ...
相关推荐
C# 版本的布隆过滤器实现了这一概念,通过使用八种不同的哈希函数来提高准确性和减少冲突。 布隆过滤器的基本原理是将所有可能存在的元素映射到一个固定大小的位数组(bit array)上。这个位数组最初全部设置为0。...
例如,`bf_create(size_t capacity, uint8_t num_hashes)`用于创建一个布隆过滤器,`bf_insert(bloom_filter* filter, const void* item)`用于插入元素,`bf_query(bloom_filter* filter, const void* item)`用于...
`bloomfilter.js`可能是JavaScript版本的布隆过滤器实现,而"Go-布隆过滤器的一个Go实现参考bloomfilter.js"则表明该Go版本的实现是借鉴了JavaScript版本的设计思路或代码结构。 Go实现布隆过滤器的关键组件包括: ...
在Java中,实现布隆过滤器可以使用开源库如Guava或者自定义实现。例如,`BloomFilter.java`和`MyBloomFilter.java`可能是两个不同的实现版本。自定义实现通常包括以下几个关键部分: 1. **位数组(Bit Array)**:...
在提供的压缩包文件`Bloom Filter`中,可能包含了具体的Java实现代码,你可以通过阅读和分析这些代码来深入理解布隆过滤器的工作原理和Java实现细节。此外,还可以通过测试不同参数组合下的性能,进一步了解布隆过滤...
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在Java开发中,特别是在处理大数据、内存限制或需要快速查询是否存在某个元素的场景下,布隆过滤器是一个...
C++实现的布隆过滤器,其中使用到的bitset也是自己简单实现的一个BitContainer。可以处理千万条到亿条记录的存在性判断。做成dll可以在很多场合使用,如自己写爬虫,要判断一个url是否已经访问过,判断一个单词是否...
布隆过滤器(Bloom Filter)是一种空间效率极高...通过这个“bloom filter布隆过滤器学习资料大全”,你可以深入研究布隆过滤器的理论、算法实现以及在不同场景下的应用实例,提升对这一重要数据结构的理解和应用能力。
Redisson是一个Java客户端,它不仅支持Redis的各种功能,还包含了布隆过滤器的实现。通过使用Redisson,用户可以在分布式环境中利用布隆过滤器,提高系统的可扩展性和效率。 总的来说,布隆过滤器是一种在空间效率...
- `Intersection(other *BloomFilter)`: 计算两个布隆过滤器的交集,创建一个新的布隆过滤器,只保留同时存在于两个过滤器中的元素的位。 4. **优化策略**: - **位数组大小**:位数组的大小直接影响误判率,需要...
* 邮件过滤,使用布隆过滤器实现邮件黑名单过滤 * 爬虫爬过的网站过滤,爬过的网站不再爬取 * 推荐过的新闻不再推荐 * 去重问题,例如在明日头条APP中,推荐给用户的内容不会重复 Redis集成布隆过滤器需要使用Redis...
布隆过滤器,大家学过数据结构的应该都清楚,一般的字典树要实现嵌入和查找都内存的消耗非常大,布隆过滤器有BloomFilter,string, BKDRHash, APHash, DJBHash> bf五个参数你要查找的元素个数,查找元素类型,三个...
这个压缩包文件"Bloom_filter_(C).zip"包含了一个C++版本的布隆过滤器实现,它具有简单易学、易用的特点。 布隆过滤器的基本原理是通过多个哈希函数将元素映射到一个固定大小的位数组中。这些哈希函数是独立且随机...
下面将详细介绍布隆过滤器的原理、实现及测试用例。 ### 布隆过滤器原理 1. **基本结构**:布隆过滤器是一个很长的二进制数组和几个独立的哈希函数。数组初始全为0,哈希函数是随机且独立的。 2. **插入操作**:...
在Python中,有多个库实现了布隆过滤器,其中一个就是我们这里提到的"python-bloomfilter-master"。 这个Python库提供了对布隆过滤器的简单接口,使得开发者可以方便地在项目中应用布隆过滤器。安装过程非常直观,...
布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。它可能会误判,但不会漏判,即可能存在假阳性(False Positive),但绝不会有假阴性(False Negative)。...
在PHP和Redis中实现布隆过滤器,可以利用PHP的扩展库,如BloomFilter库,或者直接在Redis中使用BF.ADD、BF.MEMBERS和BF.EXISTS等命令操作布隆过滤器。Redis的布隆过滤器模块提供了方便的操作接口,能够在分布式环境...
**布隆过滤器(Bloom Filter)**是一种空间效率极高的概率型数据结构,用于测试一个元素是否在一个集合中。由Burton Howard Bloom在1970年提出,主要用于节省存储空间,尤其在大数据场景下,它能有效地解决大规模...
Cuckoo 过滤器是近似集合成员查询的布隆过滤器替代品。虽然 Bloom 过滤器是众所周知的节省空间的数据结构,可以服务于“如果项目 x 在一个集合中?”之类的查询,但它们不支持删除。它们启用删除的差异(如计算 ...