如何在Ruby中找到一串二进制容器的最近对(汉明距离),而不存在O^2问题?

如何在Ruby中找到一串二进制容器的最近对(汉明距离),而不存在O^2问题?,ruby,mongodb,kdtree,hamming-distance,Ruby,Mongodb,Kdtree,Hamming Distance,我有一个MongoDB,里面有大约一百万个文档。这些文档都有一个字符串,表示1和0的256位bin,如: 01101010101010101010110101010101 理想情况下,我希望查询接近二进制的匹配。这意味着,如果两个文档具有以下编号。是的,这是海明距离 这在Mongo中目前不受支持。所以,我不得不在应用层做这件事 因此,鉴于此,我试图找到一种方法来避免在文档之间进行单独的汉明距离比较。这使得做这件事的时间基本上是不可能的 我有很多羊。而且,在ruby中,似乎有一个伟大的gem(算法

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

01101010101010101010110101010101

理想情况下,我希望查询接近二进制的匹配。这意味着,如果两个文档具有以下编号。是的,这是海明距离

这在Mongo中目前不受支持。所以,我不得不在应用层做这件事

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

我有很多羊。而且,在ruby中,似乎有一个伟大的gem(算法)可以创建大量的树,但我似乎没有一个能够减少我需要进行的查询的数量

理想情况下,我希望进行100万次查询,找到几乎重复的字符串,并能够更新它们以反映这一点


任何人的想法都将受到赞赏

汉明距离定义了a,因此可以使用O(n logn)算法来定义,这是典型的分治性质

然后,您可以重复应用此选项,直到有“足够”的对为止

编辑:我现在知道维基百科实际上没有给出算法,所以


编辑2:如果距离小于
n
的地方没有对,则可以修改算法以放弃。对于汉明距离的情况:只需计算您所处的递归级别。如果您没有在任何分支中找到级别为
n
的内容,请放弃(换句话说,永远不要输入
n+1
)。如果您使用的度量值在一维上的拆分并不总是产生距离
1
,则需要调整放弃的递归级别。

这听起来像是某种算法问题。您可以尝试先比较那些具有类似数量的1或0位的数据,然后从那里开始向下搜索列表。当然,那些完全相同的人会排在首位。我不认为拥有大量的RAM在这里会有所帮助

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


根据您希望匹配的“不同”程度,您只需对源二进制值进行更改,然后进行键控搜索,以找到匹配的其他值。

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

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

您可以尝试扫描少于
N
个文档,也就是说,以获得优于线性时间的效果


one(s)
为字符串
s
1
s的数目。对于每个文档,将
ones(document.b)
存储为一个新的索引字段
ones\u count
。然后,您只能查询数量接近
one(X)
的文档,特别是
one(X)
-
d
我最终将所有文档检索到内存中。。(具有id和字符串的子集)


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

MongoDB是否有异或和“位计数”功能?如果是,您可以将每个数字与您想要的进行异或运算,并将位数设置为1,那么最低的结果将是最低的汉明距离。没有。或者,我会去的。但据我所知,它在路线图上……这取决于OP到底想做什么,这还不完全清楚。例如,有更好的方法可以找到
n
最接近的对,等等,但是是的,总的来说,你是对的,重复应用可能是错误的。嘿,其他注释去哪里了?:)还有什么评论?所以,我正试图找到接近重复的。位表示n维空间中的特征(本例中为256)。如果你有一个文本文档,并且你有一个关于如何更好地找到接近但不是完全重复的文本的建议,我洗耳恭听。-)我的回答还有另一个评论,我指的是这个。O(n log n)是找到最接近的文本对的最佳方法。这是一个明确的定义。你可能想更详细地描述你所说的“a”是什么意思“关闭复制”,如果最接近的一对没有为您剪切它。例如,比某个数字更接近的一对
n
?100个最接近的一对,等等。基本上,我正在寻找复制内容不超过5%左右的文档。所以,如果这是100%的文件,我想要所有的。但是,不太可能,大部分时间都没有重复。我现在正在做类似的事情,这似乎工作得相当好,但速度非常慢。我想问题是你不知道将所有其他的
X
进行比较,因此
n^2
的复杂性?所以,今天,我不使用simhash/minhash,但是通过使用页面上的单词本身。我抓住一个词,然后根据那些没有这些词的词进行消除。这是缓慢的方式。我希望做得比这更快,这就是我所指的。