有效地查找大集合中具有低汉明距离的二进制字符串

2023-11-24

Problem:

给定一个大(约 1 亿)无符号 32 位整数列表、一个无符号 32 位整数输入值和最大汉明距离,返回输入值的指定汉明距离内的所有列表成员。

保存列表的实际数据结构是开放的,性能要求决定了内存中的解决方案,构建数据结构的成本是次要的,查询数据结构的低成本是关键。

Example:

For a maximum Hamming Distance of 1 (values typically will be quite small)

And input: 
00001000100000000000000001111101

The values:
01001000100000000000000001111101 
00001000100000000010000001111101 

should match because there is only 1 position in which the bits are different.

11001000100000000010000001111101

should not match because 3 bit positions are different.

到目前为止我的想法:

对于汉明距离为 0 的退化情况,只需使用排序列表并对特定输入值进行二分搜索。

如果汉明距离仅为 1,我可以翻转原始输入中的每一位并重复上述 32 次。

如何有效(无需扫描整个列表)发现汉明距离 > 1 的列表成员。


问题:我们对汉明距离 d(x,y) 了解多少?

Answer:

  1. 它是非负数:d(x,y) ≥ 0
  2. 对于相同的输入,它仅为零: d(x,y) = 0 ⇔ x = y
  3. 它是对称的: d(x,y) = d(y,x)
  4. 它遵循三角不等式, d(x,z) ≤ d(x,y) + d(y,z)

问题:我们为什么关心?

Answer:因为这意味着汉明距离是metric for a 度量空间。有用于索引度量空间的算法。

  • 度量树(维基百科)
  • BK-tree(维基百科)
  • M-tree(维基百科)
  • VP-tree(维基百科)
  • 覆盖树(维基百科)

您还可以查找一般的“空间索引”算法,并了解您的空间不是欧几里得空间,而是它is一个度量空间。关于这个主题的许多书籍都介绍了使用汉明距离等度量标准的字符串索引。

脚注:如果您要比较固定宽度字符串的汉明距离,则可以通过使用汇编或处理器内在函数来获得显着的性能改进。例如,对于海湾合作委员会(manual) 你做这个:

static inline int distance(unsigned x, unsigned y)
{
    return __builtin_popcount(x^y);
}

如果您随后通知 GCC 您正在使用 SSE4a 为计算机进行编译,那么我相信这应该减少到只有几个操作码。

Edit:根据许多消息来源,这有时/通常比通常的掩码/移位/添加代码慢。基准测试表明,在我的系统上,C 版本的性能优于 GCC 的__builtin_popcount约 160%。

附录:我自己对这个问题很好奇,所以我分析了三种实现:线性搜索、BK 树和 VP 树。请注意,VP 树和 BK 树非常相似。 BK 树中节点的子节点是树的“壳”,其中包含距离树中心固定距离的点。 VP 树中的节点有两个子节点,一个子节点包含以节点中心为中心的球体内的所有点,另一个子节点包含外部的所有点。因此,您可以将 VP 节点视为具有两个非常厚的“壳”而不是许多更细的“壳”的 BK 节点。

结果是在我的 3.2 GHz PC 上捕获的,并且算法不会尝试利用多个内核(这应该很容易)。我选择的数据库大小为 100M 伪随机整数。结果是距离 1..5 的 1000 个查询的平均值,以及距离 6..10 的 100 个查询和线性搜索的平均值。

  • 数据库:100M伪随机整数
  • 测试次数:距离 1..5 为 1000 次,距离 6..10 为 100 次,线性
  • 结果:平均查询命中数(非常近似)
  • 速度:每秒查询数
  • 覆盖率:每个查询检查的数据库的平均百分比


                -- BK Tree --   -- VP Tree --   -- Linear --
Dist    Results Speed   Cov     Speed   Cov     Speed   Cov
1          0.90 3800     0.048% 4200     0.048%
2         11     300     0.68%   330     0.65%
3        130      56     3.8%     63     3.4%
4        970      18    12%       22    10%
5       5700       8.5  26%       10    22%
6       2.6e4      5.2  42%        6.0  37%
7       1.1e5      3.7  60%        4.1  54%
8       3.5e5      3.0  74%        3.2  70%
9       1.0e6      2.6  85%        2.7  82%
10      2.5e6      2.3  91%        2.4  90%
any                                             2.2     100%
  

在您的评论中,您提到:

