Python程序设计项目6----Dijkstra算法求解最短路径、绘制无向权值图、指明最短路线

Python以及c语言学习者加群交流:651707058

以下为代码以及运行结果截图

《Python程序设计项目6----Dijkstra算法求解最短路径、绘制无向权值图、指明最短路线》

先贴上代码,再稍微讲一下过程吧。如图,示范代码是计算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

    原文作者:Dijkstra算法
    原文地址: https://blog.csdn.net/tobe_numberone/article/details/80658428
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