📅  最后修改于: 2021-01-12 03:36:12             🧑  作者: Mango
Dijkstra的算法解决了有向加权图G =(V,E)上的单源最短路径问题,其中所有边均为非负值(即,每个边的w(u,v) ≥0 (u,v )ЄE )。
在以下算法中,我们将使用一个函数Extract-Min() ,该函数提取具有最小密钥的节点。
Algorithm: Dijkstra’s-Algorithm (G, w, s)
for each vertex v Є G.V
v.d := ∞
v.∏ := NIL
s.d := 0
S := Ф
Q := G.V
while Q ≠ Ф
u := Extract-Min (Q)
S := S U {u}
for each vertex v Є G.adj[u]
if v.d > u.d + w(u, v)
v.d := u.d + w(u, v)
v.∏ := u
该算法的复杂性完全取决于Extract-Min函数。如果使用线性搜索实现提取最小函数,则该算法的复杂度为O(V 2 + E) 。
在此算法中,如果我们使用min-heap, Extract-Min()函数将其用于从具有最小密钥的Q返回节点,则可以进一步降低该算法的复杂性。
让我们分别将顶点1和9视为起始顶点和目标顶点。最初,除起始顶点以外的所有顶点都标记为∞,起始顶点则标记为0 。
Vertex | Initial | Step1 V1 | Step2 V3 | Step3 V2 | Step4 V4 | Step5 V5 | Step6 V7 | Step7 V8 | Step8 V6 |
---|---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | ∞ | 5 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
3 | ∞ | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
4 | ∞ | ∞ | ∞ | 7 | 7 | 7 | 7 | 7 | 7 |
5 | ∞ | ∞ | ∞ | 11 | 9 | 9 | 9 | 9 | 9 |
6 | ∞ | ∞ | ∞ | ∞ | ∞ | 17 | 17 | 16 | 16 |
7 | ∞ | ∞ | 11 | 11 | 11 | 11 | 11 | 11 | 11 |
8 | ∞ | ∞ | ∞ | ∞ | ∞ | 16 | 13 | 13 | 13 |
9 | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | ∞ | 20 |
因此,顶点9与顶点1的最小距离为20 。路径是
1→3→7→8→6→9
该路径是根据前驱信息确定的。
该算法解决了边权重可能为负的有向图G =(V,E)的单源最短路径问题。此外,如果不存在任何负加权循环,则该算法可用于找到最短路径。
Algorithm: Bellman-Ford-Algorithm (G, w, s)
for each vertex v Є G.V
v.d := ∞
v.∏ := NIL
s.d := 0
for i = 1 to |G.V| - 1
for each edge (u, v) Є G.E
if v.d > u.d + w(u, v)
v.d := u.d +w(u, v)
v.∏ := u
for each edge (u, v) Є G.E
if v.d > u.d + w(u, v)
return FALSE
return TRUE
第一个for循环用于初始化,运行时间为O(V)次。下一个for循环运行| V-1 |经过边缘,这需要O(E)次。
因此,Bellman-Ford算法运行时间为O(V,E) 。
下面的示例逐步说明了Bellman-Ford算法的工作原理。该图具有负边缘,但没有任何负周期,因此可以使用此技术解决问题。
在初始化时,除源以外的所有顶点都用∞标记,而源用0标记。
第一步,以最小成本更新可从源到达的所有顶点。因此,顶点a和h被更新。
在下一步中,将更新顶点a,b,f和e 。
按照相同的逻辑,在此步骤中,更新顶点b,f,c和g 。
在这里,顶点c和d被更新。
因此,顶点s与顶点d之间的最小距离为20 。
根据先前的信息,路径为s→h→e→g→c→d