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
值很重要。
加群
加陈某微信,陈某会第一时间拉你进群。