Dijkstra和Floyd算法
1. Dijkstra算法
Dijkstra算法用于寻找单源最短路径,即从一个节点到所有其他节点的最短路径。它的基本思想是每次选择未处理节点中距离起点最近的节点,并更新其邻居的最短路径。
1.1. 算法步骤:
- 初始化:设定起点到起点的距离为0,其他节点到起点的距离为无穷大。将所有节点标记为未处理。
- 选择未处理节点中距离起点最近的节点,记为当前节点。
- 更新当前节点的邻居节点的最短路径。
- 将当前节点标记为已处理。
- 重复步骤2-4,直到所有节点都被处理。
1.2. Python实现Dijkstra算法
import heapq
def dijkstra(graph, start):
# 创建一个字典来存储从起点到每个节点的最短路径距离
distances = {node: float('infinity') for node in graph}
# 起点到起点的距离为0
distances[start] = 0
# 创建一个优先队列来处理节点
priority_queue = [(0, start)]
while priority_queue:
current_distance, current_node = heapq.heappop(priority_queue)
if current_distance > distances[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = current_distance + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(priority_queue, (distance, neighbor))
return distances
# 示例图表示为邻接表
graph = {
'A': {'B': 1, 'C': 4},
'B': {'A': 1, 'C': 2, 'D': 5},
'C': {'A': 4, 'B': 2, 'D': 1},
'D': {'B': 5, 'C': 1}
}
# 从节点 'A' 出发
print(dijkstra(graph, 'A'))
2. Floyd算法
Floyd算法,又称Floyd-Warshall算法,用于寻找任意两点之间的最短路径。它的基本思想是通过不断更新节点之间的最短路径,最终得到任意两点之间的最短路径。
2.1. 算法步骤:
- 初始化:创建一个矩阵,记录图中所有节点间的距离,初始值为节点间的边的权重,如果两节点间没有直接边则设为无穷大。
- 对于每一对节点 (i, j),检查通过每个可能的中间节点 k 是否能找到更短的路径。如果能,更新路径距离。
- 重复上述过程,直到所有节点对的最短路径被找到。
2.2. Python实现Floyd算法
def floyd_warshall(graph):
# 初始化距离矩阵
distance = [[float('infinity')] * len(graph) for _ in range(len(graph))]
# 自己到自己的距离为0
for i in range(len(graph)):
distance[i][i] = 0
# 设置直接边的距离
for i in range(len(graph)):
for j in range(len(graph)):
if graph[i][j] != 0:
distance[i][j] = graph[i][j]
# 逐个检查每个可能的中间节点 k
for k in range(len(graph)):
for i in range(len(graph)):
for j in range(len(graph)):
if distance[i][j] > distance[i][k] + distance[k][j]:
distance[i][j] = distance[i][k] + distance[k][j]
return distance
# 示例图表示为邻接矩阵
graph = [
[0, 3, float('infinity'), 5],
[2, 0, float('infinity'), 4],
[float('infinity'), 1, 0, float('infinity')],
[float('infinity'), float('infinity'), 2, 0]
]
print(floyd_warshall(graph))
这两个算法分别解决了单源最短路径和任意两点之间的最短路径问题。Dijkstra算法适用于边权重非负的情况,而Floyd算法则可以处理有向图和负权重的边,但不能处理负权重环。