Algorithm 平面中具有最小距离的所有最近点对

Algorithm 平面中具有最小距离的所有最近点对,algorithm,recursion,optimization,Algorithm,Recursion,Optimization,我必须从给定的集合中找到平面上所有最近的点对 我已经成功地实现了一个简单的算法O(n²)类似于这个伪代码函数,其中set是输入上所有点的列表,count是输入上所有点的计数,它返回dist,这是找到的最小距离,result是具有该距离的所有点对的列表 函数初始值(点[]集,整数计数) 结果=[] 距离=INF 对于i=0到计数-1: 对于j=i+1进行计数: newDistance=距离(集合[i],集合[j]) 如果newDistance根据点如何分布,最好的解决方案可能不同。一种方法是将正方

我必须从给定的集合中找到平面上所有最近的点对

我已经成功地实现了一个简单的算法
O(n²)
类似于这个伪代码函数,其中
set
是输入上所有点的列表,
count
是输入上所有点的计数,它返回
dist
,这是找到的最小距离,
result
是具有该距离的所有点对的列表

函数初始值(点[]集,整数计数)
结果=[]
距离=INF
对于i=0到计数-1:
对于j=i+1进行计数:
newDistance=距离(集合[i],集合[j])
如果newDistance<距离:
结果=[]
追加({set[i],set[j]})
否则,如果newDistance==距离:
追加({set[i],set[j]})
返回(距离、结果)
此解决方案运行良好,但由于高
O(n²)
复杂性,对于较大的输入速度非常慢。我想找到一个更快、优化的解决方案,因此我使用基于的递归分治算法实现了一个
O(n logn)
解决方案,该算法适用于大多数输入,但由于这种方法不会迭代所有点,因此在这种输入上失败(对的顺序和对内点的顺序无关紧要):

输入:
{A[0,0],B[1,0],C[1,1]D[0,1]}
电流(错误)输出:
{A[0,0],D[0,1]},{B[1,0],C[1,1]}
期望输出:
{A[0,0],B[0,1]},{A[0,0],D[0,1]},{C[1,1],B[1,0]},{C[1,1],D[1,0]}
而且由于它是递归的,对于较大的输入,堆栈很容易溢出。有什么更好的方法来解决这个问题


谢谢

< p>根据点如何分布,最好的解决方案可能不同。一种方法是将正方形划分成许多更小的子方块,选择每个子方块平均有大约1个点。然后,将关联点与相应的子方块。最后,对于任何给定的点,你只需要考虑最近的子空间。ares找到最近的邻居(通过检查可能包含较近点的所有子正方形来确认nearesr状态)。

关于第一个问题。我可能错了,但我可以给你一些提示

假设你有1000个点。你用250个点把它们分成4组,然后用所有的组对组成500个元素集。总共6个。在这种情况下,任何一对点都会被一半(组对)覆盖。不要忘记保留所有的最小值,而不是每次递归迭代都保留一个最小值

也因为每次分割一个集合都必须进行分组,所以这里增加了复杂性,所以你可能会考虑“慢”<代码> O(n席)< /> >小集的算法,所以实际的解决方案将是<>代码> O(n log n)< /> >和<代码> o(n)


对于第二个问题,我只能建议避免递归的一般方法。如果您有足够的内存,请使用动态规划,即将所有以前的结果都保存在内存中,直到用所有可能的参数填充数组为止。因此,不进行递归调用,您只需从数组中获取值。当然,您必须启动增益,直到数组中没有空值为止。每个任务的实现都不同,因此您必须考虑如何实现此任务。

但您不需要将所有内容与其他内容进行比较。对于任何给定的点对,假设它们位于矩形的[矩形与坐标轴对齐]对角线长度
d

  • 如果坡度为正:
    • 线
      x=d
      左侧的任何其他点将更远,不应考虑
    • 位于线
      y=d
      下方的任何其他点将更远,不应予以考虑
  • 如果坡度为负:
    • 线右侧的任何其他点
      x=d
      将更远,不应考虑
    • 位于线
      y=d
      下方的任何其他点将更远,不应予以考虑
类似的约束可以被想象成在每一种情况下给你一个边界框,除非你有一个特别密集的星座,否则它可以用来消除在你的内循环中要考虑的大比例的点。 在这里,您肯定需要相当多的动态编程来为大型集合提供合理的运行时