如何在没有O ^ 2问题的Ruby中找到一串二进制二进制文件的最接近对(汉明距离)?

时间:2012-01-04 21:06:55

标签: ruby mongodb kdtree hamming-distance

我有一个包含大约100万个文档的MongoDB。这些文档都有一个字符串,表示一个1位和0位的256位bin,如:

0110101010101010110101010101

理想情况下,我想查询近二进制匹配。这意味着,如果两个文件具有以下数字。是的,这是汉明距离。

Mongo目前不支持此功能。所以,我不得不在应用程序层中这样做。

所以,鉴于此,我试图找到一种方法来避免在文档之间进行单独的汉明距离比较。这使得时间基本上不可能完成。

我有很多内存。并且,在ruby中,似乎有一个伟大的宝石(算法)可以创建许多树,我似乎没有任何工作(还)可以减少我需要做的查询数量。

理想情况下,我想制作100万个查询,找到接近重复的字符串,并能够更新它们以反映这一点。

任何人的想法将不胜感激。

4 个答案:

答案 0 :(得分:6)

我最终将所有文档检索到内存中..(带有id和字符串的子集)。

然后,我使用BK Tree来比较字符串。

答案 1 :(得分:4)

汉明距离定义metric space,因此您可以使用O(n log n)算法find the closest pair of points,这是典型的分而治之的性质。

然后,您可以反复应用此选项,直到您拥有“足够”对。

编辑:我现在看到维基百科实际上没有给出算法,所以here is one description

编辑2:如果距离小于n,则可以修改算法以放弃。对于汉明距离的情况:简单地计算你所在的递归水平。如果你没有在任何分支的n级找到某些东西,那么放弃(换句话说,永远不要输入{{1} })。如果您使用的指标在一个维度上拆分并不总是产生n + 1的距离,则需要调整放弃的递归级别。

答案 2 :(得分:2)

据我所知,您有一个输入字符串X,并且您想要在数据库中查询包含字符串字段b的文档,以便X和{之间的汉明距离{1}}小于某个小数字document.b

您可以在线性时间中执行此操作,只需扫描所有d = 1M文档并计算距离(每个文档需要较少的固定时间)。由于您只需要距离小于N的文档,因此您可以在d个不匹配的字符后放弃比较;你只需比较所有256个字符,如果大多数匹配的话。

您可以尝试扫描少于d个文档,也就是说,优于线性时间

N为字符串ones(s)中的1个数。对于每个文档,将s存储为新的索引字段ones(document.b)。然后,您只能查询其中一些数量足够接近ones_count的文档,具体而言,ones(X) - ones(X)< = d< = document.ones_count + ones(X)。 Mongo索引应该在这里开始。

如果你想在集合中找到所有足够接近的对,请参阅@ Philippe的回答。

答案 3 :(得分:1)

这听起来像是某种算法问题。您可以尝试首先比较具有相似数量的1或0位的那些,然后从那里向下查看列表。那些相同的东西当然会名列前茅。我不认为有大量的RAM会对此有所帮助。

您也可以尝试使用较小的块。而不是处理256位序列,你可以将其视为32个8位序列吗? 16个16位序列?此时,您可以计算查找表中的差异,并将其用作一种索引。

根据您想要匹配的“不同”的方式,您可以只更改源二进制值的更改并执行键控搜索以查找匹配的其他值。