我认为可以通过生成一堆具有不同根节点的 BK 树并将它们展开来改进 BK 树。

我认为这正是 VP 树表现(稍微)优于 BK 树的原因。 “更深”而不是“更浅”,它与更多的点进行比较,而不是与更少的点进行更细粒度的比较。我怀疑在高维空间中差异更为极端。

最后的提示:树中的叶节点应该只是线性扫描的平面整数数组。对于小集合(可能 1000 点或更少),这会更快且内存效率更高。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

有效地查找大集合中具有低汉明距离的二进制字符串 的相关文章

  • 用于插入/删除/排名/选择查询的最佳数据结构/算法

    到目前为止 我知道像AVL树和红黑树这样的自平衡BST可以在O log n 次内完成这些操作 然而 要使用这些结构 我们必须自己实现AVL树或RB树 我听说有一个算法 实现这四个操作而不使用自平衡 BST 有了我们自己定义的结构 我们就需要
  • 设置字节中的特定位

    我正在尝试设置 Java 字节变量中的位 它确实提供了适当的方法 例如 setBit i 有谁知道我如何才能实现这一点 我可以按位迭代给定的字节 if my byte 1 lt lt i 0 但是我不能将此位置设置为 1 或 0 可以吗 使
  • 如何计算两个ip之间的主机数量? C#

    我有两个ip 1 1 1 1 1 2 4 4 4 4 显然这只是一个例子 这是一个动态计算器 如果子网掩码不相关 我如何计算所述 ip 之间的主机数量 要计算 理论 IP 地址的数量 您需要将每个 IP 地址转换为其 32 位整数格式 这实
  • 十六进制数的按位异或

    我们如何在 Python 中对十六进制数进行异或 例如 我想要异或 ABCD and 12EF 答案应该是 B922 我使用了下面的代码 但它给出了错误的结果 xor two strings of different lengths def
  • 基于时间的算法评分

    我们希望创建一种评分算法 在更短的时间内获得更高的分数 在更长的时间内获得更少的分数 需要注意的是 没有实际范围 因此时间范围可以从 100 毫秒到长达 10 分钟或更长时间 点范围为 0 到 50 谢谢你的帮助 你可以简单地把它变成一个线
  • 在关键服务器上对字符串进行内存受限的外部排序,并合并和计算重复项(数十亿个文件名)

    我们的服务器生成如下文件 c521c143 2a23 42ef 89d1 557915e2323a sign xml在其日志文件夹中 第一部分是GUID 第二部分是名称模板 我想计算具有同名模板的文件的数量 例如 我们有 c521c143
  • 在 Java 中实现排列算法的技巧

    作为学校项目的一部分 我需要编写一个函数 该函数将接受整数 N 并返回数组 0 1 N 1 的每个排列的二维数组 该声明看起来像 public static int permutations int N 该算法描述于http www usn
  • 使用FFT算法计算

    给定在平面上的点 1 0 2 0 n 0 上发现的一组 n 个粒子电荷载流子 在 i 0 点发现的粒子电荷记为 Qi 作用在粒子上的力由以下公式给出 C is a Coulomb s constant 给出一个算法来计算 Fi 对于总复杂度
  • 将嵌套字典中的所有键从camelCase转换为snake_case

    我有一本类似这样的字典 firstName abc lastName xyz favoriteMovies Star Wars The lone ranger favoriteCountries country China capitalC
  • 如何高效地在屏幕上精确绘制N个点?

    这听起来是一个简单的问题 但我发现要获得良好的性能是非常棘手的 我提出的第一个算法是随机绘制点 从一组中检查是否已绘制 否则绘制 如果我们只绘制几个点 那么这种方法效果很好 但当我们接近填满屏幕时 速度会灾难性地减慢 我想出的最好的方法是构
  • 通过分布式数据库聚合作业优化网络带宽

    我有一个分布式 联合数据库 结构如下 数据库分布在三个地理位置 节点 每个节点集群有多个数据库 关系数据库是 PostgreSQL MySQL Oracle 和 MS SQL Server 的混合体 非关系数据库是 MongoDB 或 Ca
  • 检索受“rowspan”影响的行的列索引的最有效方法是什么?

    考虑下表 table thead tr th th th A th th B th th C th tr thead tbody tr th 1 th td Apples td td Oranges td td Pears td tr tb
  • 删除队列中的最后一个元素

    我需要删除队列的最后一个元素 我唯一可以使用的操作是 Peek 获取第一个元素而不删除它 Enqueue element 向队列末尾插入一个元素 Dequeue 删除第一个元素 IsEmpty true 或 false 队列是否为空 而且我
  • 如何确定算法函数的复杂度?

    您如何知道算法函数对于特定操作是否需要线性 常数 对数时间 它取决于CPU周期吗 您可以通过三种方式 至少 做到这一点 在网上查找算法 看看它是如何描述其时间复杂度的 根据输入大小 自己检查算法 查看嵌套循环和递归条件等内容 以及每个循环运
  • mysql中的按位移位

    如何在 MySQL 中进行按位移位 有没有具体的指令或者操作符 如果不是 如何最佳地模拟它 看一下按位运算符MySQL first http dev mysql com doc refman 5 0 en bit functions htm
  • 将字符串中的“奇怪”字符转换为罗马字符

    我需要能够将用户输入仅转换为 a z 罗马字符 不区分大小写 所以 我感兴趣的角色只有26个 然而 用户可以输入他们想要的任何 形式 的字符 西班牙语 n 法语 e 和德语 u 都可以包含用户输入中的重音符号 这些重音符号会被程序删除 我已
  • 0-1背包算法

    以下 0 1 背包问题是否可解 浮动 正值和 浮动 权重 可以是正数或负数 背包的 浮动 容量 gt 0 我平均有 这是一个相对简单的二进制程序 我建议用蛮力进行修剪 如果任何时候你超过了允许的重量 你不需要尝试其他物品的组合 你可以丢弃整
  • 关于在字典中查找所有有效单词的算法问题

    给定一个字典 只是一个字符串列表 您收到来自外部来源的未知数量的信件 给定字母串 您将如何列出您可以通过这些字母的任意组合组成的所有有效单词 来自字典 因此 如果您收到 applead 你应该找到apple bad pad lead等 我知
  • 包围一组点的多边形

    我有一组 S 点 2D 由 x 和 y 定义 我想找到 P 包围该组所有点的最小 含义 具有最少数量的点 多边形 P 是S 有没有已知的算法来计算这个 我在这个领域缺乏文化令人惊讶 感谢您的帮助 对于这个问题有很多算法 它被称为 最小边界框
  • 在常数空间中创建 1..N 的随机排列

    我正在寻找枚举固定空间中数字 1 N 的随机排列 这意味着我无法将所有数字存储在列表中 原因是 N 可能非常大 超过可用内存 我仍然希望能够一次遍历这样一个数字的排列 只访问每个数字一次 我知道对于某些 N 可以这样做 许多随机数生成器随机

