Bloom Filter算法

一、概念

Bloom Filter的中文翻譯叫做布隆過濾器,是1970年由布隆提出的。它實際上是一個很長的二進制向量和一系列隨機映射函數。布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都遠遠超過一般的算法,缺點是有一定的誤識別率和刪除困難。如文章標題所述,本文只是做簡單介紹,屬于科普文章。

二、應用場景

在正式介紹Bloom Filter算法之前,先來看看什么時候需要用到Bloom Filter算法。

1. HTTP緩存服務器、Web爬蟲等

主要工作是判斷一條URL是否在現有的URL集合之中(可以認為這里的數據量級上億)。

  • 對于HTTP緩存服務器,當本地局域網中的PC發起一條HTTP請求時,緩存服務器會先查看一下這個URL是否已經存在于緩存之中,如果存在的話就沒有必要去原始的服務器拉取數據了(為了簡單起見,我們假設數據沒有發生變化),這樣既能節省流量,還能加快訪問速度,以提高用戶體驗。
  • 對于Web爬蟲,要判斷當前正在處理的網頁是否已經處理過了,同樣需要當前URL是否存在于已經處理過的URL列表之中。

2. 垃圾郵件過濾

假設郵件服務器通過發送方的郵件域或者IP地址對垃圾郵件進行過濾,那么就需要判斷當前的郵件域或者IP地址是否處于黑名單之中。如果郵件服務器的通信郵件數量非常大(也可以認為數據量級上億),那么也可以使用Bloom Filter算法。

幾個專業術語

這里有必要介紹一下False Positive和False Negative的概念(更形象的描述可以閱讀第4條參考)。

  • False Positive中文可以理解為“假陽性”,形象的一點說就是“誤報”,后面將會說道Bloom Filter存在誤報的情況,現實生活中也有誤報,比如說去體檢的時候,醫生告訴你XXX檢測是陽性,而實際上是陰性,也就是說誤報了,是假陽性,殺毒軟件誤報也是同樣的概念。
  • False Negative,中文可以理解為“假陰性”,形象的一點說是“漏報”。醫生告訴你XXX檢測為陰性,實際上你是陽性,你是有病的(Sorry, it’s just a joke),那就是漏報了。同樣殺毒軟件也存在漏報的情況。

?

三、Bloom Filter算法

初始狀態下,Bloom Filter是一個m位的位數組,且數組被0所填充。同時,我們需要定義k個不同的hash函數,每一個hash函數都隨機的將每一個輸入元素映射到位數組中的一個位上。那么對于一個確定的輸入,我們會得到k個索引。

插入元素:經過k個hash函數的映射,我們會得到k個索引,我們把位數組中這k個位置全部置1(不管其中的位之前是0還是1)

查詢元素:輸入元素經過k個hash函數的映射會得到k個索引,如果位數組中這k個索引任意一處是0,那么就說明這個元素不在集合之中;如果元素處于集合之中,那么當插入元素的時候這k個位都是1。但如果這k個索引處的位都是1,被查詢的元素就一定在集合之中嗎?答案是不一定,也就是說出現了False Positive的情況(但Bloom Filter不會出現False Negative的情況)

在上圖中,當插入x、y、z這三個元素之后,再來查詢w,會發現w不在集合之中,而如果w經過三個hash函數計算得出的結果所得索引處的位全是1,那么Bloom Filter就會告訴你,w在集合之中,實際上這里是誤報,w并不在集合之中。

?

False Positive Rate

Bloom Filter的誤報率到底有多大?下面在數學上進行一番推敲。假設HASH函數輸出的索引值落在m位的數組上的每一位上都是等可能的。那么,對于一個給定的HASH函數,在進行某一個運算的時候,一個特定的位沒有被設置為1的概率是

bloom filter pr1


那么,對于所有的k個HASH函數,都沒有把這個位設置為1的概率是

bloom filter pr2


