最短路径算法用于寻找图中两点之间的最短路径。这类算法在网络路由、地图导航、物流和许多其他应用中起到关键作用。常见的最短路径算法包括 Dijkstra 算法、Bellman-Ford 算法和 Floyd-Warshall 算法。下面将介绍这些算法的基本原理和具体实现。8 F q B' D0 e; Z. m: A
0 Y9 ^1 D: s. o9 Z## 1. Dijkstra 算法$ S, E7 Y/ I1 g# r
4 J6 G+ L( M9 ?% h6 w0 _9 V
Dijkstra 算法用于计算单源最短路径,有效于边权为非负数的图。它通过贪心策略逐步选择最短路径,从起点出发扩展到其他节点。 * E$ {' K5 E+ A7 C / F) i- c7 x Q m/ x### 原理步骤- U) e2 m, J5 U0 F7 h" g
1 [1 Y4 F9 ?9 z* A+ c* U
1. **初始化**: K* M$ s8 ^" u/ x' k S - 设置源节点到自己的距离为0,其他节点为无穷大(一般用 `inf` 表示)。 8 n) L) u* }' ]( ^" j, }% N - 初始化一个空的优先队列,用于存储待处理的节点。7 i+ O4 l) @, ]" K! u
. U# ~% Y0 d8 _$ x2 g
2. **处理节点**:- k4 x {! T7 w. R0 Q, P& g# M1 U
- 从优先队列中选取距离最小的节点作为当前节点。9 K# E0 }# |4 B8 X1 d9 `. n$ z
- 更新当前节点的所有邻接节点的距离。如果新的距离更短,则更新并将邻接节点加入优先队列。 2 l( |% _+ ]" n& j / F2 P5 U! r* Q! F) h* r2 d; y# _3. **重复处理**: 5 h" h+ V" C% D/ e }: U! a - 继续选择距离最小的节点,直到处理完所有节点或找到目标节点。 / G9 G' P4 }4 [0 N, ?% [5 B M3 Z; J5 s: ~5 n$ A! g# ]
### 示例代码 1 r" ~$ B$ j3 U4 E4 w ' F) k% {0 ^6 L# }( `1 W```python% D9 V# G' p9 l: C
import heapq5 z8 K1 K+ o) ~) Y2 ?
$ A( S3 Y( H0 {% J7 z
def dijkstra(graph, start):* ]. T1 U; v6 e0 g
# 图的表示为字典,键为节点,值为邻接节点及其边权4 H- q* m) u9 f: o
queue = []: S; G; m( K- r
distances = {node: float('inf') for node in graph}- d+ g3 H3 ^! w$ A" `9 V! U- O
distances[start] = 0 * W* p* ]" {( a+ d; S heapq.heappush(queue, (0, start)) # (距离, 节点)7 @ A2 o9 D& `' H [7 u" r
l P) G& R* U while queue: 8 R0 ^ f9 S6 A: F2 k3 e' B2 Z" a current_distance, current_node = heapq.heappop(queue) ( J5 W2 h4 U: f$ U; V7 m7 B ' n g9 B# d1 a) o& T # 只处理当前节点的最短距离 # ~6 z4 }9 |- c0 o# f8 @ if current_distance > distances[current_node]:$ G6 I# I8 @2 m3 W, A7 _. r
continue c: K- S/ p4 }" N
$ u' Y& s% d& I* q+ z for neighbor, weight in graph[current_node].items(): 1 e* k( N+ p! I! i+ t, t distance = current_distance + weight1 I: k( l/ L4 A6 n4 h1 k5 k" k+ P0 E
$ O0 m5 S8 @# s$ }9 G. |8 }" }3 F
# 更新邻接节点的距离 7 a: t% }0 _! t% t$ d if distance < distances[neighbor]: : L+ I* _0 Y4 W& ?* F2 k" r distances[neighbor] = distance 9 C) P* ]' a! ?2 O heapq.heappush(queue, (distance, neighbor))1 O- H2 M2 M# o* ~7 b5 n
e8 h. F. e; v3 B" a( p6 m6 t
return distances " F' N! E- X8 A$ _/ a$ E/ K3 y$ s+ N 2 [' R, C# ]" y4 m% o" s# 示例图: i' X5 T: W) ?7 M0 S
graph = {/ h0 Z4 Q0 C8 m' [
'A': {'B': 1, 'C': 4},. D' } c! n) S8 G/ A1 c
'B': {'A': 1, 'C': 2, 'D': 5}, ( H# n, O5 C) V* b0 T4 Z# q 'C': {'A': 4, 'B': 2, 'D': 1}, 4 N4 y! r f& {5 K 'D': {'B': 5, 'C': 1},6 q* l0 C5 u9 |/ ]) Z
} f* k, o3 o8 W+ I# s3 { ! k/ @6 b; E$ r! O; vstart_node = 'A'+ U% C8 t" z$ P0 r
shortest_paths = dijkstra(graph, start_node) / f8 G! f% I2 t E4 {print(shortest_paths) # {'A': 0, 'B': 1, 'C': 3, 'D': 4}. ?2 B' y; o# H: f O
```+ s" w! y% P3 p! A$ x: r
2 t }! F8 h; O$ l) N
## 2. Bellman-Ford 算法3 R2 V1 d2 z( k