【问题标题】:Most isolated point on 2d map - algorithm二维地图上最孤立的点 - 算法
【发布时间】:2013-12-13 05:14:54
【问题描述】:

我有一组点,需要知道哪个点与任何其他点的欧几里得距离最远。

为了得到这个点,我把我所有点的每一个距离,做一个平均,取最大的平均作为最远点。

有没有更快的方法来找出那个点?

【问题讨论】:

  • 您是否已经确定了“孤立”的定义并想要一个更快的算法?还是您在问“最孤立”是否有更好/更快的定义?
  • 为了提高性能:确保2点之间的距离计算一次,因为dist(p1,p2) = dist(p2,p1)
  • 您应该在问题中澄清这一点。听起来您想要平均到 所有 点的距离以测量“隔离”,这与“最远最近的邻居”不同。
  • 也许建立一个你的点的k-d树。您可以使用它来找到每个点的最近邻居,并取所有这些中最大的。你应该得到一个 O(log n) 而不是 O(n*n) 算法。
  • 哦,另外,如果你的意思是欧几里得距离(作为距离的度量),使用距离的平方就足够了。

标签: algorithm computational-geometry


【解决方案1】:

正如其他人建议的那样,为所有 N 个点构建一个 KD-tree。这将花费O(N logN) 时间。对于每个点,找到最近的邻居,对于单个点,可以在O(logN) 中完成。对于所有N 点,您可以通过在O(N logN) 中找到该集合的最小值来找到最孤立的点。

此外,您现在有一个方便的 KD-tree 用于其他基于距离的查询。

【讨论】:

  • 我的理解是在 O(n log n) 时间内构建一个 k-d 树是很棘手的,而且大多数实现实际上都是 O(n log^2 n)。对于随机分布的点,最近邻查找通常为 O(log n)。如果分布不是随机的,情况可能会更糟。您还必须使用经过调整的算法版本,否则每个点的最近邻查找只会返回相同的点。如果您对树有额外的查询,这肯定是一个胜利。如果没有,您可能想先尝试更简单的复杂度更高的算法。
  • @Hooked "注意 x 不必是 P 中的一个预先存在的点" Kd 树将如何工作是该点已经存在。它返回相同的点。
【解决方案2】:

我没有看到比 O(n^2) 做得更好的方法。如果有办法通过将点预处理为空间分区结构来做得更好,我不会感到惊讶,但这些通常只有在您进行大量计算时才有用。

但即使使用 O(n^2),您也可以进行一些优化以将常数因子减小到足以在几秒钟内检查 100,000 个点。

基本算法:

nearest_of_most_isolated = 0
for every point A {
  nearest = infinity
  for every point B != A
    nearest = min(nearest, distance(A, B));
  if (nearest > nearest_of_most_isolated) {
    nearest_of_most_isolated = nearest
    most_isolated = A
  }
}
return most_isolated;

优化机会:

  1. 您可以在内部循环中提前退出。如果nearest becomes < nearest_of_most_isolated,那么您可以跳出内部循环,因为您已经可以排除这一点。这是一个非常显着的改进。

  2. 您可以记住距离计算,但这需要 O(n^2) 内存。通过聪明,您可以利用对称性将其减半(从 A->B 的距离与从 B->A 的距离相同)。但是距离计算很简单,所以可能不值得。

  3. 由于您只是比较相对距离,因此您可以使用距离的平方,这比实际距离的计算速度更快。这进一步降低了 #2 的价值。

  4. 如果您有多个处理器或内核,您可以通过在候选城市的 n 个子集(内部循环仍然必须全部击中),然后对单个结果进行后续传递。如果点数非常多,这可能是值得的。

【讨论】:

  • @VaughnCato 已经为该问题提供了带有 kDtrees 的 O(nlogn) 解决方案,其中与最近邻居的距离最大化。
猜你喜欢
  • 2021-08-14
  • 1970-01-01
  • 1970-01-01
  • 2015-05-26
  • 1970-01-01
  • 1970-01-01
  • 2018-02-26
相关资源
最近更新 更多