如果我們已經插入了n個元素,那么對于一個給定的位,這個位仍然是0的概率是

bloom filter pr3


那么,如果插入n個元素之后,這個位是1的概率是

bloom filter pr4


如果對一個特定的元素存在誤報,那么這個元素的經過HASH函數所得到的k個索引全部都是1,概率也就是

bloom filter pr5


根據常數e的定義,可以近似的表示為:

bloom filter pr6

?

關于誤報

有時候誤報對實際操作并不會帶來太大的影響,比如對于HTTP緩存服務器,如果一條URL被誤以為存在與緩存服務器之中,那么當取數據的時候自然會無法取到,最終還是要從原始服務器當中獲取,之后再把記錄插入緩存服務器,幾乎沒有什么不可以接受的。
對于安全軟件,有著“另可錯報,不可誤報”的說法,如果你把一個正常軟件誤判為病毒,對使用者來說不會有什么影響(如果用戶相信是病毒,那么就是刪除這個文件罷了,如果用戶執意要執行,那么后果也只能由用戶來承擔);如果你把一個病毒漏判了,那么對用戶造成的后果是不可設想的……更有甚者,誤報在某種程度上能讓部分用戶覺得你很專業……

參考資料:

1.?Bloom Filter 算法簡介 (增加 Counting Bloom Filter 內容

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385279.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385279.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385279.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

237. 刪除鏈表中的節點

請編寫一個函數,使其可以刪除某個鏈表中給定的(非末尾)節點,你將只被給定要求被刪除的節點。 現有一個鏈表 -- head [4,5,1,9],它可以表示為: 示例 1: 輸入: head [4,5,1,9], node 5 輸出: [4,1,9] 解釋: 給定你鏈表…

151. 翻轉字符串里的單詞

輸入: " hello world! " 輸出: "world! hello" 解釋: 輸入字符串可以在前面或者后面包含多余的空格,但是反轉后的字符不能包括。 示例 3: 輸入: "a good example" 輸出: "example good a" 解釋: 如果兩個單…

進程間同步(互斥量、信號量)

進程間同步可以使用互斥量mutex(互斥鎖)、信號量和文件鎖。 進程間同步使用信號量: int sem_init(sem_t *sem, int pshared, unsigned int value); 用于進程間同步此時第二個參數不能取0了,取非0值用于進程間同步,一…

1059 Prime Factors(25 分)

Given any positive integer N, you are supposed to find all of its prime factors, and write them in the format N p?1???k?1????p?2???k?2?????p?m???k?m????. Input Specification: Each input file contains one test case which gives a…

STL源碼剖析

1. 當vector的內存用完了,它是如何動態擴展內存的?它是怎么釋放內存的?用clear可以釋放掉內存嗎?是不是線程安全的? vector內存用完了,會以當前size大小重新申請2* size的內存,然后把原來的元素…

C++ 內存管理機制

內存分配方式 簡介 在C中,內存分成5個區,他們分別是堆、棧、自由存儲區、全局/靜態存儲區和常量存儲區。 棧:在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存…

哲學家用餐模型

分析: 為了避免死鎖,做了如下規定:每個哲學家先拿自己左手邊的筷子,然后再去拿右手邊的筷子,如果不能同時得到兩支筷子,則該哲學家放下手中已有的筷子。這種規定依然會因為振蕩而產生死鎖,例如…

【C++ Primer | 16】std::move和std::forward、完美轉發

右值引用應該是C11引入的一個非常重要的技術,因為它是移動語義(Move semantics)與完美轉發(Perfect forwarding)的基石: 移動語義:將內存的所有權從一個對象轉移到另外一個對象,高效…

循環引用

1. 測試代碼 #include <iostream> #include <memory> using namespace std;class B; class A { public:shared_ptr<B> pb;~A() { cout << "kill A\n";} };class B { public:shared_ptr<A> pa;~B() { cout << "kill B\n&q…

8. 字符串轉換整數 (atoi)

請你來實現一個 atoi 函數&#xff0c;使其能將字符串轉換成整數。 首先&#xff0c;該函數會根據需要丟棄無用的開頭空格字符&#xff0c;直到尋找到第一個非空格的字符為止。 當我們尋找到的第一個非空字符為正或者負號時&#xff0c;則將該符號與之后面盡可能多的連續數字組…

【C++ Primer | 16】容器適配器全特化、偏特化

上面對模板的特化進行了總結。那模板的偏特化呢&#xff1f;所謂的偏特化是指提供另一份模板定義式&#xff0c;而其本身仍為模板&#xff1b;也就是說&#xff0c;針對模板參數更進一步的條件限制所設計出來的一個特化版本。這種偏特化的應用在STL中是隨處可見的。比如 1.測試…

select、poll、epoll優缺點

select的缺點&#xff1a; 單個進程能夠監視的文件描述符的數量存在最大限制&#xff0c;通常是1024&#xff0c;當然可以更改數量&#xff0c;但由于select采用輪詢的方式掃描文件描述符&#xff0c;文件描述符數量越多&#xff0c;性能越差&#xff1b;內核/用戶空間內存拷貝…

vector源碼剖析

一、vector定義摘要&#xff1a; template <class T, class Alloc alloc> class vector { public:typedef T value_type;typedef value_type* pointer;typedef const value_type* const_pointer;typedef value_type* iterator;typ…

vs2013編譯win-32位下的libevent-2.0.21-stable,debug版本

環境&#xff1a;win10&#xff08;64位&#xff09;vs2013 首先需要修改Makefile.nmake中的CFLAGS$(CFLAGS) /Ox /W3 /wd4996 /nologo注釋掉&#xff0c;這一行是不帶調試信息的。CFLAGS$(CFLAGS) /Od /W3 /wd4996 logo /Zi 替換這一行之后就可以自帶調試信息。 打開vs2013的…

Leetcode 219. 存在重復元素 II

解題思路&#xff1a; class Solution { public:bool containsNearbyDuplicate(vector<int>& nums, int k) {unordered_map<int, int> cnt;for(int i0; i<nums.size(); i){if(cnt.find(nums[i]) ! cnt.end()){if(i - cnt[nums[i]] < k) return true;}cn…

Linux程序設計01:開發工具和開發平臺

1.SecureCRT 1.1SecureCRT支持SSH*&#xff08;SSH1和SSH2&#xff09;&#xff0c;安裝的過程不在贅述 1.2與SecureCRT相關的Linux命令 rz和sz是Linux同windows進行ZModem文件傳輸的命令行工具。 sz命令利用ZModem協議來從Linux服務器傳送文件到本地&#xff0c;一次可以傳送一…

fork、vfork、clone

1. 概念 寫時復制技術最初產生于Unix系統&#xff0c;用于實現一種傻瓜式的進程創建&#xff1a;當發出fork( )系統調用時&#xff0c;內核原樣復制父進程的整個地址空間并把復制的那一份分配給子進程。這種行為是非常耗時的&#xff0c;因為它需要&#xff1a; 為子進程的頁…

Linux02進程內存管理

1.進程地址空間 1.1程序的結構與進程的結構 [rootlocalhost demo]# size testtext data bss dec hex filename 1193 492 16 1701 6a5 test 一個可執行程序包含三個部分&#xff1a; 代碼段&#xff1a;主要存放指令&#xff0c;操作以及只讀的常量數據例…

epoll

開發高性能網絡程序時&#xff0c;windows開發者們言必稱iocp&#xff0c;linux開發者們則言必稱epoll。大家都明白epoll是一種IO多路復用技術&#xff0c;可以非常高效的處理數以百萬計的socket句柄&#xff0c;比起以前的select和poll效率高大發了。我們用起epoll來都感覺挺爽…

劍指offer目錄

序號題目1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21