import heapq
def dijkstra(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
heap = [(0, start)]
while heap:
(dist, current_node) = heapq.heappop(heap)
if dist > distances[current_node]:
continue
for neighbor, weight in graph[current_node].items():
distance = dist + weight
if distance < distances[neighbor]:
distances[neighbor] = distance
heapq.heappush(heap, (distance, neighbor))
return distances
Bellman-Ford算法
算法思路: 从源点出发,依次进行n-1轮更新,每次更新当前节点的所有邻居的距离
优化思路: 提前退出, 差分约束系统求解
代码示例:
def bellman_ford(graph, start):
distances = {node: float('inf') for node in graph}
distances[start] = 0
for _ in range(len(graph) - 1):
for node in graph:
for neighbor, weight in graph[node].items():
if distances[node] + weight < distances[neighbor]:
distances[neighbor] = distances[node] + weight
return distances
Floyd-Warshall算法
算法思路: 以中间节点为枚举变量,更新任意两个节点之间的距离
优化思路: 利用矩阵运算加速
代码示例:
def floyd_warshall(graph):
distances = graph
for k in graph:
for i in graph:
for j in graph:
distances[i][j] = min(distances[i][j], distances[i][k] + distances[k][j])
return distances
A*算法
算法思路: 综合考虑路径长度和启发函数值,每次选取最小值作为下一个搜索节点
优化思路: 启发函数优化(如曼哈顿距离), 双向A*
代码示例:
import heapq
from math import sqrt
def euclidean_distance(a, b):
return sqrt((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2)
def a_star(graph, start, end):
open_set = set([start])
closed_set = set()
g = {node: float('inf') for node in graph}
g[start] = 0
parents = {node: None for node in graph}
f = {node: euclidean_distance(graph[node], graph[end]) for node in graph}
while open_set:
current = min(open_set, key=lambda node: f[node])
if current == end:
path = []
while current:
path.append(current)
current = parents[current]
return list(reversed(path))
open_set.remove(current)
closed_set.add(current)
for neighbor in graph[current]:
if neighbor in closed_set:
continue
tentative_g_score = g[current] + euclidean_distance(graph[current], graph[neighbor])
if neighbor not in open_set:
open_set.add(neighbor)
elif tentative_g_score >= g[neighbor]:
continue
parents[neighbor] = current
g[neighbor] = tentative_g_score
f[neighbor] = g[neighbor] + euclidean_distance(graph[neighbor], graph[end])
return None