在加权有向图G
(具有正权重),n
个顶点和m
边,我们想要计算从顶点1
到其他的最短路径顶点。我们使用一维数组D[1..n]
和D[1]=0
以及其他填充+infinity
的数组。为了更新数组我们只允许使用Realx(u, v)
if D[v] > D[u] + W(u, v) then D(v):=D(u)+W(u,v)
其中W(u, v)
是u-->v
边缘的权重。我们必须多少次调用Relax函数来确保每个顶点u
,D[u]
等于从顶点1
到u
的最短路径长度。
Solution: i think this is Bellman-Ford and m*n times we must call.
在Dijkstra
和Bellman-Ford
以及其他人中,我们有Relax
个功能。我们如何检测它们中的哪一个?
引自CLRS书:
本章中的算法不同之处在于它们放松每条边的次数以及它们放松边缘的顺序。 Dijkstra算法和有向无环图的最短路径算法恰好放松每个边缘一次。 Bellman-Ford算法放宽每个边| V | -1次。
答案 0 :(得分:1)
我们应该遍历每个边n - 1
次:
for step <- 0 ... n - 1:
for edge <- edges
relax(edge)
有必要:设想一个带n
个顶点的链。我们需要准确n - 1
步骤才能到达最后一步。
这就足够了:最佳路径中没有循环,最长的简单路径最多包含n - 1
个边缘。
所以答案是(n - 1) * m
想要简单地遍历距离数组并进行更改(是的,它是福特 - 贝尔曼的算法)。
然而,如果使用另一种算法(例如,Dijkstra's),则对relax函数的调用次数较少(即m
)。
所以这取决于我们使用的算法的细节。
答案 1 :(得分:1)
对于Bellman-Ford和Dijkstra算法,我们将使用相同的松弛函数,但主要的不同是,在每个算法中调用松弛函数的次数。
贝尔曼 - 福特:
for i from 1 to size(vertices)-1:
for each edge (u, v) with weight w in edges:
relax(u,v)
因此,对于每个边缘,松弛函数将被称为n - 1次。
对于Dijkstra:
while Q is not empty:
u ← vertex in Q with min dist[u] // Source node in first case
remove u from Q
for each edge(u,v) of u: // where v is still in Q.
relax(u,v)
end for
end while
在这种情况下,当处理其起始顶点时,将为每个边调用一次relax函数。
摘要: Bellman-Ford的算法,松弛函数调用次数为m*n
,Dijkstra算法,调用次数为m
,{{1} }是边数,m
是顶点数。
注意:从维基百科中获取和修改代码,为您提供更清晰的使用放松功能的视图