我需要解决一个计算问题,归结为搜索两组之间相互最近的点对。问题是这样的:
在欧几里德空间中给定一组点A和一组点B,找到所有对(a,b),使得b是B中与a的最近点,a是A到b中的最近点。 / p>
A组和B组的大小大致相等,我们称之为N.对于我的特殊问题,N大约为250,000。
蛮力解决方案是将每个点与每个其他点进行比较,该点具有二次时间复杂度。有没有更有效的算法来做到这一点?
答案 0 :(得分:10)
我发现在必须进行最近邻搜索时非常有用的数据结构是 k d树。 Wikipedia有一个很好的概述,this是一个非常深入的讨论,如果你实现自己的算法(虽然一个库可能已经存在 - 你没有提到你的语言'重新使用)。关于 k d树的最重要的事情是它允许在O(log N)时间内执行最近的neghbour搜索。
通过这种方式,你可以在O(N log N)时间内产生两个列表--A的成员和他们在B中的最近邻居以及B的成员和他们在A中的最近邻居。然后,您可以比较列表以查看哪些对匹配。天真地做,那是O(N ^ 2),尽管你可以想出一种更快的方法。
[编辑]你让我思考;这是我的第二个想法:
for(a in A)
b := nearest(B, a)
if a = nearest(A, b)
add (a, b) to results
end if
end for
function nearest(X, y)
return nearest member of set X to point y
end function
据我估算,那是O(N log N)。
答案 1 :(得分:3)
很抱歉拿起一个相当老的帖子,但我只想添加一个我在教科书中找到的算法设计类的解决方案:
有一种分而治之(思考合并排序)的方法来解决这个问题应该是O(n logn)
,我只看到它找到一组点内的最短距离,但它应该很容易适应,要求每个配对由不同组的点组成。
d
)p
)并检查p_x
和p_x + d
之间所有点的距离,如果这些距离中的任何一个都短于{{ 1}}即返回d
,否则返回d
。答案 2 :(得分:-1)
旧线程,但我看到最近有一条评论。
我相信对于n维点集,可以通过找到集合差异的原点的近点来找到两个集合之间的近点。您可以通过贝尔实验室的Phillip Wolfe查找论文,并列出算法。您可以通过在集合A中取一个随机点,找到集合B中的最近点,然后找到与集合B中的点的最近点等来考虑它。 http://link.springer.com/article/10.1007%2FBF01580381
答案 3 :(得分:-2)