【发布时间】:2012-10-02 18:56:47
【问题描述】:
我有一个无向和未加权图的某个节点子集。我正在尝试确定所有这些节点之间是否存在路径,如果存在,最短路径是什么,其中包含不在节点子集中的最少节点。
我一直在想办法修改最小生成树算法来实现这一点,但到目前为止我还没有想出一个可行的解决方案。
有没有好的方法可以做到这一点,或者这是对已知算法的描述?
【问题讨论】:
我有一个无向和未加权图的某个节点子集。我正在尝试确定所有这些节点之间是否存在路径,如果存在,最短路径是什么,其中包含不在节点子集中的最少节点。
我一直在想办法修改最小生成树算法来实现这一点,但到目前为止我还没有想出一个可行的解决方案。
有没有好的方法可以做到这一点,或者这是对已知算法的描述?
【问题讨论】:
我创建了一个 Graph/Node/Connection 类,它不仅可以显示最短路径,还可以告诉你是否所有节点都已连接:
var allNodesAreConnected = StartNode.AllNodes.All(n => n.IsConnectedToStartNode);
或者如果您想知道哪些节点未连接,请稍微更改一下:
var anotConnectedNodes = StartNode.AllNodes.Where(n => !n.IsConnectedToStartNode);
这篇文章中有更多示例和完整代码: Create your own navigation system (with a Graph, Node and Connection class)
【讨论】:
对于没有图论背景的人,我已经解决了这个问题,发现在未加权无向图中,最简单的方法是Depth First Search。 Dijkstra 等算法的实现通常采用加权解决方案,并为权重输入任意值。
我发现可行的解决方案我在使用DFS时遍历了节点并记录了每一个成功的旅程,那么这只是一个返回最短成功旅程的案例。
这是完成繁重工作的文件: Depth First Search Algorithm
【讨论】:
这里有一个方法可以帮助你:
使用Floyd-Warshall 或 Dijkstra 求每个 i 和 j 的节点 i 和节点 j 之间的距离 d(i, j),使得节点 i 和节点 j 在节点的子集中。
(如果 d(i,j) = infinity 那么现在停止,没有解决方案)
制作一个包含子集中每个节点的新图。对于每个 d(i, j),在新图中的节点 i、节点 j 之间添加一条边,权重 = d(i, j)
现在在这个新图上使用旅行商算法来找到访问所有节点的最短路径。
这条最短路径为您提供路径的长度,但该路径可能会多次访问某些节点。这意味着我们对所需子集之外的节点数量有一个上限。
【讨论】:
I am trying to determine whether there is a path between all of these nodes)。这个问题实际上是 NP-Hard。
您应该使用Dijkstra's shortest path algorithm。首先,您必须为图中的所有边分配权重(或距离),连接不在子集中的两个节点的每条边必须被赋予权重 1。连接子集中一个或两个节点的每条边必须被赋予无限重量。其次,您应该在结果图上运行 Dijkstra 算法。 该算法将检查图的每条边。
另外,您可以使用A* (A-star) algorithm。
更新: 起初我不明白这个问题。正如@amit 所说,这是一个 NP 难题,是 HCP 和 TSP 的组合。也许某种随机搜索算法可以在多项式时间内以高概率解决这个问题。
【讨论】:
I am trying to determine whether there is a path between all of these nodes
我正在尝试确定所有这些之间是否存在路径 节点
(据我了解,您正在寻找访问所有标记节点的单一路径)
我的朋友,这可能是个问题 - 您正在描述 Traveling Salesman Problem 和 Hamiltonian Path Problem 的变体(如果您正在寻找简单路径,reduction 来自哈密顿路径是直截了当的:标记所有节点)。
但恐怕这些问题是NP-Hard。
NP-Hard 问题是一个我们不知道任何多项式时间解决方案来解决它的问题,并且一般假设是 - 一个不存在1支持>.
因此,您最好的选择可能是某种指数解决方案。使用动态编程的 TSP 有O(n^2 * 2^n) 解决方案,或者是O(n!) 的蛮力解决方案
(1) 确实不是一个正式的定义,但这是足够的信息来理解问题,NP-Hard 问题确实还有很多。
【讨论】:
Dijkstra 算法或使用广度优先搜索。
【讨论】:
I am trying to determine whether there is a path between all of these nodes