查找连接所有节点的最短路径集

时间:2020-01-31 00:09:58

标签: algorithm search optimization graph-theory shortest-path

我在2D坐标空间中有一组点。

我想找到连接它们的路径总长度最短的一组路径。 (好的启发式解决方案,不需要很精确。)

这听起来像是旅行商的问题,但这是不同的。我不是在寻找一个将访问每个点一次且只有一次的循环。我只需要将每个点连接到至少一个其他点,以使集合中的所有点至少间接地彼此连接,并使所选连接的长度之和最小即可。因此,应尽量减少连接长度的总和。

简单的最近邻居算法(即,将每个点连接到尚未与其连接的最近邻居)不起作用,因为彼此相距较远的小群集最终将被隔离,并且您将永远结束创造周期。

3 个答案:

答案 0 :(得分:0)

如果我正确理解了您的问题,那么您正在寻找的是最小生成树(通常简称为MST)。 MST只是

的一部分路径
  • (a)连接所有点,
  • (b)这样做的总长度尽可能短,并且
  • (c)没有循环。

可以找到MST的几种著名算法,例如Prim算法和Kruskal算法-我将带您逐步了解Kruskal算法,我个人认为这是最直观的。如果有兴趣,您应该可以在线或在算法教科书中找到其他算法。


Kruskal首先按长度对各个路径进行排序。使用该列表,我们可以通过重复以下过程直到所有点/顶点都包含在树中来创建MST:

  1. 考虑列表中的最短路径。
    • 如果它将在您的MST中创建一个循环,请不要将其添加到树中(只需将其从列表中删除)。
    • 否则,将其添加到树中(并将其从列表中删除)。

最终,您将得到一棵

  • (a)连接所有点-由于已考虑到每条路径,因此必须保证,符合MST资格的每个顶点都必须在一条路径上,并且添加一条路径以到达先前未连接的顶点不能创建循环;
  • (b)具有尽可能短的总长度,这是有保证的,因为路径是按长度递增的顺序添加的;和
  • (c)没有循环-可以保证,因为算法明确避免了这种情况。

注意:

(1)在处理MST(和其他图形问题)时,我们经常用特定的名称来称呼零件:点的集合是“图形”,特定的点或节点是“顶点”,顶点之间的路径是“边缘”和边缘的长度是“权重”。

(2)Kruskal算法的运行时间为O(ElogV),其中E是路径/边的数量,V是点/顶点的数量。

(3)如果图形中有任何顶点或一组顶点与其余数据集断开连接,则最终将在“ MST林”中出现多个MST。

(4)一个图可以具有多个MST;例如在this graph中,MST的最小长度为6,这是通过以下两个MST来实现的:MST1MST2

(5)确定添加路径是否会创建循环实际上很棘手;一种实现方法是使用UnionFind数据结构,您可以使用here进行操作。

答案 1 :(得分:0)

您描述的问题听起来像克鲁斯卡尔算法:

Kruskal算法是一种最小生成树算法,可以发现 最小重量的边缘,用于连接任意两棵树 它是图论中的贪婪算法,因为它发现了一个森林 连接加权图的最小生成树增加 每一步的成本都很高。这意味着它将找到边缘的子集 形成一棵包括每个顶点的树,总重量 树中所有边缘的最小化。如果图形不是 连接,然后找到最小跨度林(最小跨度 每个已连接组件的树)。

enter image description here

Kruskal时间复杂度最坏的情况是O(E log E),这是因为我们需要对边进行排序。原始时间复杂度最差的情况是带有优先级队列的O(E log V)甚至更好,带有Fibonacci堆的O(E + V log V)。当图稀疏时,即边缘已经被排序或者我们可以在线性时间内对其进行排序时,应使用Kruskal,即图的边缘数量少,例如E = O(V)。当图密集时,即边数很多时,例如E = O(V²)

答案 2 :(得分:0)

就像其他人指出的那样,您需要投标一个MST。但是,如果要从所有对点(MST的潜在边)中进行选择,则最终需要处理大量边,这会耗尽运行时间和内存。

从任何一点开始,将其连接到最接近的邻居(不会创建周期),然后重复此步骤,直到所有内容都连接起来,这样可能会更快。

这是构建最小生成树的另一种较不常见的方法,该树在您的应用程序中应该更快。

如果您愿意,我可以(尝试)证明我刚刚提出的算法。

如果针对您的问题找到不同的解决方案,请注意,MST不一定是唯一的,可能会有多个最佳解决方案。