幾種常見的最短路徑算法以及代碼實現(xiàn)注釋
以下是幾種常見的最短路徑算法以及帶有代碼注釋的實現(xiàn)示例(使用Python語言):
1. Dijkstra算法:
? ?- 原理:從起始頂點開始,逐步找到距離起始頂點最近的頂點,并計算到達該頂點的最短路徑。不斷更新頂點的最短路徑,直到找到到達目標頂點的最短路徑。
? ?- 實現(xiàn)(使用鄰接矩陣表示圖):
? ? ?```python
? ? ?import sys
? ? ?def dijkstra(graph, start):
? ? ? ? ?num_vertices = len(graph)
? ? ? ? ?visited = [False] * num_vertices
? ? ? ? ?distance = [sys.maxsize] * num_vertices
? ? ? ? ?distance[start] = 0
? ? ? ? ?for _ in range(num_vertices):
? ? ? ? ? ? ?min_distance = sys.maxsize
? ? ? ? ? ? ?min_vertex = -1
? ? ? ? ? ? ?# 找到當前距離起始頂點最近的頂點
? ? ? ? ? ? ?for v in range(num_vertices):
? ? ? ? ? ? ? ? ?if not visited[v] and distance[v] < min_distance:
? ? ? ? ? ? ? ? ? ? ?min_distance = distance[v]
? ? ? ? ? ? ? ? ? ? ?min_vertex = v
? ? ? ? ? ? ?if min_vertex == -1:
? ? ? ? ? ? ? ? ?break
? ? ? ? ? ? ?visited[min_vertex] = True
? ? ? ? ? ? ?# 更新從起始頂點到達其他頂點的最短路徑
? ? ? ? ? ? ?for v in range(num_vertices):
? ? ? ? ? ? ? ? ?if not visited[v] and graph[min_vertex][v] != 0:
? ? ? ? ? ? ? ? ? ? ?new_distance = distance[min_vertex] + graph[min_vertex][v]
? ? ? ? ? ? ? ? ? ? ?if new_distance < distance[v]:
? ? ? ? ? ? ? ? ? ? ? ? ?distance[v] = new_distance
? ? ? ? ?return distance
? ? ?```
2. Bellman-Ford算法:
? ?- 原理:從起始頂點開始,逐步更新頂點的最短路徑。迭代V-1次,每次迭代都遍歷所有邊,對于每條邊,嘗試通過該邊進行松弛操作,即更新邊的終點頂點的最短路徑估計值。
? ?- 實現(xiàn)(使用邊列表表示圖):
? ? ?```python
? ? ?import sys
? ? ?def bellman_ford(graph, start):
? ? ? ? ?num_vertices = len(graph)
? ? ? ? ?distance = [sys.maxsize] * num_vertices
? ? ? ? ?distance[start] = 0
? ? ? ? ?for _ in range(num_vertices - 1):
? ? ? ? ? ? ?for u, v, weight in graph:
? ? ? ? ? ? ? ? ?if distance[u] != sys.maxsize and distance[u] + weight < distance[v]:
? ? ? ? ? ? ? ? ? ? ?distance[v] = distance[u] + weight
? ? ? ? ?# 檢查是否存在負權回路
? ? ? ? ?for u, v, weight in graph:
? ? ? ? ? ? ?if distance[u] != sys.maxsize and distance[u] + weight < distance[v]:
? ? ? ? ? ? ? ? ?return None
? ? ? ? ?return distance
? ? ?```
Floyd-Warshall算法用于解決帶權重的有向圖或無向圖中任意兩個頂點之間的最短路徑問題。它使用動態(tài)規(guī)劃的思想,通過逐步考慮中間頂點的遍歷,不斷優(yōu)化頂點對之間的最短路徑。
算法原理:
1. 初始化距離矩陣為圖的鄰接矩陣,其中距離矩陣`distance[u][v]`表示頂點u到頂點v的最短路徑長度。
2. 通過中間頂點k的遍歷,更新距離矩陣中任意兩個頂點之間的最短路徑。對于每對頂點u和v,檢查通過中間頂點k的路徑是否比直接連接的路徑更短,如果是,則更新距離矩陣中的值為更短的路徑長度。
代碼實現(xiàn)(使用鄰接矩陣表示圖):
```python
import sys
def floyd_warshall(graph):
? ? num_vertices = len(graph)
? ? distance = [[sys.maxsize] * num_vertices for _ in range(num_vertices)]
? ? # 初始化距離矩陣為圖的鄰接矩陣
? ? for u in range(num_vertices):
? ? ? ? for v in range(num_vertices):
? ? ? ? ? ? distance[u][v] = graph[u][v]
? ? # 逐步遍歷中間頂點,更新最短路徑
? ? for k in range(num_vertices):
? ? ? ? for i in range(num_vertices):
? ? ? ? ? ? for j in range(num_vertices):
? ? ? ? ? ? ? ? # 如果通過中間頂點k能夠獲得更短的路徑,則更新距離矩陣
? ? ? ? ? ? ? ? if distance[i][k] != sys.maxsize and distance[k][j] != sys.maxsize:
? ? ? ? ? ? ? ? ? ? distance[i][j] = min(distance[i][j], distance[i][k] + distance[k][j])
? ? return distance
```
在該實現(xiàn)中,`graph`是輸入圖的鄰接矩陣表示,其中`graph[u][v]`表示頂點u到頂點v之間的邊的權重。距離矩陣`distance`初始化為無窮大,然后通過遍歷中間頂點的方式,不斷更新距離矩陣中的值。最終,返回的距離矩陣將包含任意兩個頂點之間的最短路徑長度。
請注意,如果圖中存在負權回路,F(xiàn)loyd-Warshall算法將無法得到正確的結(jié)果。因此,在使用該算法之前,需要先確保圖中不存在負權回路。