布隆過濾器的改進及其應用實踐


1 目的

  一個好的過濾算法需要具備的特征有:低時間復雜度、低空間復雜度、低錯誤率。本算法從低時間復雜度(算法只需要讀取一次文件)和空間復雜度出發,通過尋找它們的平衡點以達到低錯誤率。

2 原理

  當需要判斷一個元素是不是在一個集合中,我們通常做法是把所有元素保存下來,然后通過比較知道它是不是在集合內,鏈表、樹都是基於這種思路,當集合內元素個數的變大,我們需要的空間和時間都線性變大,檢索速度也越來越慢。 BloomFilter采用的是哈希函數的方法,將一個元素映射到一個m長度的陣列上的一個點,當這個點是 1 時,那么這個元素在集合內,反之則不在集合內。這個方法的缺點就是當檢測的元素很多的時候可能有沖突,解決方法就是使用k個哈希函數對應k個點,如果所有點都是 1 的話,那么元素在集合內,如果有 0 的話,元素則不在集合內。

根據此原理可以推斷出總的誤判個數期望為

 

  具體的證明可以看參考的博客鏈接

  假設去重后總量為1億條,可利用內存最大為1G,也就是位數組長度2^33為 ,則可預估如下表結果:

假設總量:

1億

 

 

 

 

Hash個數

h=3

h=4

h=5

h=6

h=7

誤判數

1022

87

10

2

0

誤判率

1.02E-05

8.70E-07

1.00E-07

2.00E-08

0.00E+00

為此,在執行中只需要將哈希函數的個數設置為7個即可保證很大程度上與真實總量一致.

3 執行步驟

 

4 算法的改進

•用多個標准布隆過濾器表示多維集合的單屬性域。
•多個濾器共同完成元素的表示及是否屬於集合的查詢判斷。
 
 具體的流程圖見下

 

與傳統的布隆過濾器相比

優勢:每個字符串只進行一次數值轉換,傳統做法是多個Hash函數產生多個值,我們只產生一個值,利用多Mod對該值取余(等價於多Hash函數),減少多次Hash函數值轉換帶來的運行時間。

劣勢:貌似可以證明與傳統的算法的空間復雜度與准確率均相等,所以暫時說不出啥缺點

 

  對於一個字符串,經過HashCode轉換成對應的數值,分別對K個大素數進行求余操作,並查找對應的小布隆過濾器相對的位置是否為1,如果均為1則該字符串已經包含其中,否則是新字符串,既而對相應的位置數值更改為1.

本人用這套思路在java上實現了,判斷1億條數據,占用內存700M,准確率達100%

 

具體的實現代碼可查閱本人的Github:

 https://github.com/JueFan/BloomFilterTool

參考博客

 http://blog.csdn.net/jiaomeng/article/details/1495500


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM