, T) R4 L* o5 G m( }% X```python . P* V: l: A/ h2 wdef bellman_ford(graph, start): / d A) @. v8 ^6 }0 b# I" U' S # 初始化距离$ l0 @& [( ]/ k! b
distances = {node: float('inf') for node in graph}, \/ S( d/ c; q0 @8 `" F
distances[start] = 0 7 J) [/ G8 o8 R8 P$ R0 m! X ; c# s7 i9 v/ |2 w7 [ # 松弛操作# S8 r% C+ s) u1 a% `; _
for _ in range(len(graph) - 1):1 i5 n, l( H$ ^8 X
for u in graph: 5 c2 u: W3 N! H+ W1 S. M$ v for v, weight in graph[u].items(): % D, A# N5 {8 Y. S% P, q% z if distances[u] + weight < distances[v]: 3 J( \4 o! I( k5 K& K& a% X& w distances[v] = distances[u] + weight + ~; j: p) S5 `8 G/ M6 r9 |* n- ^, m/ N9 H- n) b# a6 L' U8 G
# 检查负权回路% i% ~1 A8 w" b. F
for u in graph: |% _1 i5 ?) r& i$ _
for v, weight in graph[u].items(): 6 r$ R$ U$ p( R2 x0 P if distances[u] + weight < distances[v]: $ O& H: @, P, J @ D" N raise ValueError("Graph contains a negative weight cycle") * ^5 `( m" A% l3 W( T. }: J6 ~- Y, s- d/ k) _+ _$ G# u
return distances1 e3 ^, t ]: _/ ^ l7 l1 e b+ w
* h1 a0 [/ m6 R7 h# 示例图(带有负权边), \- ]$ a! h7 r R# F. i; v
graph_with_negative_weight = {6 K" O! M% Z* `( o! o
'A': {'B': 1, 'C': 4}, - ^- w% b2 V$ a }/ I9 Z 'B': {'C': -3, 'D': 2}, , X& N k& N c+ o. }& \' u 'C': {}, 6 f' L, `. v9 Z& U2 E S 'D': {'A': -1}3 n: q$ @. U- P$ m! _9 N
}9 }5 h q8 X3 w C5 y
2 ~, M' g; L0 ]+ O" hstart_node = 'A'2 t9 t8 q: q) u1 O8 ~
shortest_paths = bellman_ford(graph_with_negative_weight, start_node) - O- W6 B% d9 D; \6 c @print(shortest_paths) # {'A': 0, 'B': 1, 'C': -2, 'D': 3} * f1 u! [& p; }``` + ?( f# f3 {6 w' j- s; ~* ?( ]
## 3. Floyd-Warshall 算法 7 K; E' h$ R. f0 b6 K! B E7 Y, g' ^' `7 e" c; r, ~* h6 O) k* D u
Floyd-Warshall 算法用于寻找图中所有节点之间的最短路径,适用于边权任意的图,包括有负权边但无负权回路的情况。 # p. X9 ]' W& n( N2 ~5 T- _; k9 K* r w" ?$ d# i
### 原理步骤 " i( ? Z2 [$ S$ p. d! k0 R- z/ B! j; h! c+ W6 T; Y p; O, I. C( b
1. **初始化**:3 g; ^8 Y; O6 H3 I& K, ~
- 创建一个距离矩阵,初始化为无穷大,源节点到自身的距离置为0,直接相连的节点的距离为边权。 9 ?7 W# \0 D+ [2 O5 B7 b; f( f0 h) V
2. **更新路径**:+ G; X# e4 N! J3 t @# G
- 三重循环遍历所有节点,以每个中间节点尝试更新路径。! r; O6 ^, u$ E
4 J4 \6 b6 X) S. Z( J
3. **输出结果**: . O$ P, B' M) R3 O$ A - 最终得到的矩阵即为每对节点之间的最短路径长度。' H- G& h7 X/ ^2 W4 ]! L
- m; _9 x7 U. T/ H. u, }: ^### 示例代码/ H1 c/ |* }0 A$ }# c( z, f4 |, H
0 W ]$ {0 U: l9 Q2 E```python( ]$ `' n; I. T# ~1 k
def floyd_warshall(graph):% o* o; d, o9 w E9 ?% y9 K3 D
# 初始化距离矩阵# s; [3 L, B- }& A: A
nodes = list(graph.keys())( z$ n7 h4 l4 X9 P6 R3 c
distances = {node: {n: float('inf') for n in nodes} for node in nodes}0 |% Q% X2 M! u7 Y# A) b
7 \" c+ ~5 Z; m- S* e% S E
for u in nodes:7 ~* @( o7 d; [- ?" U
distances[u][u] = 0/ _/ H& W* @) I" D. i! Z
for v, weight in graph[u].items(): " K O6 E( `+ |; U2 F distances[u][v] = weight ) J: U; G* a% h. m6 V% E0 d9 E' g/ d% x! S
# 更新路径 7 I9 m$ d$ r1 k9 o3 ] for k in nodes: + u7 b& W$ Q1 J# a/ K3 q7 `5 U for i in nodes: + W% G6 J$ P+ ~+ J" T for j in nodes: 0 ^8 V- L( P; M& W7 I if distances[i][j] > distances[i][k] + distances[k][j]: . ?/ I5 s- t3 s0 J5 S distances[i][j] = distances[i][k] + distances[k][j]( l6 C6 k* y8 u- w