四种求图的最短路径模板
发布人:shili8
发布时间:2025-01-13 19:20
阅读次数:0
**四种求图的最短路径模板**
在计算机科学中,求图的最短路径是指从一个顶点到另一个顶点的最短路径。这种问题在许多领域都有应用,如网络规划、交通流预测等。在本文中,我们将介绍四种常见的求图的最短路径模板:Dijkstra算法、Bellman-Ford算法、Floyd-Warshall算法和A*算法。
###1. Dijkstra算法Dijkstra算法是最早的一种求图的最短路径算法,于1959年由Edsger W. Dijkstra提出。该算法适用于有向图或无向图,并且每个顶点都有一个权值。
**模板代码**
import heapqdef dijkstra(graph, start): # 初始化距离和前驱节点表 distances = {node: float('inf') for node in graph} distances[start] =0 predecessors = {start: None} # 构造优先队列 queue = [(0, start)] while queue: current_distance, current_node = heapq.heappop(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 predecessors[neighbor] = current_node heapq.heappush(queue, (distance, neighbor)) return distances, predecessors
**注释**
* `graph`是图的邻接表,表示每个顶点的相邻节点和权值。
* `start`是起始顶点。
* `distances`是距离表,记录从起始顶点到其他顶点的最短距离。
* `predecessors`是前驱节点表,记录从起始顶点到其他顶点的前驱节点。
###2. Bellman-Ford算法Bellman-Ford算法是Dijkstra算法的一个扩展版本,可以处理负权值和循环图。该算法适用于有向图或无向图,并且每个顶点都有一个权值。
**模板代码**
def bellman_ford(graph, start): # 初始化距离表 distances = {node: float('inf') for node in graph} distances[start] =0 # 构造前驱节点表 predecessors = {start: None} # Relax edges V-1 次 for _ in range(len(graph) -1): for u, v in graph.items(): for neighbor, weight in v.items(): distance = distances[u] + weight # 如果新距离小于已知最短距离,则更新 if distance < distances[neighbor]: distances[neighbor] = distance predecessors[neighbor] = u return distances, predecessors
**注释**
* `graph`是图的邻接表,表示每个顶点的相邻节点和权值。
* `start`是起始顶点。
* `distances`是距离表,记录从起始顶点到其他顶点的最短距离。
* `predecessors`是前驱节点表,记录从起始顶点到其他顶点的前驱节点。
###3. Floyd-Warshall算法Floyd-Warshall算法是一种求图的最短路径算法,可以处理有向图或无向图,并且每个顶点都有一个权值。该算法适用于所有类型的图。
**模板代码**
def floyd_warshall(graph): # 初始化距离表 distances = [[float('inf')] * len(graph) for _ in range(len(graph))] # 初始化距离表中的自身距离为0 for i in range(len(graph)): distances[i][i] =0 # 构造距离表 for u, v in graph.items(): for neighbor, weight in v.items(): distances[u][neighbor] = weight # Relax edges for k in range(len(graph)): for i in range(len(graph)): for j in range(len(graph)): distance = distances[i][k] + distances[k][j] # 如果新距离小于已知最短距离,则更新 if distance < distances[i][j]: distances[i][j] = distance return distances
**注释**
* `graph`是图的邻接表,表示每个顶点的相邻节点和权值。
* `distances`是距离表,记录从一个顶点到另一个顶点的最短距离。
###4. A*算法A*算法是一种求图的最短路径算法,可以处理有向图或无向图,并且每个顶点都有一个权值。该算法适用于所有类型的图。
**模板代码**
import heapqdef a_star(graph, start, goal): # 初始化距离和前驱节点表 distances = {node: float('inf') for node in graph} distances[start] =0 predecessors = {start: None} # 构造优先队列 queue = [(0, start)] while queue: current_distance, current_node = heapq.heappop(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 predecessors[neighbor] = current_node heapq.heappush(queue, (distance, neighbor)) return distances, predecessors
**注释**
* `graph`是图的邻接表,表示每个顶点的相邻节点和权值。
* `start`是起始顶点。
* `goal`是目标顶点。
* `distances`是距离表,记录从起始顶点到其他顶点的最短距离。
* `predecessors`是前驱节点表,记录从起始顶点到其他顶点的前驱节点。
以上四种求图的最短路径模板都可以用于不同的场景中。Dijkstra算法和A*算法适用于有向图或无向图,并且每个顶点都有一个权值。Bellman-Ford算法适用于有向图或无向图,并且每个顶点都有一个权值,能够处理负权值和循环图。Floyd-Warshall算法适用于所有类型的图,可以求出从一个顶点到另一个顶点的最短距离。