布隆過濾器(Bloom Filter)

布隆過濾器(Bloom Filter)是一種基於Hash的高效查找數據結構,它可以快速答覆「某個元素是否存在」的問題。布隆過濾器只能用於添加元素與查詢元素,不可以用於刪除元素。git

在布隆過濾器以前,使用的是基於Hash的快速查找算法。Hash能夠將一個元素進行哈希,而後根據哈希值映射到數組的某一個位置。而且根據Hash算法的優劣,不一樣元素映射到相同位置的可能性不一樣。可是若是基於Hash的快速查找算法的數組大小被限制在必定的範圍內,那麼發生哈希衝突的機率將會變大。而且數組範圍越小,衝突機率將越大。所以布隆過濾器採用了使用多個hash函數進行運算來提升空間利用率。github

Bloom過濾器原理

布隆過濾器是由一個可變長度爲N的二進制數組與一組數量可變M的哈希函數構成。其中,哈希函數爲肯定性函數,全部哈希函數的輸出值都在1~N之間,與二進制數組相對應。所以,每個元素使用布隆過濾器的哈希函數進行運算都將會獲得相同的結果。
Bloom Filter算法

插入一個元素

假設咱們須要插入一個元素到布隆過濾器中,咱們須要使用不一樣的哈希函數進行運算生成不一樣的哈希值,而且根據生成的哈希值將二進制數組對應的Bit位置爲1.例如插入字符串"Bloom"到過濾器中,使用三種哈希函數進行計算所獲得的哈希值分別爲1,3,7,那麼布隆過濾器的二進制數組則會變爲:
數組

假設咱們插入第二個字符串"Filter"到過濾器中,一樣,咱們使用相同的哈希函數進行運算,假設哈希值分別爲2,4,7,那麼二進制數組則會變爲:
數據結構

由於在插入第一個字符串時,哈希值爲7的Bit位置已經被置爲1,所以不須要更改,只須要將Bit位爲2,4置爲1便可。ide

查詢元素

假設須要查詢某個元素是否存在,只須要使用相同的哈希函數進行運算,而後與二進制數組進行Bit值匹配便可。好比,咱們須要查詢字符串"hash"是否存在,使用以前的哈希函數進行運算,假設輸出的哈希值爲4,5,7,因爲Bit位爲5的位置仍然爲0,因此對於字符串"hash"並不存在。
函數

可是若是運算的哈希值爲2,3,7,咱們也只能說該字符串有可能存在。由於隨着存儲的數組越多,將會有越多的Bit位被置爲1,即便某個字符串沒有存儲,可是有可能該字符串的哈希值與其餘被存儲的數據哈希值重複,仍然可能誤判爲該字符串存在。
ui

所以,對於查詢某個元素,只能斷定某個元素必定不存在或者有可能存在,並不能斷定某個元素必定存在3d

選擇合適的數組長度與哈希函數數量

所以須要設置合適的數組長度與哈希函數數量。code

  • 數組越短則更容易全部的位置被置爲1,那麼可能查詢任何值都會被判斷可能存在,過濾的效率將大大下降。
  • 數組越長則會增長過濾效率,可是過長則會耗費大量空間。

哈希函數數量也會影響過濾效率.

  • 哈希函數越多則二進制位置1的次數越多,效率也會變低
  • 可是數量過少的話誤判率將會變高。

能夠經過如下公式計算合適的數組長度與哈希函數數量:

其中k爲哈希函數個數,m 爲布隆過濾器長度,n 爲插入的元素個數,p 爲誤報率。

Hash與布隆過濾器

實際上,不管是 Hash,仍是布隆過濾器,基本思想是一致的,

  • 都是基於內容的編址。
  • Hash 函數存在衝突,布隆過濾器也存在衝突。
  • 均可能誤報,但絕對不會漏報。

參考文獻: https://github.com/yeasy/blockchain_guide/blob/master/05_crypto/bloom_filter.md

相關文章
相關標籤/搜索