编程语言
首页 > 编程语言> > 布隆过滤器(Bloom Filter)算法的实现原理

布隆过滤器(Bloom Filter)算法的实现原理

作者:互联网

文章目录


前言

布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多。

一、布隆过滤器

1、算法描述

在这里插入图片描述

当需要新增的所有元素都添加到布隆过滤器之后,那么比特数组中的很多比特都被设置为1。这个时候如果需要判断一个元素是否存在于布隆过滤器中,只需要通过k个散列函数处理得到比特数组的k个下标,然后判断比特数组对应的下标所在比特是否为1。如果这k个下标所在比特中至少存在一个0,那么这个需要判断的元素必定不在布隆过滤器代表的集合中;如果这k个下标所在比特全部都为1,那么那么这个需要判断的元素可能存在于布隆过滤器代表的集合中或者刚好是一个False Positive

2、False positives 概率推导

布隆过滤器的显着特点是在m和误报概率之间存在明显的权衡。观察到在将n 个键插入大小为m的表后,特定位仍然为 0 的概率恰好为
在这里插入图片描述
因此,在这种情况下误报的概率是

在这里插入图片描述
右手边被最小化 k = ln ⁡ 2 × m / n k = \ln 2 \times m / n k=ln2×m/n,此时False Positives的概率为
在这里插入图片描述
参考资料: 链接

3、优势和劣势

二、布隆过滤器算法实现

public class HashFunction {

    /**
     * 布隆过滤器容量
     */
    private final int size;

    private final int seed;

    public HashFunction(int size, int seed) {
        this.size = size;
        this.seed = seed;
    }

    public int hash(String value) {
        int result = 0;
        int len = value.length();
        for (int i = 0; i < len; i++) {
            result = seed * result + value.charAt(i);
        }
        //与运算两位同时为1,结果才为1。确保计算出来的结果不会超过size
        return (size - 1) & result;
    }
}

public class MyBloomFilter {

/**
 * 为了降低错误率,使用加法hash算法,所以定义一个8个元素的质数数组
 */
private static final int[] SEEDS = {3, 5, 7, 11, 13, 31, 37, 61};

/**
 * 相当于构建 8 个不同的hash算法
 */
private static HashFunction[] functions;

/**
 * 初始化布隆过滤器的 bitmap
 */
private static BitSet bitset;


public MyBloomFilter(int size) {
    bitset = new BitSet(size);
    functions = new HashFunction[SEEDS.length];
    for (int i = 0; i < SEEDS.length; i++) {
        functions[i] = new HashFunction(size, SEEDS[i]);
    }
}

/**
 * 添加数据
 *
 * @param value 需要加入的值
 */
public void add(String value) {
    for (HashFunction function : functions) {
        //计算 hash 值并修改 bitmap 中相应位置为 true
        bitset.set(function.hash(value), true);
    }
}

/**
 * 判断相应元素是否存在
 *
 * @param value 需要判断的元素
 * @return 结果
 */
public boolean contains(String value) {
    if (value == null) {
        return false;
    }
    boolean ret = true;
    for (HashFunction f : functions) {
        ret = bitset.get(f.hash(value));
        //一个 hash 函数返回 false 则跳出循环
        if (!ret) {
            break;
        }
    }
    return ret;
}

/**
 * 测试。。。
 */
public static void main(String[] args) {
    MyBloomFilter bf = new MyBloomFilter(10);
    bf.add("Aa");

    System.out.println(bf.contains("BB")); //true
    System.out.println(bf.contains("Aa"));//true
}

总结

感谢您的阅读

如果你发现了错误的地方,可以在留言区提出来,我对其加以修改

标签:比特,int,元素,布隆,value,Filter,过滤器,Bloom
来源: https://blog.csdn.net/qq_39140300/article/details/118246591