随机推荐

  • 致命错误 C1001:编译器中发生内部错误。 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\p0io.c'

    在 Visual Studio 2013 中构建 C 解决方案时 出现以下错误 fatal error C1001 An internal error has occurred in the compiler compiler file f
  • 如何单独/单独对齐行内的子可组合项?

    我是jetpack compose的新手 我正在尝试做一件我无法实现的简单事情 我想要做的是在同一行中对齐一个组件 在本例中是一个表面 位于行的开头 另一个组件 列 位于行的末尾 怎么才能得到这个呢 我正在尝试这个 但它不起作用 Row M
  • 如何获取标题? (java,httpclient 4.X)

    当我做 Header h first getAllHeaders 返回的Header数组为空 有任何想法吗 下面是我的代码 HttpClient httpclient new DefaultHttpClient CookieStore co
  • 正则表达式:包含至少 8 位十进制数字

    我需要正则表达式来检查字符串是否包含 8 位或更多十进制数字 它可以包含任何其他内容 并且数字不必是连续的 提前致谢 编辑 用 十进制数字 替换 数字 以匹配接受的答案 d d 8 也许不是最优雅 最有效的方法 但它确实有效 基本上它将匹配
  • 如何在Spring Boot中为RestTemplate设置PropertyNamingStrategy?

    我编写了一个 SpringBoot 应用程序 它使用一个 REST API 并呈现一个 REST API 我的模型 pojo 有驼峰命名的属性 应用程序使用的 json 具有 under score 属性名称 应用程序生成的 json 具有
  • React Native 中的 AutoCompleteTextView 兼容 iOS 和 Android

    我需要在本机反应中实现 AutoCompleteTextView 问题是没有这样的内置组件 所有可用于模仿此功能的模块和库并不完全相似 主要问题是建议没有出现在视图上 如选择框 选择器 即使是这样 它与KeyboardAvoidingVie
  • 尝试使用 jasmine 和 Angular 时出现错误

    当我尝试使用时 httpBackend flush 我收到错误类型错误 browser cookies 不是函数 我找不到有关此类错误的任何信息以及任何解决方案 describe someText function var httpBack
  • jQuery 按钮单击 jqGrid 刷新仅触发一次

    我有以下 jQuery 代码 用于填充 jqGrid 第一次单击按钮时 它可以完美地发布到我的 ASP NET MVC 页面 我的问题是 任何其他点击超过第一个点击按钮时似乎都会运行 jquery 代码 但它永远不会进入 POST 页面 有
  • 为什么 WPF 支持多重绑定,但 silverlight 不支持?

    多重绑定是 WPF 中非常强大的功能 为什么 silverlight 不支持它 他们从来没有抽出时间来增加支持吗 它太大而无法适应 NET 框架 它会出现在 Silverlight 5 中吗 有谁知道答案吗 Thanks 它不受开箱即用的支
  • 在子进程 Popen 和通信后关闭所有文件的正确方法

    我们在运行 python Twisted 应用程序的 Ubuntu Linux 机器上遇到了一些可怕的 打开文件过多 问题 在我们程序的许多地方 我们都使用子进程 Popen 如下所示 Popen ifconfig iface shell
  • 错误:项目上未安装 EntityFramework 包

    我刚刚安装了 SQL Server 2008 将 ASP NET MVC 4 项目配置为部署在本地 IIS 上 并添加了到当时创建的数据库的新连接 在 sql server 2008 中 当我尝试通过启用迁移 实体框架 时启用 迁移 Con
  • 如何在格子中标记面板

    这是一个简单的问题 您肯定已经遇到过 但让我很头疼 我有一个像这样的数据框 set seed 3 mydata lt data frame var rnorm 100 20 1 temp sin sort rep c 1 10 10 sub
  • 评估业务规则引擎的标准[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心以获得指导 我们正在购买业务规则引擎
  • Jquery 选择元素 2 的位置进一步 - .next().next() 的另一种方式

    我正在寻找一种方法 如何选择一个 div 元素 该元素不是通过单击功能 选择 的元素的直接下一个元素 div siblings div div text div div div 现在我想选择 id 为 get this one 的一个 在我
  • Git 如何记录(或更可能表示)其 blob 的文件路径和名称,然后识别重命名?

    我正在尝试了解 git 设法 记住 文件名及其路径的方式 因为它只将文件内容存储在 blob 中 解释是在链接在这里Abizem 写的不错吗 这是迄今为止我见过的最好的 后续问题是 git 如何 在哪里 确定我们何时具有相似性 特别是在 移
  • Python 等价于 vector::reserve()

    我正在寻找 C vector reserve 的 Python 等效项 我不知道列表会提前有多大 但我知道它会相当大 并且我希望尽可能避免调整大小 因为列表是在深层内部循环中增长的 到目前为止 我提出的唯一解决方案与 vector rese
  • 将映射值复制到 STL 中的向量[重复]

    这个问题在这里已经有答案了 目前正在努力学习Effective STL 第 5 条建议使用范围成员函数通常比使用单元素函数更可取 我目前希望将映射中的所有值 即 我不需要键 复制到向量中 最干净的方法是什么 你可能可以使用std trans
  • __stdcall的含义和用法是什么?

    我遇到过 stdcall这些天很多 MSDN 没有非常清楚地解释它的真正含义 何时以及为什么应该使用它 如果有的话 如果有人能提供解释 最好是举一两个例子 我将不胜感激 这个答案涵盖了 32 位模式 Windows x64 仅使用 2 个约
  • 在 JDBC 中处理 DATETIME 值 0000-00-00 00:00:00

    如果我尝试这样做 我会得到一个例外 见下文 resultset getString add date 对于包含 DATETIME 值 0000 00 00 00 00 00 DATETIME 的准空值 的 MySQL 数据库的 JDBC 连
  • 有效地查找大集合中具有低汉明距离的二进制字符串

    Problem 给定一个大 约 1 亿 无符号 32 位整数列表 一个无符号 32 位整数输入值和最大汉明距离 返回输入值的指定汉明距离内的所有列表成员 保存列表的实际数据结构是开放的 性能要求决定了内存中的解决方案 构建数据结构的成本是次