Python以及c语言学习者加群交流:651707058
以下为代码以及运行结果截图
先贴上代码,再稍微讲一下过程吧。如图,示范代码是计算D点到各点的最短路径。
main.py:
from func import *
#无向图数据:开始计算最短路径用的rout来存储结构,后来网络分析模块必须要rout_list格式制作权值表
# 由于不想统一成rout_list,因为要改算法,就没管,路径数据保留了两份,等以后有时间了再改
rout = {'AB':12,'AG':14,'AF':16,'BF':7,'BC':10,'GF':9,\
'GE':8,'CF':6,'EF':2,'CD':3,'CE':5,'ED':4}
rout_list = [('A','B',12),('A','G',14),('A','F',16),('B','F',7),\
('B','C',10),('G','F',9),('G','E',8),('C','F',6),\
('E','F',2),('C','D',3),('C','E',5),('E','D',4)]
inf = float('inf')#无穷大
cloest_rout = [['D']]
S = {'D':0} #确定最短路径集合
U = {'A':inf,'B':inf,'C':inf,'E':inf,'F':inf,'G':inf} #未确定的最短路径集合
while(U != {}): #直到未确定最短路径为空,才最终确定完最短路径
findCloestrout(inf,rout,S,U,cloest_rout)
for list1 in cloest_rout:
print(list1[-1]+':',end='')
print('->'.join(list1))
print('最短路径集合:',S)
draw(rout,rout_list)
func.py:
import copy
import networkx as nx #导入网络分析模块
import matplotlib.pyplot as plt#图形绘制模块
#以下为求解最短路径
def findCloestrout(inf,rout,S,U,cloest_rout):
key_UtoS = {} #记录u的每个key到D点会通过哪个已经确定的最短路径,用于后面输出最短路线
for key in U:
for key2 in S:
if key+key2 in rout:
if rout[key+key2]+S[key2] <= U[key]: #保持存储最小值
U[key] = rout[key+key2]+S[key2]
key_UtoS[key] = key2
elif key2+key in rout:
if rout[key2+key]+S[key2] <= U[key]:
U[key] = rout[key2+key]+S[key2]
key_UtoS[key] = key2
else:
continue
min_value = inf
key_min = None
for key in U: #找最小的路径
if U[key]<min_value:
min_value = U[key]
key_min = key
del U[key_min]#从未确定的最短路径集合删除可以确定的最短路径
S[key_min] = min_value#添加已经确定的最短路径
for num in range(len(cloest_rout)):
if cloest_rout[num][-1] == key_UtoS[key_min]:
temp_list = copy.deepcopy(cloest_rout[num])#这里一定要深拷贝,不然后一改全改
temp_list.append(key_min)
cloest_rout.append(temp_list)
# 以下为绘制带权值无向图
def draw(rout,rout_list):
G = nx.Graph() # 创建一个空图
G.add_weighted_edges_from(rout_list) # 添加权值边
weight_list = {}
for it in rout_list: # 制作一个全权值表
weight_list[it[0], it[1]] = it[2]
pos = nx.spring_layout(G) # 设置点的布局
nx.draw_networkx_edge_labels(G, pos, weight_list, font_size=10) # 绘制权值
nx.draw(G, pos, node_color='g', edge_color='r', with_labels=True, \
font_color='b', font_size=20, node_size=800) # 绘制权值边
plt.show() # 显示绘图
这也是老师给我布置的一个作业,交上去的时候,47行代码完成了最短路径求解和绘制无向权值图,比c++代码量少很多。结果老师让我把每条最短路径的路线也输出出来。于是,自己又改了,现在代码量似乎有点多,但还可以接受。另外我这个无向权值图的数据源最好写成文件形式,读入在把结果输出到控制台比较好。
我参考算法原理的文档,这应该比我自己来说好一些:
https://blog.csdn.net/yalishadaa/article/details/55827681
看此文档中的图片,然后理清思路就足以想通算法了。
其中绘制无向权值图,怎么标记边的权值,我参考的文档:
https://blog.csdn.net/weixin_40198632/article/details/78800947
绘制无向权值图,边和节点,参考的文档:
https://blog.csdn.net/qq951127336/article/details/54586869