我有一组点,需要知道哪一个点与其他任何点之间的欧氏距离最远。
为了得到这一点,我可以获得所有积分的所有距离,取平均值,并将最大平均值作为最远点。
有没有更快的方法来找出这一点?
答案 0 :(得分:6)
正如其他人所建议的那样,为所有N点建立KD-tree。这将花费O(N logN)
时间。对于每个点找到最近的邻居,单个点可以在O(logN)
中完成。对于所有N
点,您可以通过在O(N logN)
中找到此集合的最小值来找到最孤立的点。
此外,您现在可以使用方便的KD树进行其他基于距离的查询。
答案 1 :(得分:1)
我没有看到比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;
优化机会:
你可以在内循环中提前退出。如果nearest becomes < nearest_of_most_isolated
,那么你可以突破内循环,因为你已经可以排除这一点。这是一个非常显着的进步。
您可以记住距离计算,但这需要O(n ^ 2)个记忆。通过聪明,你可以通过利用对称性将其切成两半(距离A-> B的距离与距离B-> A的距离相同)。但距离计算非常简单,因此可能不值得努力。
由于您只是比较相对距离,因此可以使用距离的平方,这些距离的计算速度比实际距离快。这进一步降低了#2的价值。
如果您有多个处理器或核心,则可以通过在候选城市的 n 子集中运行算法的 n 实例来对此进行并行化(内部循环)必须仍然打击他们所有)然后对个别结果进行后续传递。如果点数非常大,这可能是值得的。