• Java 数据结构教程

最短路径算法



最短路径算法是一种找到从源节点 (S) 到目标节点 (D) 的最低成本路径的方法。在这里,我们将讨论 Moore 算法,也称为广度优先搜索算法。

Moore 算法

  • 标记源顶点 S 并将其标记为 i 并设置 i = 0

  • 找到与标记为 i 的顶点相邻的所有未标记的顶点。如果没有任何顶点连接到顶点 S,则顶点 D 未连接到 S。如果存在连接到 S 的顶点,则将其标记为 i+1

  • 如果 D 已标记,则转到步骤 4,否则转到步骤 2 以增加 i = i+1。

  • 找到最短路径的长度后停止。

Dijkstra 算法

Dijkstra 算法解决了有向加权图 G = (V, E) 上的单源最短路径问题,其中所有边的权重均为非负数(即对于每条边 (u, v) Є E),w(u, v) ≥ 0)。

在以下算法中,我们将使用一个函数 Extract-Min(),它提取具有最小键的节点。

算法:Dijkstra-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 函数的实现。如果使用线性搜索实现 Extract-Min 函数,则该算法的复杂度为 O(V2 + E)

在此算法中,如果我们使用最小堆,Extract-Min() 函数在该堆上工作以从 Q 返回具有最小键的节点,则可以进一步降低该算法的复杂度。

示例

让我们考虑顶点 19 分别作为起点和终点。最初,除起点外的所有顶点均标记为 ∞,起点标记为 0

顶点 初始 步骤 1 V1 步骤 2 V3 步骤 3 V2 步骤 4 V4 步骤 5 V5 步骤 6 V7 步骤 7 V8 步骤 8 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

此路径是根据前驱信息确定的。

Dijkstra's algorithm

Bellman-Ford 算法

该算法解决了有向图 G = (V, E) 的单源最短路径问题,其中边权重可能为负数。此外,如果不存在任何负权重循环,则可以应用此算法来查找最短路径。

算法: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

Bellman Ford Algorithm Initialization

在第一步中,所有可从源节点到达的顶点都将更新为最小成本。因此,顶点 ah 会更新。

Bellman Ford Algorithm Minimum Cost

在下一步中,顶点 a, b, fe 会更新。

Bellman Ford Algorithm Updated

遵循相同的逻辑,在此步骤中,顶点 b, f, cg 会更新。

Bellman Ford Algorithm Logic

在这里,顶点 cd 会更新。

Bellman Ford Algorithm Vertices

因此,顶点 s 和顶点 d 之间的最小距离为 20

根据前驱信息,路径为 s → h → e → g → c → d

广告