布隆過濾器原理及實現

2021-10-09 14:30:42 字數 1779 閱讀 6236

如何高效判斷元素w是否存在於集合a之中?首先想到的答案是,把集合a中的元素乙個個放到雜湊表中,然後在雜湊表中查一下w即可。這樣確實可以解決小資料量場景下元素存在性判定,但如果a中元素數量巨大,甚至資料量遠遠超過機器記憶體空間,該如何解決問題呢?

實現乙個基於磁碟和記憶體的雜湊索引當然可以解決這個問題。而另一種低成本的方式就是借助布隆過濾器(bloom filter)來實現。

布隆過濾器由乙個長度為n的01陣列array組成。首先將陣列array每個元素初始設為0。

對集合a中的每個元素w,做k次雜湊,第i次雜湊值對n取模得到乙個index(i),即index(i)=hash_i(w)%n,將array陣列中的array[index(i)]置為1。最終array變成乙個某些元素為1的01陣列。

下面舉個例子,如圖所示,a=,n=18,k=3。

初始化array=000000000000000000。

對元素x,hash_0(x)%n=0,hash_1(x)%n=4,hash_2(x)%n=16。因此array=100010000000000010。

對元素y,hash_0(y)%n=7,hash_1(y)%n=10,hash_2(y)%n=14。因此array=000000010010001000。

對元素z,hash_0(z)%n=2,hash_1(y)%n=10,hash_2(y)%n=17。因此array=001000000010000010。

此時,對於元素w,k次雜湊值分別為:

hash_0(w)%n=4

hash_1(w)%n=13

hash_2(w)%n=15

可以發現,布隆過濾器串中的第15位為0,因此可以確認w肯定不在集合a中。因為若w在a中,則第15位必定為1。

如果有另外乙個元素t,k次雜湊值分別為:

hash_0(t)%n=1

hash_1(t)%n=7

hash_2(t)%n=17

我們發現布隆過濾器串中的第1、7、17位都為1,但是卻沒法肯定t一定在集合a中。

因此,布隆過濾器串對任意給定元素w,給出的存在性結果為兩種:

·w可能存在於集合a中。

·w肯定不在集合a中。

在**[1]中證明,當n取k*|a|/ln2時(其中|a|表示集合a元素個數),能保證最佳的誤判率,所謂誤判率也就是過濾器判定元素可能在集合中但實際不在集合中的佔比。

舉例來說,若集合有20個元素,k取3時,則設計乙個n=3×20/ln2=87二進位制串來儲存布隆過濾器比較合適。

演算法實現

布隆過濾器的**實現很短,如下所示:

public class bloomfilter 

public byte generate(byte keys)

}return result;

} public boolean contains(byte key)

int delta = (h >> 17) | (h << 15);

h += delta;

}return true;

}}

有兩個地方說明一下:

·在構造方法bloomfilter(int k,int bitsperkey)中,k表示每個key雜湊的次數,bitsperkey表示每個key占用的二進位制bit數,若有x個key,則n=x*bitsperkey。

·在實現中,對key做k次雜湊時,算出第一次雜湊值h之後,可借助h位運算來實現二次雜湊,甚至三次雜湊。這樣效能會比較好。

布隆過濾器速度 布隆過濾器原理及在推薦業務的應用

提到布隆過濾器總想起上大學時候學習的什麼切比雪夫濾波器之類的東西 博主是學通訊的 我發現過濾器一般都是以發明人的名字命名,布隆過濾器是一種布林型判斷器,可以非常高效的判斷乙個物品是否在某個列表裡。有人說判斷乙個item是否在乙個item列表裡,只要將所有item存在資料庫,或者做一層快取存在redi...

布隆過濾器

布隆過濾器 bloom filter 是1970年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。如果想要判斷乙個元素是不是在乙個集合裡,一般想到...

布隆過濾器

布隆過濾器的概念 如果想要判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路.但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢 o n o logn 不過世界上還有一種叫作雜湊表 又叫 雜湊表,hash tabl...