`
rcyl2003
  • 浏览: 237384 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

大数据量的过滤 (用于爬虫,蜘蛛) Bloom Filter 布隆过滤器

阅读更多

原文:Bloom Filters in C#
http://www.devsource.com/article2/0,1895,2113495,00.asp


想像一下.如果你有一个非常大的无序的数据(url连接) 并且你要保证同样的一条连接不会在其它地方再次出现
你实时的收集哪些数据,你没有办法来预防两个相同的url出现,再不断增加的数据当中.

当这些数据是少的时候你可以轻松的创建一个list(dictonary or hashtable 或者你自已的数据结构)然后遍历它们,看它是不是已经存在在这个list当中,
遍历所花的时间是非常多的,
但是 当这些数据的长度超过可用的内存的时候? hashtable可以帮我加快速度,但是存...

上面的比较多的费话..看起来累 呦口继续不下去了.

得出的方案是用 bit数组来节省空间
a hash table capable of holding M items will take m/8 bytes of memory
接下来是实际的解决方法
net 里面有一个类 BitArray它可以帮我们很容易的创建出一个hashtabel

创建一个简单的 HashingTable

public class SimpleHashTable
    
{
        
private BitArray hashbits = null;

        
public SimpleHashTable(int tableSize)
        
{
            hashbits 
= new BitArray(tableSize, false);
        }


        
public bool Test(string str)
        
{
            
int hash = Math.Abs(str.GetHashCode()) % hashbits.Count;
            
return hashbits[hash];
        }


        
public bool Add(string str)
        
{
            
int hash = Math.Abs(str.GetHashCode()) % hashbits.Count;
            
bool rslt = hashbits[hash];
            
if (!rslt)
                hashbits[hash] 
= true;
            
return rslt;
        }

    }


Add 里面没有这个值的时候是返回 false ,
Test 里面有值的话是返回 true;

 class Program
    
{
        
static void Main(string[] args)
        
{
            
int urlsRead = 0;
            
int collisions = 0;

            SimpleHashTable hashTable 
= new SimpleHashTable(1000000);
            
using (StreamReader sr = new StreamReader("urls.txt"))
            
{
                
string url;
                
while ((url = sr.ReadLine()) != null)
                
{
                    urlsRead
++;
                    
bool rslt = hashTable.Add(url);
                    
if (rslt)
                        collisions
++;
                    
if ((urlsRead % 10000== 0)
                    
{
                        Console.WriteLine(
"{0}  {1}  {2}%"
                            urlsRead, collisions, 
100*
                                (
double)collisions / urlsRead);
                    }

                }

            }

            Console.WriteLine(
"{0} urls read", urlsRead);
            Console.WriteLine(
"{0} collisions", collisions);
            Console.WriteLine(
"False positive rate = {0}%"
                
100*(double)collisions / urlsRead);
        }

    }

The output from that program, run against the 100,000 unique URLs in my file, is:

10000  44  0.44%
20000  187  0.935%
30000  423  1.41%
40000  753  1.8825%
50000  1200  2.4%
60000  1753  2.92166666666667%
70000  2375  3.39285714285714%
80000  3123  3.90375%
90000  3946  4.38444444444444%
100000  4834  4.834%
100000 urls read
4834 collisions
False positive rate = 4.834%
然后写了一个简单的测试类,我们可以看到它的碰撞(冲突)还是比较明显的

接下来就是如何继续去解决这样的问题
创建一个新的 Hash算法函数 HashString
hi(x) = (f1(x) + if2(x)) mod m

然后提供了一个 防止碰撞的结构. hashkeys 保存这个hash的三个位置

 public class BloomFilter
    
{
        
private BitArray hashbits;
        
private int numKeys;
        
private int[] hashKeys;

        
public BloomFilter(int tableSize, int nKeys)
        
{
            numKeys 
= nKeys;
            hashKeys 
= new int[numKeys];
            hashbits 
= new BitArray(tableSize);
        }


        
private int HashString(string s)
        
{
            
int hash = 0;

            
for (int i = 0; i < s.Length; i++)
            
{
                hash 
+= s[i];
                hash 
+= (hash << 10);
                hash 
^= (hash >> 6);
            }

            hash 
+= (hash << 3);
            hash 
^= (hash >> 11);
            hash 
+= (hash << 15);
            
return hash;
        }


        
private void CreateHashes(string str)
        
{
            
int hash1 = str.GetHashCode();
            
int hash2 = HashString(str);

            hashKeys[
0= Math.Abs(hash1 % hashbits.Count);
            
if (numKeys > 1)
            
{
                
for (int i = 1; i < numKeys; i++)
                
{
                    hashKeys[i] 
= Math.Abs((hash1 + (i * hash2))
                        
% hashbits.Count);
                }

            }

        }


        
public bool Test(string str)
        
{
            CreateHashes(str);
            
// Test each hash key.  Return false if any 
            
//  one of the bits is not set.
            foreach (int hash in hashKeys)
            
{
                
if (!hashbits[hash])
                    
return false;
            }

            
// All bits set.  The item is there.
            return true;
        }


        
public bool Add(string str)
        
{
            
// Initially assume that the item is in the table
            bool rslt = true;
            CreateHashes(str);
            
foreach (int hash in hashKeys)
            
{
                
if (!hashbits[hash])
                
{
                    
// One of the bits wasn't set, so show that
                    
// the item wasn't in the table, and set that bit.
                    rslt = false;
                    hashbits[hash] 
= true;
                }

            }

            
return rslt;
        }

    }

测试:

分享到:
评论

相关推荐

    bloom filter(C#版自制布隆过滤器)

    布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。它是由 Burton Howard Bloom 在1970年提出的,主要应用于大数据存储和检索,尤其在数据库、缓存系统和网络搜索等领域有广泛...

    bloom filter布隆过滤器学习资料大全

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在大数据处理、缓存系统、分布式存储等领域有着广泛的应用。这个压缩包文件“bloom filter布隆过滤器学习...

    硬核 - Redis 布隆(Bloom Filter)过滤器原理与实战.doc

    Redis 布隆(Bloom Filter)过滤器是一种space efficient的概率型数据结构,用于判断一个元素是否在集合中。布隆过滤器的原理是,首先分配一块内存空间做bit数组,数组的bit位初始值全部设为0。加入元素时,采用k个...

    【技术分享】Bloomfilter布隆过滤器.pptx

    布隆过滤器是一种高效的空间节省的数据结构,用于判断一个元素是否可能在一个集合中,但可能会产生一定的误判率。它由一个很长的二进制向量和多个独立的哈希函数组成。布隆过滤器的基本原理是,当一个元素被添加到...

    布隆过滤器-BloomFilter

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。由布隆在1970年提出,它不像传统的数据结构如哈希表那样保证不误判,而是允许有一定的错误率。这种特性使得...

    布隆过滤器C源码-bloomfilter.rar

    例如,`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)`用于...

    布隆过滤器BloomFilters的一个简单Java库

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在Java开发中,特别是在处理大数据、内存限制或需要快速查询是否存在某个元素的场景下,布隆过滤器是一个...

    Java版本的BloomFilter (布隆过滤器)

    **布隆过滤器(Bloom Filter)**是一种空间效率极高的概率型数据结构,用于测试一个元素是否在一个集合中。由Burton Howard Bloom在1970年提出,主要用于节省存储空间,尤其在大数据场景下,它能有效地解决大规模...

    Bloom_filter_(C).zip_bloom_bloom filter_c++布隆_布隆过滤器

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在C++中实现布隆过滤器,可以有效地处理大量数据,尤其是在内存有限的情况下。这个压缩包文件"Bloom_filter...

    Go-布隆过滤器的一个Go实现参考bloomfilter.js

    `bloomfilter.js`可能是JavaScript版本的布隆过滤器实现,而"Go-布隆过滤器的一个Go实现参考bloomfilter.js"则表明该Go版本的实现是借鉴了JavaScript版本的设计思路或代码结构。 Go实现布隆过滤器的关键组件包括: ...

    Go-一个简单的golang布隆过滤器

    布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。在Go语言中实现一个简单的布隆过滤器可以帮助我们高效地处理大数据集,尤其是在内存有限的情况下。以下是对这个主题的详细...

    介绍Bloom Filter(布隆过滤器)原理、实现及具体应用

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能在一个集合中。它可能会误判,但不会漏判,即可能存在假阳性(False Positive),但绝不会有假阴性(False Negative)。...

    java-bloomfilter

    布隆过滤器(Bloom Filter)是计算机科学中一种高效的空间节省的数据结构,主要用于判断一个元素是否可能存在于一个大规模集合中。它由伯特·布隆(Burton Howard Bloom)在1970年提出,因此得名。布隆过滤器在处理...

    带bloom filter 的c网络爬虫

    Bloom Filter是一种空间效率极高的概率型数据结构,常用于大数据集的去重和存在性查询,尤其在内存有限的情况下。 **描述:“linux下编写的网络爬虫,可以实现bloom filter 去重过滤,是用来垂直爬取www.8684.cn...

    java实现的布隆过滤器算法

    布隆过滤器(Bloom Filter)是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。它可能会误判,但不会漏判,即如果它说一个元素在集合中,那可能是错误的,但如果它说一个元素不在集合中,那么...

    Python-bloomfilter过滤器

    **Python-bloomfilter过滤器详解** Bloom Filter是一种空间效率极高的概率型数据结构,用于判断一个元素是否在一个集合中。在Python开发中,尤其是在处理大量数据时,Bloom Filter可以有效地节省内存空间,尤其适用...

    Cuckoo过滤器:实际上比 Bloom 更好_Go语言_代码_相关文件_下载

    虽然 Bloom 过滤器是众所周知的节省空间的数据结构,可以服务于“如果项目 x 在一个集合中?”之类的查询,但它们不支持删除。它们启用删除的差异(如计算 Bloom 过滤器)通常需要更多空间。 Cuckoo 过滤器提供了...

    布隆过滤器python库

    布隆过滤器是一种概率数据结构,用于判断一个元素是否可能在一个集合中存在。它通过使用位数组和几个独立的哈希函数来实现,具有高效、节省空间的特点,但可能会产生假阳性错误,即误判一个不在集合中的元素为在集合...

    bloom-filter-scala, 用于 Scala的Bloom过滤器,最快的JVM.zip

    bloom-filter-scala, 用于 Scala的Bloom过滤器,最快的JVM Scala的 Bloom filter 概述Bloom过滤器是一种空间高效的数据结构,用于测试某个元素是否是集合的成员。 false 正匹配是可能的,但 false 负数不是。 ...

    转载:布隆过滤器算法

    布隆过滤器是一种高效的数据结构,特别适用于大数据集的快速查询场景。通过本篇文章的学习,我们不仅了解了布隆过滤器的基本原理,还通过具体的C/C++实现代码深入理解了其内部机制。在未来的工作中,可以根据具体...

Global site tag (gtag.js) - Google Analytics