【问题标题】:Algorithm to find points that are furthest apart -- better than O(n^2)?找到相距最远的点的算法——比 O(n^2) 更好?
【发布时间】:2011-06-29 16:52:07
【问题描述】:

在我的程序中,我有一组点。出于重新缩放的目的,我正在搜索相距最远的两个节点,然后计算一个因子,将所有坐标相乘以使最大距离等于我定义的某个预定义的距离。

但是,我用来找到相距最远的两个点的算法对于大量点集是有问题的,因为它是O(n^2);伪代码(已计算的距离被跳过):

 for each point in points:
     for each other point in points:
         if distance between point and other point > max
             max = distance between point and other point

有更快的方法吗?

【问题讨论】:

  • 看到John Feminella's excellent answer这个类似的问题。对于平均情况,您应该得到 O(n log n)。
  • 尽管如此,它仍然是 n^2 最坏的情况,而且很容易找到比幼稚代码更糟糕的实例。因此,如果您知道您的积分是“随机”分布的,那很好,但如果它们是对抗性选择的,那就不好了。
  • 是的。我同意 Martin 的观点,集群是一个很大的帮助,我在许多地理感知应用程序中为此使用了 geohashing。
  • 凸包可以在 O(n ln n) 最坏情况下计算。通过在凸包中搜索对映点来找到集合的直径需要 O(n) 时间。更多细节在我的回答中

标签: algorithm math language-agnostic geometry


【解决方案1】:

如果您只需要比例而不是确切的点,您可以在 O(n) 时间内以一定的误差范围执行此操作。想想制作边界框的简单案例。从所有点计算最小 x 值,最大 x,最小 y 和最大 y。这四个数字为您提供了一个围绕点的最大边界框,最大误差为 1 - (1/sqrt(2)) 约 30%。您可以通过在正方形中添加更多边来减少这种情况。想想八边形的情况。要计算其他边的最小值和最大值,您必须旋转坐标系。

错误与运行时间像这样分解。

形状 - 运行时间 - 最大误差

  • 正方形 - 2N - 30%
  • 八角形 - 4N - 16%
  • 16 面 - 8N - 4%
  • 32 面 - 16N - 1%

这是我想出的最大误差公式。

angle = 180 / sides
max_error = (1 / cos angle) - cos angle

让我知道我是否应该添加一个图表来解释这一点。

【讨论】:

  • 好主意!这些点实际上是 3D 的,但原理也适用。我不太在意错误(它只是为了更容易看到,基本上),所以立方体将简单快速地实现。谢谢!
【解决方案2】:

以下内容可能有助于更清楚地说明平均情况线性时间算法(针对有限集的直径),以及对比多维和平面几何问题。

1983 年,Megiddo 为the smallest enclosing circle(或更高维度的球体)提供了确定性线性时间算法。

在一般情况下,封闭圆的边界上有两个或三个点,因此一旦知道边界圆,就可以在恒定时间内“平均”找到相距最远的两个点。在更高维度中,球体边界上所需的一般位置点的数量会增加(维度 D 为 D+1 个点),实际上计算一对点之间的距离的成本随着维度线性增加。

位于边界圆或球体上的点的子集也在线性时间内找到。在理论上的最坏情况下,所有点都将位于边界圆或球体上,但这至少比仅将所有点都放在凸包上更严格。如果球体上的点是独立扰动的,例如沿径向线,则以概率 1 确保大致位置,并且可以从修改后的封闭球体上的 D+1 个点找到近似直径。这种随机逼近对维度具有二次依赖性,但在点数上只有线性复杂度。

如果位于边界圆上的点是“排序的”(当然是循环的),则可以在线性时间内找到相距最远的点,这取决于圆的“单峰性”(意味着距固定点的距离)点单调上升直到对极然后下降)to amortize the cost of computing distances。不幸的是,排序会引入一个时间复杂度为 O(n log n) 的步骤,这被证明是平面情况下精确确定性方法的最坏情况最优。

2001 年,Ramos 成功地展示了an O(n log n) deterministic algorithm for three-dimensional sets,但该技术涉及的非常多,以至于实现可能是impractical or slower than brute force all-pairs search up to very large datasets

对于更高维度,许多作者已经考虑过randomized 或近似算法。请参阅Piotr Indyk's thesis (2000) 了解对于各种邻近问题只有多项式依赖于维度的近似 方法。

【讨论】:

    【解决方案3】:

    正如this answer 中提到的,您正在寻找 N 点集合的“直径”,这是计算几何中的一个众所周知的问题。基本上有两个步骤:

    1. 找到点的凸包。 Algorithms exist 是 O(N ln N),最坏的情况。在实践中,QuickHull 通常是一个快速的选择,尽管可能是 O(N^2) 最坏的情况。 QHull implementation 方便从命令行调用。 CGAL 库提供了一个C++ implementation

    2. 凸包上的对映点对是最远点的候选对象。可以使用类似Rotating calipers 的算法在 O(N) 时间内搜索对映点。

    这个问题可以概括为“最远的对”问题:对于每个i,找到最远的点j---我们现在正在寻找N对的点。该解决方案再次使用凸包,但现在可以使用matrix searching 算法完成第二部分。

    【讨论】:

      【解决方案4】:

      并非如此 - 一种常见的方法是将点分组到集群中,然后存储集群之间的距离。

      这样,如果你已经确定澳大利亚离巴黎更远,你就不需要检查纽约的某个房子是否离巴黎最远

      【讨论】:

        【解决方案5】:

        AB 的距离与BA 的距离相同。您可以通过这种方式轻松修改算法以消除一半的计算。它仍然是O(n^2),但速度会提高一倍。

        也就是说,不是计算距离矩阵P x P的所有非对角元素:

        P = {A, B, C, D, ...}
        
          + A + B + C + D + ...
        A |   | * | * | * | ...
        B | * |   | * | * | ...
        C | * | * |   | * | ...
        D | * | * | * |   | ...
          |   |   |   |   |
        

        你可以计算上面的三角形:

          + A + B + C + D + ...
        A |   | * | * | * | ...
        B |   |   | * | * | ...
        C |   |   |   | * | ...
        D |   |   |   |   | ...
          |   |   |   |   |
        

        或下三角:

          + A + B + C + D + ...
        A |   |   |   |   | ...
        B | * |   |   |   | ...
        C | * | * |   |   | ...
        D | * | * | * |   | ...
          |   |   |   |   |
        

        【讨论】:

        • 其实我已经在这样做了,但为了简单起见,我没有把它放在伪代码中。
        【解决方案6】:

        如果您经常执行此查询但点变化不大,您可以执行可以加快查询速度的预计算。

        每个点都可以存储离它最远的点,如果新点更远,则重新检查每个添加的点。

        当您查询时,您只需遍历所有点并查看它们的缓存点。

        对于新的点条目,您最终会得到 O(n),对于相距最远的查询,您会得到 O(n)。

        【讨论】:

          【解决方案7】:

          我不确定将这些点放入 spatial index 并查询它是否会导致 O(n log n) 算法。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-23
            • 1970-01-01
            • 1970-01-01
            • 2023-04-10
            • 2023-03-25
            • 1970-01-01
            • 2014-06-13
            • 1970-01-01
            相关资源
            最近更新 更多