在一个有向图G=(V,E)中,G中每一条边都有一个比例常数W(Weight)与之对应,如果想求G图中某一个顶点V0到其他顶点的最少W总和的值,这类问题就称为最短路径问题。一般讨论的方向有两种:
一个顶点到多个顶点的最短路径通常用Dijkstra算法求得。Dijkstra算法(迪杰斯特拉)是典型的最短路径路由算法,用于计算一个节点到其他所有节点的最短路径。主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。Dijkstra算法能得出最短路径的最优解,但由于它遍历计算的节点很多,所以效率低。可以用堆优化。
# 图为邻接表形式
# Dijkstra算法——通过边实现松弛
# 指定一个点到其他各顶点的路径——单源最短路径
# 初始化图参数
G = {1:{1:0,2:1,3:12},
2:{2:0,3:9,4:3},
3:{3:0,5:5},
4:{3:4,4:0,5:13,6:15},
5:{5:0,6:4},
6:{6:0}}
def Dijkstra(G,v0,INF=999):
""" 使用 Dijkstra 算法计算指定点 v0 到图 G 中任意点的最短路径的距离
INF 为设定的无限远距离值
此方法不能解决负权值边的图
"""
book = set()
minv = v0 # 源顶点到其余各顶点的初始路程
dis = dict((k,INF) for k in G.keys())
dis[v0] = 0
while len(book)
输出:{1: 0, 2: 1, 3: 8, 4: 4, 5: 13, 6: 17}
#图为邻接矩阵形式
NUMBER=6
INF=999
SIZE=7
Graph_Matrix=[[0]*SIZE for row in range(SIZE)]
def BuildGraph_Matrix(Path_Cost):
for i in range(1,SIZE):
for j in range(1,SIZE):
if i==j:
Graph_Matrix[i][j]=0
else:
Graph_Matrix[i][j]=INF
i=0
while i
Dijkstra算法只能求出某一点到其他顶点的最短距离,如果要求出图中任意两点甚至所有顶点间最短的距离,就必须使用Floyd算法。Floyd-Warshall算法(Floyd-Warshall algorithm)是解决任意两点间的最短路径的一种算法,可以正确处理有向图或负权的最短路径问题,同时也被用于计算有向图的传递闭包。Floyd-Warshall算法的时间复杂度为O(n^3),空间复杂度为O(n^2)。
从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从i到j,2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点u到节点v的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。
#有向图
SIZE=7
NUMBER=6
INF=999
Graph_Matrix=[[0]*SIZE for row in range(SIZE)]
distance=[[0]*SIZE for row in range(SIZE)]
def BuildGraph_Matrix(Path_Cost):
for i in range(1,SIZE):
for j in range(1,SIZE):
if i==j:
Graph_Matrix[i][j]=0
else:
Graph_Matrix[i][j]=INF
i=0
while i
输出:
0 20 50 45 77 140
999 0 30 25 57 120
999 999 0 999 28 95
999 999 999 0 32 95
999 999 999 999 0 67
999 999 999 999 999 0
#无向图(只需更改初始化图的长度数组部分代表)
for i in range(1,vertex_total+1):
for j in range(i,vertex_total+1):
distance[i][j]=Graph_Matrix[i][j]
distance[j][i]=Graph_Matrix[i][j]
输出:
0 20 50 45 77 140
20 0 30 25 57 120
50 30 0 55 28 95
45 25 55 0 32 95
77 57 28 32 0 67
140 120 95 95 67 0