经典的图论问题
求0~4四个点中两点间的最短距离和其路径。
弗洛伊德算法的代码如下
import numpy as np
import networkx as nx
from numpy import inf
from matplotlib import pyplot as plt
def Floyd(A):
'''
弗洛伊德算法
created by yzy
2022.8.3
'''
# A=np.array([[inf,3,inf,2,inf],
# [3,inf,2,1,inf],
# [inf,2,inf,inf,5],
# [2,1,inf,inf,4],
# [inf,inf,5,4,inf]])
n,m=A.shape
dis=A #邻接矩阵包含了任意两个节点之间的距离,distance
path=np.zeros((n,n)) #初始化路由矩阵,让它都是零
for k in range(n):
for i in range(n):
for j in range(n):
if dis[i][k]+dis[k][j]<dis[i][j]:
dis[i][j]=dis[i][k]+dis[j][k] #找到经过k点时路径更短,接受这个更短的路径长度
path[i][j]=k #路由矩阵记录路径
print("dis:",dis) #显示每对顶点最短路径长度
print("path:",path) #显示路由矩阵
#我们以0到4 点为例,最短距离是6。path[0][4]=3,该路径经过点3,反向追踪:path[0][3]=0,结束;正向追踪:
# path[3][4]=0,结束。最短路径就是0->3->4。看一看前面的图,的确符合事实。
def drawMat(A):
'''
画无向赋权图
created by yzy
2022.8.3
'''
# A=np.mat([[0,3,0,2,0],
# [3,0,2,1,0],
# [0,2,0,0,5],
# [2,1,0,0,4],
# [0,0,5,4,0]]) #邻接矩阵
G=nx.Graph(A) #无向赋权图
pos=nx.shell_layout(G) #布局设置
w=nx.get_edge_attributes(G,"weight") #获取权重
nx.draw_networkx(G=G,pos=pos,node_size=260) #画网络图
nx.draw_networkx_edge_labels(G=G,pos=pos,font_size=12,edge_labels=w) #标注权重
plt.show()
if __name__ == '__main__':
A=np.array([[inf,3,inf,2,inf],
[3,inf,2,1,inf],
[inf,2,inf,inf,5],
[2,1,inf,inf,4],
[inf,inf,5,4,inf]])
n, m = A.shape
#这里注意,B=A赋值法是错的,地址没变,只能一个元素一个元素的赋值
B=np.zeros((n,n))
for i in range(n):
for j in range(n):
B[i][j]=A[i][j]
for i in range(n):
# print(i),是从0到n-1哦
for j in range(n):
if A[i][j]==inf :
B[i][j]=0
# print("A",A)
# print("B",B)
drawMat(B)
Floyd(A)
输出的一个是路由矩阵,一个是距离矩阵
代码里一个是画图的,一个是算矩阵的
要手动修改邻接矩阵,自己看着图手写出来邻接矩阵
输出结果为
dis: [[4. 3. 5. 2. 6.]
[3. 2. 2. 1. 5.]
[5. 2. 4. 3. 5.]
[2. 1. 3. 2. 4.]
[6. 5. 5. 4. 8.]]
path: [[3. 0. 1. 0. 3.]
[0. 3. 0. 0. 3.]
[1. 0. 1. 1. 0.]
[0. 0. 1. 1. 0.]
[3. 3. 0. 0. 3.]]
path的含义代码里有解释