• 布隆过滤器的改进及其应用实践


    1 目的

      一个好的过滤算法需要具备的特征有:低时间复杂度、低空间复杂度、低错误率。本算法从低时间复杂度(算法只需要读取一次文件)和空间复杂度出发,通过寻找它们的平衡点以达到低错误率。

    2 原理

      当需要判断一个元素是不是在一个集合中,我们通常做法是把所有元素保存下来,然后通过比较知道它是不是在集合内,链表、树都是基于这种思路,当集合内元素个数的变大,我们需要的空间和时间都线性变大,检索速度也越来越慢。 BloomFilter采用的是哈希函数的方法,将一个元素映射到一个m长度的阵列上的一个点,当这个点是 1 时,那么这个元素在集合内,反之则不在集合内。这个方法的缺点就是当检测的元素很多的时候可能有冲突,解决方法就是使用k个哈希函数对应k个点,如果所有点都是 1 的话,那么元素在集合内,如果有 0 的话,元素则不在集合内。

    根据此原理可以推断出总的误判个数期望为

     

      具体的证明可以看参考的博客链接

      假设去重后总量为1亿条,可利用内存最大为1G,也就是位数组长度2^33为 ,则可预估如下表结果:

    假设总量:

    1亿

     

     

     

     

    Hash个数

    h=3

    h=4

    h=5

    h=6

    h=7

    误判数

    1022

    87

    10

    2

    0

    误判率

    1.02E-05

    8.70E-07

    1.00E-07

    2.00E-08

    0.00E+00

    为此,在执行中只需要将哈希函数的个数设置为7个即可保证很大程度上与真实总量一致.

    3 执行步骤

     

    4 算法的改进

    •用多个标准布隆过滤器表示多维集合的单属性域。
    •多个滤器共同完成元素的表示及是否属于集合的查询判断。
     
     具体的流程图见下

     

    与传统的布隆过滤器相比

    优势:每个字符串只进行一次数值转换,传统做法是多个Hash函数产生多个值,我们只产生一个值,利用多Mod对该值取余(等价于多Hash函数),减少多次Hash函数值转换带来的运行时间。

    劣势:貌似可以证明与传统的算法的空间复杂度与准确率均相等,所以暂时说不出啥缺点

      对于一个字符串,经过HashCode转换成对应的数值,分别对K个大素数进行求余操作,并查找对应的小布隆过滤器相对的位置是否为1,如果均为1则该字符串已经包含其中,否则是新字符串,既而对相应的位置数值更改为1.

    本人用这套思路在java上实现了,判断1亿条数据,占用内存700M,准确率达100%

    具体的实现代码可查阅本人的Github:

     https://github.com/JueFan/BloomFilterTool

    参考博客

     http://blog.csdn.net/jiaomeng/article/details/1495500

  • 相关阅读:
    二叉树进阶之寻找一棵二叉树中的最大二叉搜索子树
    二叉树进阶之求一棵二叉树中结点间最大距离
    软件工程各阶段的UML图
    软件工程各阶段的开发文档
    二叉树应用进阶之折纸(二叉树的右根左遍历)
    二叉树进阶应用之查找结点的后继结点
    二叉树进阶之满二叉树和完全二叉树
    二叉树进阶之搜索二叉树的判断与找出搜索二叉树中出错的结点
    二叉树进阶之平衡二叉树的判断
    二叉树基础之序列化和反序列化二叉树
  • 原文地址:https://www.cnblogs.com/juefan/p/BloomFilter.html
Copyright © 2020-2023  润新知