专栏文章
Filters
算法·理论参与者 7已保存评论 10
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @mj3478ow
- 此快照首次捕获于
- 2025/12/13 01:02 2 个月前
- 此快照最后确认于
- 2026/02/13 01:26 7 天前
前言:
本文中和文末设计了若干思考题,可以稍加思考。
Filter 用于解决如下问题:
- 插入一个元素 。
- 查询一个 是否出现过。
普通的做法是开一个 uset 直接做,但是这样有若干缺陷:
- 空间消耗大。
- 无法传输(这里指通信)。
因为如上原因,我们要引入 Bloom Filter(布隆过滤器)。
思考:平常的哈希表使用 vector 来避免冲突,我们现在允许一定的错误率,能否只用 01 字符串存储信息?要求只有假阳性而不会出现假阴性(即可能 0 回答成 1 而不允许 1 回答成 0)。
考虑如下算法:
- 设计哈希函数 。
- 对于一个插入操作,。
- 对于一个查询操作,查询 的值。
但是这样 FP 率比较高。Bloom Filter 采用了如上思想,但是做了些许改进。
- 设计哈希函数 。
- 对于一个插入操作,。
- 对于一个查询操作,查询 的值。
如果要取得较优的参数,可以查询 https://hur.st/bloomfilter/。
参数选择在合理范围内都具有可行性。
Bloom Filter 看似简单,事实上已经逼近了信息论的极限,但是仍然有许多方向可以优化。
- 增加删除操作(Cuckoo Filter)。
- 优化空间性能(Xor Filter)。
- 杜绝错误(4-coloring Filter),但是有额外限制。
Before Cuckoo:计数 Bloom Filter
思考:能否给 Bloom Filter 加入计数器使得其支持删除操作?
解答:显然可以,考虑存至多 次,则需要 倍空间,从赋值变为加减即可。
Cuckoo Filter 基于布谷鸟哈希算法。
布谷鸟哈希是一种特殊的哈希算法。
设立 。
- 如果 上没有巢穴直接随机放在 或 上。
- 如果 上只有一个巢穴直接放在空的巢穴上。
- 如果都不为空,则随机踢出一个元素,踢出的元素再重新计算哈希找到相应的位置。
可以设一个踢出阈值动态扩容。
现在思考如下问题:
- 直接建立 Cuckoo 哈希表是不可取的,这样做比普通哈希没有优势。思考空间复杂度瓶颈在哪里?
- 提示:如果使用 个 01 bit,随机哈希可达到 的错误率。
- 如何在不存储 的情况下计算 Hash 值?
- 提示:考虑优化哈希函数。
我们考虑不存储 的真实值,但是这样我们就无法在迁巢时计算第二个哈希函数的真实值。
- 考虑改变:让两个 Hash 函数不再独立!
- 令 ,
- 考虑让 。
我们将键值变为 ,如果我们仅存储 ,我们也可以通过 的方式找到另一个哈希值。
查询的时候判断 下标是否有一个 的即可。
4-Coloring Filter 相对而言知名度较低,下文将介绍其核心思想。
这个 Filter 虽然效率最高但是有一个额外限制:必须提前给定所有输入,也就是你必须知道 ,其中 表示所有询问构成的集合,你也可以理解为每个元素有一个 权值然后若干次询问权值。
思考:设计 ,考虑根据 权值建图。
我们令 表示权值为 构成的 集合, 表示权值为 构成的 集合。
我们钦定 ,否则可以交换。
考虑给图着色,让 中的所有边代表两个节点同色, 代表异色。
如果找到一个合法的图着色方案,可以 回答询问,并且必然正确。
但是冲突是难免的(当 约等于 时),理由是并查集缩点后异色边链接同一个连通块,我们在启发式合并之后尽可能找到一组冲突数量尽可能少的解,剩余的再使用 hash_table/umap。
Xor Filter 的主要思想是设计三个哈希函数 ,和指纹 并求出一组解 使得对于任意 ,都有 。
- 思考:如何构造 ?
- 提示:如果我们让 都增加 ,即 是计数器。如果存在 值恰好为 的 ,无论其他 分布,我们可以仅改变该位的 使得条件成立。
做法已经呼之欲出:类似拓扑排序,将每个 值为 的点剔除,找到他的 ,删除标记后我们将 压入栈中。
最后弹出栈时修改 使其满足条件即可。
这个算法需要离线处理,即先处理插入再回答询问。
如果仍然认为不够清晰,可以查阅伪代码:

事实上取 最优。
Ribbon Filter
Ribbon Filter 在概念上可视为 Xor Filter 的泛化。
下文中的矩阵乘法都是加乘矩阵(在 01 意义下),即 。
放个伪代码。
都是 Hash 函数。 是定长二进制整数,这样避免了 xor 时补位。记得低位补 。
我们考虑令 , 表示字符串拼接, 表示 个 。这样每次相当于看 有多少个前缀 ,记为 。
如果第 行为空,则直接插入:。
否则让 ,。
- tip:如果 归零说明构建失败(除非 ,此时说明了这个限制重复)
这样就完成了插入。同时显然我们可以快速撤销上一次插入,但无法快速删除。
- 为什么直接 xor 是对的:显然在同一行的元素 相同,又因为 定长,因此是对的。
如何查询?考虑构造矩阵 使得 ,这样查询即可快速判断:只需查询 是否成立即可。
- 思考:为什么查询是正确的?
- 解答:插入是一个消元的过程。
- 思考:如何构造 。
- 提示:考察消元后 矩阵的性质。
解答:这就是一个高斯消元。已经消出了一个上三角矩阵,因此做完了。(稍微说一下,就是倒着确定 的每一行即可)。
显然构建出 后可以立即抛弃 矩阵,因此也只是产生临时空间。
取 效果不错(哈希位数)。
RibbonFilter%E7%90%86%E8%AE%BA%E5%88%86%E6%9E%90//image-20240204164054237.png)
这张图是真实存储的 矩阵(b)。
Homogeneous Ribbon Filters
- 考虑丢弃指纹函数 会怎么样。
这样 矩阵就是一个全 矩阵。
显然有平凡解 也为全零矩阵。
但是如果使用这个 ,则 FP 率等于 。
如果我们可以随机从解集空间选择一个 ,这样 FP 率会较低。而且这完全改善了构建失败的问题。
但是这个过滤器在 较小时 FP 率较高,因为解的质量方差很大。所以在 时不要使用这个过滤器。
- 思考:给定 01(xor-and)矩阵 ,如何在所有 是全 的解 中随机选取一个?
- 解答:给每个自由变量赋值为 中的随机权值即可。
思考题:
- 给定 FP 率 和插入元素个数 ,计算最少使用的空间数量(信息论下界)。
- 计算 Bloom Filter 的 FP 率,(给定 )。
- 解释 Cuckoo Filter 中 的作用。
- 如何改造 4-Coloring Filter 使其支持在线插入和删除。
- 如何在 Homogeneous Ribbon Filters 使用 FP 率换时间?
另外,我新增了一道题目供测试。
- U640209 Filter Test
可用于测试自己的 Filter 算法。
相关推荐
评论
共 10 条评论,欢迎与作者交流。
正在加载评论...