在日常生活中,包括在設計計算機軟體時,我們經常要判斷乙個元素是否在乙個集合中。比如在字處理軟體中,需要檢查乙個英語單詞是否拼寫正確(也就是要判斷它是否在已知的字典中);在 fbi,乙個嫌疑人的名字是否已經在嫌疑名單上;在網路爬蟲裡,乙個**是否被訪問過等等。最直接的方法就是將集合中全部的元素存在計算機中,遇到乙個新元素時,將它和集合中的元素直接比較即可。一般來講,計算機中的集合是用雜湊表(hash table)來儲存的。它的好處是快速準確,缺點是費儲存空間。當集合比較小時,這個問題不顯著,但是當集合巨大時,雜湊表儲存效率低的問題就顯現出來了。比如說,乙個象 yahoo,hotmail 和 gmai 那樣的公眾電子郵件(email)提供商,總是需要過濾來自傳送垃圾郵件的人(spamer)的垃圾郵件。乙個辦法就是記錄下那些發垃圾郵件的 email 位址。由於那些傳送者不停地在註冊新的位址,全世界少說也有幾十億個發垃圾郵件的位址,將他們都存起來則需要大量的網路伺服器。如果用雜湊表,每儲存一億個 email 位址, 就需要 1.6gb 的記憶體(用雜湊表實現的具體辦法是將每乙個 email 位址對應成乙個八字節的資訊指紋 googlechinablog.com/2006/08/blog-post.html,然後將這些資訊指紋存入雜湊表,由於雜湊表的儲存效率一般只有 50%,因此乙個 email 位址需要占用十六個位元組。一億個位址大約要 1.6gb, 即十六億位元組的記憶體)。因此存貯幾十億個郵件位址可能需要上百 gb 的記憶體。除非是超級計算機,一般伺服器是無法儲存的。
今天,我們介紹一種稱作布隆過濾器的數學工具,它只需要雜湊表 1/8 到 1/4 的大小就能解決同樣的問題。
布隆過濾器是由巴頓.布隆於一九七零年提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。我們通過上面的例子來說明起工作原理。
假定我們儲存一億個電子郵件位址,我們先建立乙個十六億二進位制(位元),即兩億位元組的向量,然後將這十六億個二進位制全部設定為零。對於每乙個電子郵件位址 x,我們用八個不同的隨機數產生器(f1,f2, ...,f8) 產生八個資訊指紋(f1, f2, ..., f8)。再用乙個隨機數產生器 g 把這八個資訊指紋對映到 1 到十六億中的八個自然數 g1, g2, ...,g8。現在我們把這八個位置的二進位制全部設定為一。當我們對這一億個 email 位址都進行這樣的處理後。乙個針對這些 email 位址的布隆過濾器就建成了。(見下圖)
現在,讓我們看看如何用布隆過濾器來檢測乙個可疑的電子郵件位址 y 是否在黑名單中。我們用相同的八個隨機數產生器(f1, f2, ..., f8)對這個位址產生八個資訊指紋 s1,s2,...,s8,然後將這八個指紋對應到布隆過濾器的八個二進位制位,分別是 t1,t2,...,t8。如果 y 在黑名單中,顯然,t1,t2,..,t8 對應的八個二進位制一定是一。這樣在遇到任何在黑名單中的電子郵件位址,我們都能準確地發現。
布隆過濾器決不會漏掉任何乙個在黑名單中的可疑位址。但是,它有一條不足之處。也就是它有極小的可能將乙個不在黑名單中的電子郵件位址判定為在黑名單中,因為有可能某個好的郵件位址正巧對應個八個都被設定成一的二進位制位。好在這種可能性很小。我們把它稱為誤識概率。在上面的例子中,誤識概率在萬分之一以下。
布隆過濾器的好處在於快速,省空間。但是有一定的誤識別率。常見的補救辦法是在建立乙個小的白名單,儲存那些可能別誤判的郵件位址。
布隆過濾器
布隆過濾器 bloom filter 是1970年由布隆提出的。它實際上是乙個很長的二進位制向量和一系列隨機對映函式。布隆過濾器可以用於檢索乙個元素是否在乙個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的演算法,缺點是有一定的誤識別率和刪除困難。如果想要判斷乙個元素是不是在乙個集合裡,一般想到...
布隆過濾器
布隆過濾器的概念 如果想要判斷乙個元素是不是在乙個集合裡,一般想到的是將所有元素儲存起來,然後通過比較確定。鍊錶,樹等等資料結構都是這種思路.但是隨著集合中元素的增加,我們需要的儲存空間越來越大,檢索速度也越來越慢 o n o logn 不過世界上還有一種叫作雜湊表 又叫 雜湊表,hash tabl...
布隆過濾器
如果想判斷乙個元素是不是在乙個集合裡,一般想到的是將集合中所有元素儲存起來,然後通過比較確定。鍊錶 樹 雜湊表 又叫雜湊表,hash table 等等資料結構都是這種思路。但是隨著集合中元素的增加,我們需要的儲存空間越來越大。同時檢索速度也越來越慢。bloom filter 是一種空間效率很高的隨機...