一条线上最近的一对点

时间:2013-09-04 12:09:58

标签: algorithm computational-geometry time-complexity divide-and-conquer closest-points

我有两组2D点,通过平面中的一条线相互分开。我想有效地找到一对点,​​由每组中的一个点组成,它们之间的距离最小。 Radu Litiu有一篇非常方便的论文,两个分开的点集最近对,但它使用L1(曼哈顿)距离度量而不是欧几里德距离。

有没有人知道类似的算法与欧几里德距离有效吗?

我可以看到标准鸿沟的扩展&征服最近对算法 - 将两组划分为垂直于原始分裂线的中线,在两侧递归,然后寻找由中位数每侧的一个点组成的更接近的对。如果距离递归步骤的最小距离是d,那么中位数一侧的点的伴随必须位于维度为2d * d的方框内。但与原始算法不同,我看不到任何限制该框内点数的方法,因此算法整体上变为O(m * n)。

有什么想法吗?

5 个答案:

答案 0 :(得分:2)

对于一组中的每个点,在另一组中找到最近点。在这样做时,只保留一对点之间的距离最小。这减少了给另一个问题:"Algorithm to find for all points in set A the nearest neighbor in set B",可以使用扫描线算法在(1)一组点和(2)Voronoi图解决其他集合。

算法复杂度为O((M + N)log M)。并且该算法不使用两组点彼此分开的事实。

答案 1 :(得分:2)

Evgeny's answer有效,但没有库支持需要付出很多努力:计算完整的Voronoi图和额外的扫描线算法。按顺序枚举Voronoi单元格与分离线相交的点的两组点更容易,然后通过线性时间合并步骤测试其单元格相交的所有点对。

要计算Voronoi图的所需片段,假设x轴是分离线。通过x坐标对集合中的点进行排序,丢弃具有大于等于x的其他点的y的点。开始按x坐标顺序扫描点,将它们推入堆栈。在推动之间,如果堆栈具有至少三个点,比如p,q,r,最近推动r,则测试在二等分qr之后,二等分pq的线是否与分离线相交。如果是这样,丢弃q,并用新的前三个重复测试。原始ASCII艺术:

Case 1: retain q

------1-2-------------- separating line
     /  |
  p /   |
   \    |
    q-------r

Case 2: discard q

--2---1---------------- separating line
   \ /
  p X r
   \ /
    q

答案 2 :(得分:0)

解决此问题的典型方法是扫描线算法。假设您有一个包含所有点的坐标系以及将点与不同集分开的线。现在想象一条垂直于分离线的线,从一个点到另一个点按升序跳跃。为方便起见,您可以旋转和平移点集和分离线,使分离线等于x轴。扫描线现在与y轴平行。

使用扫描线从一个点跳到另一个点,跟踪不同组中两点的最短距离。如果前几个点都来自同一个集合,那么很容易找到一个公式,告诉你哪一个你必须要记住,直到你从另一个集合中找到第一个点。

假设您总共有N个积分。您必须对O中的所有点进行排序(N * log(N))。扫描线算法本身将在O(N)中运行。

答案 3 :(得分:0)

那么这个:

  1. 确定任何一方在哪一方:

    • 让P成为你的分数(P0,...... Pi,...... Pn)
    • 让A,B成为分隔线起点
    • so:side(Pi)=(B-A)的符号。(Pi-A))
    • 这是基于一个简单的事实,即标量向量乘法(点积)的符号取决于点的顺序(更多信息请参见三角形/多边形缠绕规则)
  2. 找到任何(Pi,Pj)的最小距离,其中(Pi)!= side(pj)

    • 所以首先计算所有点的所有边O(N)
    • 然后循环遍历所有Pi并在其中循环
    • 遍历所有Pj并搜索最小距离。
    • 如果Pi和Pj组成aprox。等于大小的是O((N / 2)^ 2)
  3. 您可以通过“排序”来自AB的“距离”点Pi,Pj进一步优化搜索

    • 你可以使用另一个点积来做到这一点,这次是(B-A)
    • 使用垂直向量来说(C-A)
    • 丢弃Pi2中的所有点(以及类似的Pj2)
    • 式中((B-A)。(P(i1)-A))接近((B-A)。(P(i2)-A))
    • 和|((C-A)。(P(i1)-A))| << |((C-A)(P(3-12)-A)。)|
    • beacuese表示Pi2落后于Pi1(来自AB)
    • 并且接近于接近Pi1
    • 的AB的法线
    • 此优化后的复杂性很大程度上取决于数据集。
    • 应为O(N +(Ni * Nj))其中Ni / Nj为剩余点数Pi / Pj
    • 你需要2N点数产品,Ni * Nj距离比较(不要sq sq)

答案 4 :(得分:0)

(我不确定这是否与大卫的想法有任何相似之处......我现在只是在登录发表我的想法后才看到它。)为了论证,让我们说我们改变了一切所以划分line是x轴,并按x坐标对我们的点进行排序。假设N不是太大,如果我们沿着x轴扫描(也就是说,遍历我们的a和b的排序列表),我们可以记录总体最小值和两个传递点列表。扫描中的当前点针对来自另一个列表的每个传递点进行测试,而从列表中的点到(我们的扫描的x坐标,0)的距离大于或等于整体最小值。在下面的示例中,当到达b2时,我们可以停止在a2进行测试。

        scan ->                 
      Y                           
      |         a2         
      |                   
      |   a1           a3   
X--------------------------
      |     b1           b3
      |             b2