1. 程式人生 > >大量資料去重:Bitmap點陣圖演算法和布隆過濾器(Bloom Filter)

大量資料去重:Bitmap點陣圖演算法和布隆過濾器(Bloom Filter)

Bitmap演算法

與其說是演算法,不如說是一種緊湊的資料儲存結構。是用記憶體中連續的二進位制位(bit),用於對大量整型資料做去重和查詢。其實如果並非如此大量的資料,有很多排重方案可以使用,典型的就是雜湊表。

實際上,雜湊表為每一個可能出現的數字提供了一個一一對映的關係,每個元素都相當於有了自己的獨享的一份空間,這個對映由雜湊函式來提供(這裡我們先不考慮碰撞)。實際上雜湊表甚至還能記錄每個元素出現的次數,這樣的資料結構完成這個任務有點“大材小用”了。

如果用HashSet或HashMap儲存,每一個使用者ID都要存成int,佔4位元組即32bit。而一個使用者在Bitmap中只佔一個bit,記憶體節省了32倍!

不僅如此,bitmap在做交集和並集的時候也有極大的便利

不過bitmap不支援非運算,要想實現非運算,就得多提供一個全量的bitmap

比如,在應對標籤、使用者的場景下,可以使用一個標籤一個bitmap,bitmap上儲存含有此標籤的使用者,這樣有幾個標籤就有幾個bitmap,極大地節省了空間。此外,要查詢同時含有多個標籤的使用者,只需要讓bitmap進行&運算,或運算同理。而非運算需要增加一個全量的bitmap,用這個來儲存不包含的使用者的id。這樣要取非時只需要與這個bitmap進行異或運算即可。

JDK中的BitSet集合是對BitMap演算法相對簡單的實現,而谷歌開發的EWAHCompressedBitmap是一種更為優化的實現

如果對於一個很長的bitmap只儲存少量的資料,那麼會浪費一定的空間,所以谷歌的實現對這個空間進行了優化

然而Bitmap不是萬能的,如果資料量大到一定程度,如64bit型別的資料,不能用Bitmap,2^64bit=2^61Byte=2048PB=2EB

Bitmap的好處在於空間複雜度不隨原始集合內元素的個數增加而增加,而它的壞處也源於這一點——空間複雜度隨集合內最大元素增大而線性增大。

 

布隆演算法

是一種以bitmap集合為基礎的排重演算法,其應用場景如Url的排重,垃圾郵箱地址的過濾等鄰域

布隆演算法的核心思想就是對url進行多次不同演算法的hash,得到不同的hashcode,最後再將這些hashcode比較後對映到同一個bitmap上

如下示例中,只要三個值在bitmap上不同時為紅色,就可以插入,否則判斷為重複url

 

 

 

上圖為重複url

上圖誤判為重複url

為了減少誤判的機率,可以讓bitmap的空間更大一些,單個url所做的不同的hash更多一些(一般是8次),總之是在空間和準確率上做出取捨

bloom filter被用來檢測一個元素是不是集合中的一個成員。如果檢測結果是,該元素不一定在集合中;但如果檢測結果為否,該元素一定不在集合中。主要思路是:將一個元素對映到一個 m 長度的陣列上,使用 k 個雜湊函式對應 k 個點,如果所有點都是 1 的話,那麼元素在集合內,如果有 0 的話,元素則不在集合內。 錯誤率:如何根據輸入元素個數n,確定位陣列m的大小及hash函式個數k,k=(ln2)*(m/n)時錯誤率最小,為

 

 

參考連結:

如若讀完本文還不是很清楚,牆裂建議再閱讀以下文章

https://blog.csdn.net/zdxiq000/article/details/57626464

https://mp.weixin.qq.com/s?__biz=MzIxMjE5MTE1Nw==&mid=2653191272&idx=1&sn=9bbcd172b611b455ebfc4b7fb9a6a55e&chksm=8c990eb2bbee87a486c55572a36c577a48df395e13e74314846d221cbcfd364d44c280250234&scene=21#wechat_redirect     bitmap

https://mp.weixin.qq.com/s/RmR5XmLeMvk35vgjwxANFQ   布隆演算法