给定有向图G=(V,E)
,两个顶点s
,t
和两个权重函数w1
,w2
,我需要找到最短路径从s
到t
到w2
之间的所有最短路径s
到t
w1
。
首先,我如何才能找到两个顶点s
和t
之间的所有最短路径? Dijkstra的算法帮助我们找到从顶点到每个其他可访问顶点的最短路径,是否可以修改它以获得两个顶点之间的所有最短路径?
答案 0 :(得分:2)
这非常直截了当。完全来自Wikipedia:
更普遍的问题是找到源和目标之间的所有最短路径(可能有几个相同长度的不同路径)。然后,我们将存储满足放松条件的所有节点,而不是仅在前一个[]的每个条目中存储单个节点。例如,如果r和源都连接到目标,并且它们都位于通过目标的不同最短路径上(因为在两种情况下边缘成本都相同),那么我们将r和源都添加到先前的[目标]。当算法完成时,先前的[]数据结构将实际描述图形,该图形是原始图形的子集,其中一些边缘被移除。它的关键属性是,如果算法是使用某个起始节点运行的,那么从该节点到新图中任何其他节点的每条路径都将是原始图中这些节点之间的最短路径,以及该长度的所有路径。原始图表将出现在新图表中。然后,为了实际找到两个给定节点之间的所有这些最短路径,我们将在新图上使用路径查找算法,例如深度优先搜索。
换句话说,在Dijkstra终止之后,您应该能够知道从s
到t
的最短路径上节点的所有先前节点,并使用这些节点执行后向BFS / DFS边缘会给你所有最短的路径。
答案 1 :(得分:2)
我将扩大对该问题的评论。问题是,对于某些图形,您可以在两个顶点之间具有指数数量的最短路径,例如
o o o
/ \ / \ / \
u o o o ... o o v
\ / \ / \ /
o o o
此处O(2^|V|)
和u
之间有v
条最短路径。
更好的方法是@n.m提出的方法。在评论中:
简单地使用权重函数w =(w1,w2),使用分量加法和词典排序。
词典加法很简单:你将一个新的权重函数定义为w(e)=(w1(e), w2(e))
(即使用给定的两个权重函数的权重向量)。
然后定义加法运算(你必须有一个加权函数目标集):
w = (w1, w2)
W = (W1, W2)
w + W := (w1 + W1, w2 + W2)
对于我们的情况:根据权重函数w = (w1, w2)
,p0
,您有一条最短路径。让我们根据w2
证明它是根据w1
中最短路径的最短路径。
基本上,这意味着对于每个路径p
w(p) >= w(p0)
,这意味着w1(p) > w1(p0)
(p
根据w1
不是最短的路径)或w1(p) == w1(p0)
和w2(p) >= w2(p0)
因此根据p
,路径w1
是最短的路径,但根据w2
,路径p0
并不短。这意味着w2
根据w1
中最短的{{1}}是最短的。
答案 2 :(得分:2)
使用动态编程可以使用Floyd-Warshall算法有效地解决这个问题,该算法专门用于查找从s到t的所有可能的最短路径。当你想要处理负边缘权重(Dijkstra不会处理负权重)时,Floyd-Warshall确实比Dijkstra有了改进,但请记住,Floyd-Warshall的算法不能处理负周期。
来自Wikipedia:
“Floyd-Warshall算法比较了每对顶点之间通过图形的所有可能路径。只能在图形中使用Θ(| V |³)比较来做到这一点。考虑到可能存在这种情况,这是非常了不起的。在图中最多为Ω(| V |²)边,并且测试每个边的组合。它通过逐步改进两个顶点之间的最短路径上的估计来实现,直到估计是最优的。“
答案 3 :(得分:2)
Dijkstra正是您所寻找的。结果值将保存到“长度”结构中,其中每个顶点与数值(顶点s和可从x访问的每个其他顶点之间的距离)相关联。然后只需访问该结构中t顶点的相应值。 搜索实现。它通常就像访问数组的t位置一样简单,因为你可以用int表示你的顶点。