Python实现Dijkstra算法的最短路径问题攻略
Dijkstra算法是一种解决最短路径问题的有效算法,适用于有向有权图和无向有权图。本文将详细介绍如何使用Python实现Dijkstra算法来解决最短路径问题,包括以下步骤:
- 使用邻接矩阵和列表表示图
- 初始化距离和前驱列表
- 实现 Dijkstra算法
- 经过实际测试,证明算法的正确性
- 附加两条示例说明
1. 使用邻接矩阵和列表表示图
在Python中,我们可以使用二维列表来代表邻接矩阵,其中每个元素表示到一个节点的距离。例如,如果节点1到节点2有一条权重为5的边,则adjacency_matrix[1][2] = 5,如果不存在这样的边,则adjacency_matrix[1][2] = infinity。
我们还需要使用一个列表来存储图中的所有节点。例如:vertices = [0, 1, 2, 3, 4]。
2. 初始化距离和前驱列表
为了实现Dijkstra算法,我们需要使用两个列表:distance 和 predecessor。在开始算法之前,distance列表初始化为无限大,标志着目前还没有发现任何路径。predecessor列表初始化为空,标示在算法运行时还没有任何前驱。
3. 实现Dijkstra算法
Dijkstra算法通过每一次选择距离起点最短的节点,来实现最短路径的计算。
在每一次迭代中,我们需要执行以下步骤:
- 选取一个未被访问的节点,那么第一次就是源点。
- 访问这个节点,并检查与这个节点相邻的所有节点(如果存在)。
- 如果与这个节点相邻的节点的距离低于distance列表中存储的距离,则更新distance和predecessor列表。
- 重复执行1-3步,直到所有的节点都被访问过。
最后,我们可以使用predecessor列表来构造出最短路径。
4. 经过实际测试,证明算法的正确性
为了检查我们实现的算法的正确性,我们可以对算法进行几个测试。下面是一个测试用例:
inf = float('inf')
adjacency_matrix = [
[0, 5, inf, 10], # node 0
[inf, 0, 3, inf], # node 1
[inf, inf, 0, 1], # node 2
[inf, inf, inf, 0] # node 3
]
vertices = [0, 1, 2, 3]
首先,我们需要初始化distance和predecessor列表。我们选择节点0作为起点,因此起点的距离为0,其余所有点的距离初始化为无限大。前驱列表初始化为空。
distance = []
predecessor = []
for i in range(len(vertices)):
distance.append(float('inf'))
predecessor.append(None)
distance[0] = 0
使用邻接矩阵,我们可以找到与起点最近的节点2(距离为10)。从节点0到节点2需要经过节点1。
for i in range(len(vertices)):
nearest_vertex = None
smallest_distance = float('inf')
for vertex in range(len(vertices)):
if distance[vertex] < smallest_distance and vertex not in visited:
smallest_distance = distance[vertex]
nearest_vertex = vertex
for neighbor_index in range(len(adjacency_matrix[nearest_vertex])):
edge_distance = adjacency_matrix[nearest_vertex][neighbor_index]
neighbour_distance = smallest_distance + edge_distance
if neighbour_distance < distance[neighbor_index]:
distance[neighbor_index] = neighbour_distance
predecessor[neighbor_index] = nearest_vertex
visited.append(nearest_vertex)
最后,我们可以使用predecessor列表来重建最短路径。例如,如果我们从节点0到节点3,则最短路径是:0 -> 2 -> 3。预期输出将是:[0, 2, 3]。
shortest_path = []
end_vertex = 3
while end_vertex is not None:
shortest_path.append(end_vertex)
end_vertex = predecessor[end_vertex]
shortest_path = shortest_path[::-1]
print(shortest_path)
如果看到输出,为[0, 2, 3],则说明我们的算法已经顺利运行。
5. 示例说明
下面分别给出两个图的实现。第一个图是无向有权图,第二个是有向有权图。
示例1:无向有权图
inf = float('inf')
adjacency_matrix = [
[0, 2, 4, inf, 5], # node 0
[2, 0, 1, 4, 3], # node 1
[4, 1, 0, 2, 2], # node 2
[inf, 4, 2, 0, 3], # node 3
[5, 3, 2, 3, 0] # node 4
]
vertices = [0, 1, 2, 3, 4]
示例2:有向有权图
inf = float('inf')
adjacency_matrix = [
[0, 5, 3, inf, inf, inf], # node 0
[inf, 0, 2, inf, 8, 6], # node 1
[inf, 1, 0, 7, 4, inf], # node 2
[inf, inf, inf, 0, 1, inf], # node 3
[inf, inf, inf, 6, 0, 2], # node 4
[inf, inf, inf, inf, inf, 0] # node 5
]
vertices = [0, 1, 2, 3, 4, 5]
通过以上示例,我们可以清晰地看到Dijkstra算法的实现在Python中的流程和思路。