给定两个(大)点集,我如何有效地找到彼此最近的对?

时间:2011-02-22 10:26:52

标签: algorithm performance computational-geometry

我需要解决一个计算问题,归结为搜索两组之间相互最近的点对。问题是这样的:

在欧几里德空间中给定一组点A和一组点B,找到所有对(a,b),使得b是B中与a的最近点,a是A到b中的最近点。 / p>

A组和B组的大小大致相等,我们称之为N.对于我的特殊问题,N大约为250,000。

蛮力解决方案是将每个点与每个其他点进行比较,该点具有二次时间复杂度。有没有更有效的算法来做到这一点?

4 个答案:

答案 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),我只看到它找到一组点内的最短距离,但它应该很容易适应,要求每个配对由不同组的点组成。

  1. 根据X值对所有点进行排序。
  2. 将整个装置分成两部分。
  3. 递归每一半并选择两个最小距离(d
  4. 找到左侧最右侧的点(p)并检查p_xp_x + d之间所有点的距离,如果这些距离中的任何一个都短于{{ 1}}即返回d,否则返回d

答案 2 :(得分:-1)

旧线程,但我看到最近有一条评论。

我相信对于n维点集,可以通过找到集合差异的原点的近点来找到两个集合之间的近点。您可以通过贝尔实验室的Phillip Wolfe查找论文,并列出算法。您可以通过在集合A中取一个随机点,找到集合B中的最近点,然后找到与集合B中的点的最近点等来考虑它。 http://link.springer.com/article/10.1007%2FBF01580381

答案 3 :(得分:-2)