Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/search/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 查找连接所有节点的最短路径集_Algorithm_Search_Optimization_Graph Theory_Shortest Path - Fatal编程技术网

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

Algorithm 查找连接所有节点的最短路径集,algorithm,search,optimization,graph-theory,shortest-path,Algorithm,Search,Optimization,Graph Theory,Shortest Path,我在二维坐标空间中有一组点 我想找到一组路径,它们以最短的总长度连接在一起。启发式解决方案好的,不需要精确 这听起来像是旅行推销员的问题,但情况不同。我不是在寻找一个只访问一次每个点的循环。我只需要将每个点连接到至少一个其他点,这样集合中的所有点至少间接地彼此连接,所选连接的长度之和最小化。因此,最小化连接长度之和应该是非循环的 一个简单的最近邻算法,即将每个点连接到其尚未连接到的最近邻点,是不起作用的,因为彼此相距较远的小簇最终将被隔离,并且您将始终创建循环。如果我正确理解您的问题,你要找的是

我在二维坐标空间中有一组点

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

这听起来像是旅行推销员的问题,但情况不同。我不是在寻找一个只访问一次每个点的循环。我只需要将每个点连接到至少一个其他点,这样集合中的所有点至少间接地彼此连接,所选连接的长度之和最小化。因此,最小化连接长度之和应该是非循环的


一个简单的最近邻算法,即将每个点连接到其尚未连接到的最近邻点,是不起作用的,因为彼此相距较远的小簇最终将被隔离,并且您将始终创建循环。

如果我正确理解您的问题,你要找的是一个最小生成树,通常缩写为MST。MST只是路径的子集

a连接所有点, b的总长度尽可能最小,并且 c没有循环。 有几种著名的算法可以找到MST,比如Prim的算法和Kruskal的算法——我将带你参观Kruskal的算法,我个人认为这是最直观的。如果你感兴趣,你应该能够在网上或算法教科书中找到其他算法

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

考虑列表中的最短路径。 如果它会在你的MST中创建一个循环,不要将其添加到树中,只需将其从列表中删除即可。 否则,将其添加到树中并从列表中删除。 最终,你会得到一棵

a连接所有点-由于考虑了每条路径,因此符合MST条件的每个顶点必须位于一条路径上,并且添加一条路径以到达先前未连接的顶点不能创建循环; b具有可能的最低总长度-保证,因为路径是按升序长度添加的;和 c没有循环保证,因为算法明确避免了这一点。 注:

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

2 Kruskal的算法在OElogV时间内运行,其中E是路径/边的数量,V是点/顶点的数量

3如果图形中有任何顶点或顶点集与数据集的其余部分断开连接,则最终会在“MST林”中出现多个MST

4一个图可以有多个MST;例如,在中,MST的最小长度为6-这由以下两个MST实现:


5确定添加路径是否会创建循环实际上是一件棘手的事情;其中一种方法是使用UnionFind数据结构,您可以使用它

您描述的问题听起来像Kruskal的算法:

Kruskal算法是一种最小生成树算法 连接任意两棵树的可能最小权重的边 这是图论中的一个贪婪算法,因为它能找到一个 连通加权图的最小生成树 每个步骤的成本弧。这意味着它会找到边的子集 这形成了一个包含每个顶点的树,其中总权重 将最小化树中所有边的最大值。如果图形不是 连接,然后它找到一个最小生成林一个最小生成林 每个连接组件的树


Kruskal时间复杂度最坏的情况是OE log E,这是因为我们需要对边进行排序。基本时间复杂度最坏的情况是使用优先级队列的OE log V,甚至更好,使用Fibonacci堆的OE+V log V。当图形稀疏时,即当边已经排序或我们可以在线性时间内对它们排序时,应使用Kruskal,即少量边,如e=OV。当图是稠密的,即边的数目很高时,我们应该使用Prim,如e=OV²

如其他人所指出的,您需要建立一个MST。但是,如果您想从MST的所有点对中选择潜在的边,那么最终将需要处理大量的边,这将破坏运行时和内存

从任何一点开始,将其连接到不产生循环的最近邻点,并重复此步骤,直到所有东西都连接起来,可能会更快

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

如果你愿意,我可以试着 证明我刚才提出的算法


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

听起来您在描述MST问题。啊,是的,听起来像。可能还相关:Steiner树问题多少点?