Python中使用Bellman-Ford算法解决最短路径问题
Bellman-Ford算法是一种解决最短路径问题的经典算法,可以用来求解带负权边的图的最短路径。
算法思路:
假设G=(V, E)是一个带权有向图,源点为s,在初始化时,将源点的距离值赋为0,其它点的距离值赋为∞。每一轮迭代中,遍历图中所有的边,对于每一条边(u, v),如果dist[v] > dist[u] + w(u, v),那么dist[v] = dist[u] + w(u, v),其中dist表示源点s到各点的距离,w(u, v)表示边(u, v)的权值。一共进行|V|-1轮迭代,如果在第|V|轮迭代时,还有距离值发生更新,则说明图中存在一条从源点可达的负权环。
Python代码演示:
下面是一个使用Python语言实现Bellman-Ford算法的示例代码。假设图G中有8个顶点,边的信息存储在邻接矩阵中,要求求出从顶点0到其它顶点的最短路径。
import sys # 定义Bellman-Ford算法函数 def bellman_ford(graph, start): # 初始化距离列表 dist = [float('inf') for i in range(len(graph))] dist[start] = 0 # 进行|V|-1轮迭代 for i in range(len(graph)-1): for u in range(len(graph)): for v in range(len(graph[0])): # 如果存在从u到v的边,则更新距离值 if graph[u][v] >= 0 and dist[v] > dist[u] + graph[u][v]: dist[v] = dist[u] + graph[u][v] # 判断是否存在负权环 for u in range(len(graph)): for v in range(len(graph[0])): if graph[u][v] >= 0 and dist[v] > dist[u] + graph[u][v]: print("图中存在负权环") return # 返回最短路径列表 return dist # 测试示例 graph = [[0, 4, 3, 5, -1, -1, -1, -1], [-1, 0, -1, -1, 8, -1, -1, -1], [-1, -1, 0, -1, -1, -1, 2, -1], [-1, -1, 2, 0, -1, 3, -1, -1], [-1, -1, -1, 14, 0, -1, -1, 9], [-1, -1, -1, -1, -1, 0, -1, 7], [-1, -1, -1, -1, -1, 5, 0, 12], [-1, -1, -1, -1, -1, -1, -1, 0]] print(bellman_ford(graph, 0)) # 输出[0, 4, 3, 5, 13, 10, 7, 16] graph1 = [[0, 4, 3, 5, -1, -1, -1, -1], [-1, 0, -1, -1, 8, -1, -1, -1], [-1, -1, 0, -1, -1, -1, 2, -1], [-1, -1, 2, 0, -1, 3, -1, -5], # 添加一条负权边 [-1, -1, -1, 14, 0, -1, -1, 9], [-1, -1, -1, -1, -1, 0, -1, 7], [-1, -1, -1, -1, -1, 5, 0, 12], [-1, -1, -1, -1, -1, -1, -1, 0]] bellman_ford(graph1, 0) # 输出“图中存在负权环”
以上代码定义了一个名为bellman_ford的函数,输入参数为一个邻接矩阵graph和源点start,输出为源点到各点的最短路径。对于包含负权边的图,当存在负权环时,函数会输出警告信息“图中存在负权环”。
我们创建了一个示例图graph,并选取顶点0作为源点,运行程序,得到的输出为[0, 4, 3, 5, 13, 10, 7, 16],即源点0到各点的最短路径长度。其中inf表示无穷大。另外,我们手动在原来的示例图graph中添加了一条负权边(-4),重新运行程序,可以得到输出“图中存在负权环”。
相关文章