我在二维网格上有很多点。我想将点分组成对,同时最小化对的点之间欧氏距离的总和。
示例:
Given the points:
p1: (1,1)
p2: (5,5)
p3: (1,3)
p4: (6,6)
Best solution:
pair1 = (p1,p3), distance = 2
pair2 = (p2,p4), distance = 1
Minimized total distance: 1+2 = 3
我怀疑使用Hungarian Algorithm的变种可以解决此问题?!
解决问题的最快方法是什么?
(小评论:我总是应该少于12分。)
答案 0 :(得分:4)
您尝试解决的问题类似于通过完全连接(网状)网络的最短路径,您不允许多次访问每个顶点/节点,并且您不必关心连接最小的对。
使用graph theory,metric spaces中的技术以及计算几何中的其他结果时,此问题可以解决。
此问题与Closest pair of points problem上的wiki文章类似,本文提供了有关Voroni diagrams和Delaunay triangulation的一些有用见解,以及使用递归{{ 3}}算法来解决问题。
请注意,求解最近的一对点不是解决方案,因为你可以在一行中有四个点(A,B,C,D),其中d(B,C)最小,但是你也会得d(A,D),总和大于d(A,B)和d(C,D)。
这个Divide and Conquer解释了如何找到两点之间的最短距离,并且有一个有用的提示,可以在比较距离时跳过计算平方根。答案建议使用分而治之的方法(线性),但观察到分割X和Y坐标可能会更恰当地分割。
此stackoverflow question解决了类似的问题,建议使用math stackexchange question,Prim's algorithm,或者注意这是Kruskal's algorithm的特殊情况,即{{3} }}
我的方法是使用贪心算法计算最小生成树来解决您的问题(配对最近的点),然后从生成树中删除1/2边缘(留下不连续的对)。可能使用贪婪算法的第二个(变体)。
答案 1 :(得分:1)
对于12个或更少的点(如评论中指出的约10000或更少),可能很少配对,您可以通过强力检查所有配对,即使使用此解决方案,您也可以解决每秒约10000个问题现代个人电脑上的点数或更少。如果你想要一个更快的解决方案,你可以为每个点枚举最近的邻居,然后只检查每个点使用哪个最近邻居的最小配对。在最糟糕的情况下,我不认为这会加速,但是例如如果你的12点来自6对非常接近的点(非配对点很远)那么你会很快找到解决方案,因为与最近邻居的最小配对将使每个点与其第一个最近邻居匹配。