algorithm - 平面上所有距离最小的最近点对
问题描述
我必须从给定集合中找到平面中所有最接近的点对。
我已经成功实现了一个O(n²)
类似于这个伪代码函数的简单算法,其中set
是输入上所有点的列表,count
是输入上所有点的计数,它返回dist
找到的最小距离,并且result
是具有该距离的所有点对的列表.
function naive(Points[] set, int count)
result = []
distance = INF
for i=0 to count-1:
for j=i+1 to count:
newDistance = distance(set[i], set[j])
if newDistance < distance:
result = []
result.append({set[i], set[j]})
else if newDistance == distance:
result.append({set[i], set[j]})
return (dist, result)
该解决方案运行良好,但由于O(n²)
复杂性高,对于较大的输入非常慢。我想找到一个更快、更优化的解决方案,所以我O(n logn)
根据这篇文章使用递归分治算法实现了一个解决方案,它适用于大多数输入,但由于这种方法不会遍历所有点它失败在像这样的输入上(对的顺序和对内点的顺序无关紧要):
Input:
{A[0,0], B[1,0], C[1,1] D[0,1]}
Current (wrong) output:
{A[0,0], D[0,1]}, {B[1,0], C[1,1]}
Desired output:
{A[0,0], B[0,1]}, {A[0,0], D[0,1]}, {C[1,1], B[1,0]}, {C[1,1], D[1,0]}
而且由于它是递归的,因此对于较大的输入,堆栈很容易溢出。有什么更好的方法来解决这个问题?
谢谢
解决方案
但是您不需要将所有内容与其他所有内容进行比较。对于任何给定的点对,假设它们位于一个矩形的 [与坐标轴对齐的矩形] 对角线上,长度为d
。
- 如果斜率为正:
- 位于线左侧的任何其他点将
x = d
更远,不应考虑。 - 位于该线下方的任何其他点将
y = d
更远,不应考虑。
- 位于线左侧的任何其他点将
- 如果斜率为负:
- 位于该线右侧的任何其他点将
x = d
更远,不应考虑。 - 位于该线下方的任何其他点将
y = d
更远,不应考虑。
- 位于该线右侧的任何其他点将
可以想象类似的约束在每种情况下都会为您提供一个边界框,除非您有一个特别密集的星座,否则它应该有助于消除您内部循环中要考虑的大部分点。
你肯定需要相当多的动态编程来为大型集合提供合理的运行时间。
推荐阅读
- html - Html 项目符号未按预期出现
- python - 根据列中的值过滤行
- algorithm - 将多个值散列/编码为单个整数值的算法
- javascript - 向元素问题添加属性的surveyjs
- curl - cURL GET 返回意外结果
- bash - 有没有办法递归搜索嵌套的子目录并在每个子目录上执行命令?
- asp.net - 对表引入 FOREIGN KEY 约束可能会导致循环或多个级联路径,即使在完全删除受影响的字段后也是如此
- sql - 在 SQL 中计算另一列上的列条件的平均值
- java - 如何用 gson 处理泛型类型?
- r - 通过 aes() 使用 ggplot 和 geom_boxplot() 对矩阵的所有列进行箱线图