m
比特的位
數組與
k
個
哈希函數組成的數據結構。比特數組均初始化爲
0
,全部哈希函數均可以分別把輸入數據儘可能均勻地散列。
k
個哈希函數轉換成
k
個哈希值,這
k
個哈希值將做爲比特數組的
下標
,並將數組中的對應下標的值置爲
1
。
k
個哈希函數轉換成
k
個哈希值(數組下標),查詢數組中對應下標的值,若是有一個下標的值爲
0
代表該元素必定不在集合中,若是所有下標的值都爲
1
,代表該元素有
可能
在集合中。
至於爲何有可能在集合中? 由於有可能某個或者多個下標的值爲 1 是受到其餘元素的影響,這就是所謂的
假陽性
,下文會詳細講述。
m=18
,
k=3
的布隆過濾器示例。集合中的 x、y、z 三個元素經過 3 個不一樣的哈希函數散列到位數組中。當查詢元素 w 時,由於有一個比特爲 0,所以 w 不在該集合中。
m
的布隆過濾器中插入一個元素,它的其中一個哈希函數會將某個特定的比特置爲
1
。所以,在插入元素後,該比特仍然爲 0 的機率是:
k
個哈希函數,並插入
n
個元素,天然就能夠獲得該比特仍然爲 0 的機率是:
1
的機率就是:
n
個元素後,咱們用一個不在集合中的元素來檢測,那麼被誤報爲存在於集合中的機率(也就是全部哈希函數對應的比特都爲
1
的機率)爲:
n
比較大時,根據極限公式,能夠近似得出假陽性率:
k
必定的狀況下有以下結論:
O(k)
。
假陽性
的機率,準確率要求高的場景不太適用。
假陽性
的機率會很低,另外一方面,你認爲百度會在乎這種的偏差嗎,你的一篇文章可能由於假陽性機率沒有收錄到,對百度有影響嗎?
docker pull redislabs/rebloom
docker run -p6379:6379 redislabs/rebloom
複製代碼
redis-cli
複製代碼
1. 建立布隆過濾器java
BloomFilter<Integer> filter = BloomFilter.create(
Funnels.integerFunnel(),
5000,
0.01);
//插入
IntStream.range(0, 100_000).forEach(filter::put);
//判斷是否存在
boolean b = filter.mightContain(1);
複製代碼
arg1
:用於將任意類型 T 的輸入數據轉化爲 Java 基本類型的數據,這裏轉換爲 byte
arg2
:byte 字節數組的基數
arg3
:指望的假陽性機率
2.估計最優 m 值和 k 值面試
//m值的計算
static long optimalNumOfBits(long n, double p) {
if (p == 0) {
p = Double.MIN_VALUE;
}
return (long) (-n * Math.log(p) / (Math.log(2) * Math.log(2)));
}
//k值的計算
static int optimalNumOfHashFunctions(long n, long m) {
// (m / n) * log(2), but avoid truncation due to division!
return Math.max(1, (int) Math.round((double) m / n * Math.log(2)));
}
複製代碼
k
值應爲:
p
值和
m
值很重要。
加羣
加陳某微信,陳某會第一時間拉你進羣。