Bloom Filter演算法

來源:互聯網
上載者:User

集合資料結構一般都有這麼一個方法:contains。其作用就是判斷給定的元素是否存在集合中,這是一個常用的方法。其最簡單的內部實現即遍曆集合內的元素,一個個的判斷是否與給定元素相等。為了更高效點我們甚至可以採用“更好的(好是相對的)”演算法實現。比如如果該集合是已經排序的,那麼我們用二分尋找來實現contains肯定更好。但是,如果集合的資料量龐大到一定程度,大部分我們熟知的演算法不再有什麼用了。即使可以使用,但是機器記憶體也不允許。

而Bloom Filter就是這麼一個空間利用率非常高的演算法。我們先來看看這個演算法的原理:

1 首先我們有一個長度為n的位元數組,開始的時候將這個位元數組裡所有的元素都初始化為0

00000000000000000000

上面的位元數組n為20

2 然後選取k個雜湊函數,這k個雜湊函數產生的結果的值的範圍在0到n-1之間(對於上面的位元數組,即0到19) 。對每個要添加進集合的對象進行雜湊運算,然後將雜湊計算結果作為數組的索引,將索引位置的位元位設定為1(不管該位元位原先為0還是為1)。

比如我們選取三個雜湊函數,對於對象A雜湊值為0,5,7。那麼位元數組就為:

10000101000000000000

對象B的值為2,8,13,那麼添加B後的位元數組為:

10100101100001000000

對象C為0,4,7(對象C的第一個雜湊函數的值與對象A的相同了,沒關係我們還是設定為1就可以了):

10101101100001000000

現在我們的Bloom Filter裡已經有3個元素了。現在我們要判斷某元素X是否在該集合中。就相當於我們要實現一個contains方法。那麼這個方法如何?呢?

對元素X採用相同的三個雜湊函數雜湊,然後以這三個雜湊值為索引去位元數組裡找。如果三個索引位置的位元位都為1我們就認為該元素在集合中,否則不是。

我們可以用虛擬碼簡單的描述一下這個演算法:

public class BloomFilter{
    private bit[] bitSet = new bit[N];

    public void add(Object element){
      int[] hashValues = getHashValues(element);
      for(int i : hashValues){
         bitSet[i] = 1;
      }
    }

    public boolean contains(Object element){
        int[] hashValues = getHashValues(element);
        for(int i : hashValues){
           if(bitSet[i] != 1) return false;
        }
        return true;
    }

 

}

演算法還是挺直觀的,對不。想想,一個很大的對象,經過一雜湊,然後就變成了Bloom Filter裡面的一個位元,這個空間利用效率是多麼高啊。如果雜湊函數的實現效率也很高的話那麼不僅空間利用率高,時間複雜度也低啊。這真是一個神奇的演算法對吧。

可能你想,以後我就把我們那個啥數組的contains方法替換成Bloom Filter的實現吧。

不過你仔細驗證過這個演算法沒,它存在一些問題。這個演算法有以下這麼幾個特徵:

1 如果該元素真的在集合中,那麼Bloom Filter的contains方法肯定會返回true,這就是Bloom Filter不會漏報的特性。

2 如果該元素不在集合中,但Bloom Filter的contains方法有可能返回true。因為不同的元素經過雜湊之後雜湊值可能發生碰撞。這是Bloom Filter有可能誤判的特性。但是這個誤判的幾率並不高。

根據這兩個特性Bloom Filter在大量資料時還是挺有用的。比如假設我們有一個快取服務器叢集,叢集裡的不同的伺服器承擔的緩衝也不盡相同。如果一個使用者請求過來了,我們如何能快速的判斷出使用者請求的這個url在叢集裡哪台伺服器上呢?因為每台伺服器上緩衝的url對應的頁面非常龐大,我們全部弄到記憶體裡代價也很高。我們就可以在每台伺服器上放一個Bloom Filter,裡面添加的都是本伺服器上有緩衝的那些url。這樣即使Bloom Filter誤判了,那就是把一個url發到了一個並不持有該url對應的緩衝的伺服器上,結果就是緩衝未命中,快取服務器只需要將該url打到後端的上遊伺服器就好了。

根據Bloom Filter的特徵我們可以看到不是所有的情境都可以用的,只有在一些能容許少量的誤判的情況下使用才行。該演算法用很低的誤判率卻換來了大量的儲存空間,實在是是一個很巧妙的演算法。 

 Bloom Filter演算法:http://en.wikipedia.org/wiki/Bloom_filter

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.