📅  最后修改于: 2023-12-03 15:36:36.889000             🧑  作者: Mango
在计算机科学中,图(graph)是一种非常重要的数据结构。图由节点(vertex或node)和边(edge)组成,节点代表实体,边表示它们之间的关系。本文将介绍如何使用Python的字典构建无向图,并用Dijkstra算法找到最短路径。
一个无向图可以用邻接表来表示。邻接表是由所有顶点的列表和连接每个顶点的其他顶点的列表组成的字典。构建一个无向图的过程如下:
graph = {}
edges = [('A', 'B'), ('A', 'C'), ('B', 'C'), ('B', 'D'), ('C', 'D'), ('E', 'F'), ('F', 'C')]
for edge in edges:
a, b = edge
if a not in graph:
graph[a] = []
if b not in graph:
graph[b] = []
graph[a].append(b)
graph[b].append(a)
上面的代码中,我们定义了一个空字典graph,然后遍历每一条边。对于每个节点,如果它不在图中,我们就向图中添加该节点。然后,我们将边添加到节点的连接列表中,并将节点添加到边的连接列表中(因为这是无向图)。
我们将使用Dijkstra算法来找到两个节点之间的最短路径。Dijkstra算法是一种贪心算法,它从起点开始遍历图,找到与起点最近的节点并将其加入到 visited_nodes 集合中。然后,算法遍历所有与该节点相邻的节点,并更新它们的距离和前向节点。如果更新了某个节点的距离,那么它将被加入到待处理节点列表中。算法继续重复这个过程,直到遍历所有节点。最后,我们可以重建路径以从起点到目标节点。
以下是实现Dijkstra算法的代码片段:
from queue import PriorityQueue
def dijkstra(graph, start, end):
distances = {}
for vertex in graph:
distances[vertex] = float('inf')
distances[start] = 0
pq = PriorityQueue()
pq.put((0, start))
visited_nodes = set()
while not pq.empty():
(distance, current_vertex) = pq.get()
visited_nodes.add(current_vertex)
for neighbor in graph[current_vertex]:
if neighbor in visited_nodes:
continue
new_distance = distances[current_vertex] + 1
if new_distance < distances[neighbor]:
distances[neighbor] = new_distance
if neighbor == end:
return new_distance
pq.put((new_distance, neighbor))
return distances[end]
上述代码片段中,我们用字典 distances 记录每个节点到起点的距离,并初始化为正无穷。起点到自身的距离为0。我们使用 PriorityQueue 来维护待处理节点列表,该列表按距离排序。算法从起点开始,并将期望距离(distance)和起点加入到待处理列表中。在主循环中,它通过邻接列表遍历当前顶点的所有相邻顶点,并计算从起点到该顶点的预期距离。如果新的距离比原来的短,则更新字典 distances,并将该顶点加入到待处理列表中。
当算法遍历所有节点后,它可以重建从起点到目标节点的路径。为了实现这一点,我们可以使用另一个字典 parents,它记录每个节点的前项节点。
上面我们介绍了如何使用Python的字典构建无向图,并用Dijkstra算法来找到最短路径。无向图由邻接表表示,每个节点都是字典中的键,对应的值是连接该节点的所有节点。Dijkstra算法使用贪心策略,选择与起点最近的节点,并遍历其邻接列表更新距离。我们使用 PriorityQueue 来维护待处理的节点列表。