python Dijkstra算法实现最短路径问题的方法


Posted in Python onSeptember 19, 2019

本文借鉴于张广河教授主编的《数据结构》,对其中的代码进行了完善。

从某源点到其余各顶点的最短路径

Dijkstra算法可用于求解图中某源点到其余各顶点的最短路径。假设G={V,{E}}是含有n个顶点的有向图,以该图中顶点v为源点,使用Dijkstra算法求顶点v到图中其余各顶点的最短路径的基本思想如下:

  • 使用集合S记录已求得最短路径的终点,初始时S={v}。
  • 选择一条长度最小的最短路径,该路径的终点w属于V-S,将w并入S,并将该最短路径的长度记为Dw。
  • 对于V-S中任一顶点是s,将源点到顶点s的最短路径长度记为Ds,并将顶点w到顶点s的弧的权值记为Dws,若Dw+Dws<Ds,
  • 则将源点到顶点s的最短路径长度修改为Dw+Ds=ws。
  • 重复执行2和3,知道S=V。
  • 为了实现算法,
  • 使用邻接矩阵Arcs存储有向网,当i=j时,Arcs[i][j]=0;当i!=j时,若下标为i的顶点到下标为j的顶点有弧且弧的权值为w,则Arcs[i][j]=w,否则Arcs[i][j]=float(‘inf')即无穷大。
  • 使用Dist存储源点到每一个终点的最短路径长度。
  • 使用列表Path存储每一条最短路径中倒数第二个顶点的下标。
  • 使用flag记录每一个顶点是否已经求得最短路径,在思想中即是判断顶点是属于V集合,还是属于V-S集合。

代码实现

#构造有向图Graph
class Graph:
  def __init__(self,graph,labels): #labels为标点名称
    self.Arcs=graph
    self.VertexNum=graph.shape[0]
    self.labels=labels
def Dijkstra(self,Vertex,EndNode): #Vertex为源点,EndNode为终点
  Dist=[[] for i in range(self.VertexNum)] #存储源点到每一个终点的最短路径的长度
  Path=[[] for i in range(self.VertexNum)] #存储每一条最短路径中倒数第二个顶点的下标
  flag=[[] for i in range(self.VertexNum)] #记录每一个顶点是否求得最短路径
  index=0
  #初始化
  while index<self.VertexNum:
    Dist[index]=self.Arcs[Vertex][index]
    flag[index]=0
    if self.Arcs[Vertex][index]<float('inf'): #正无穷
      Path[index]=Vertex
    else:
      Path[index]=-1 #表示从顶点Vertex到index无路径
    index+=1
  flag[Vertex]=1
  Path[Vertex]=0
  Dist[Vertex]=0
  index=1
  while index<self.VertexNum:
    MinDist=float('inf')
    j=0
    while j<self.VertexNum:
      if flag[j]==0 and Dist[j]<MinDist:
        tVertex=j #tVertex为目前从V-S集合中找出的距离源点Vertex最断路径的顶点
        MinDist=Dist[j]
      j+=1
    flag[tVertex]=1
    EndVertex=0
    MinDist=float('inf') #表示无穷大,若两点间的距离小于MinDist说明两点间有路径
    #更新Dist列表,符合思想中第三条
    while EndVertex<self.VertexNum:
      if flag[EndVertex]==0:
        if self.Arcs[tVertex][EndVertex]<MinDist and Dist[
          tVertex]+self.Arcs[tVertex][EndVertex]<Dist[EndVertex]:
          Dist[EndVertex]=Dist[tVertex]+self.Arcs[tVertex][EndVertex]
          Path[EndVertex]=tVertex
      EndVertex+=1
    index+=1
  vertex_endnode_path=[] #存储从源点到终点的最短路径
  return Dist[EndNode],start_end_Path(Path,Vertex,EndNode,vertex_endnode_path)
#根据本文上述定义的Path递归求路径
def start_end_Path(Path,start,endnode,path):
  if start==endnode:
    path.append(start)
  else:
    path.append(endnode)
    start_end_Path(Path,start,Path[endnode],path)
  return path

if __name__=='__main__':
  #float('inf')表示无穷
  graph=np.array([[0,6,5,float('inf'),float('inf'),float('inf')],
          [float('inf'),0,2,8,float('inf'),float('inf')],
          [float('inf'),float('inf'),0,float('inf'),3,float('inf')],
          [float('inf'),float('inf'),7,0,float('inf'),9],
          [float('inf'),float('inf'),float('inf'),float('inf'),0,9],
          [float('inf'),float('inf'),float('inf'),float('inf'),0]])
  G=Graph(graph,labels=['a','b','c','d','e','f'])
  start=input('请输入源点')
  endnode=input('请输入终点')
  dist,path=Dijkstra(G,G.labels.index(start),G.labels.index(endnode))
  Path=[]
  for i in range(len(path)):
    Path.append(G.labels[path[len(path)-1-i]])
  print('从顶点{}到顶点{}的最短路径为:\n{}\n最短路径长度为:{}'.format(start,endnode,Path,dist))

输出结果如下:

请输入源点
a
请输入终点
f
从顶点a到顶点f的最短路径为:
['a', 'c', 'e', 'f']
最短路径长度为:17

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
布同自制Python函数帮助查询小工具
Mar 13 Python
教大家使用Python SqlAlchemy
Feb 12 Python
Python序列循环移位的3种方法推荐
Apr 09 Python
Python基于递归实现电话号码映射功能示例
Apr 13 Python
numpy 进行数组拼接,分别在行和列上合并的实例
May 08 Python
python调用OpenCV实现人脸识别功能
May 25 Python
python中使用zip函数出现错误的原因
Sep 28 Python
24式加速你的Python(小结)
Jun 13 Python
python学生管理系统的实现
Apr 05 Python
Python爬虫爬取新闻资讯案例详解
Jul 14 Python
python 下划线的多种应用场景总结
May 12 Python
python实现MD5进行文件去重的示例代码
Jul 09 Python
PHP统计代码行数的小代码
Sep 19 #Python
Python实现代码统计工具
Sep 19 #Python
python实现统计代码行数的小工具
Sep 19 #Python
python日志模块logbook使用方法
Sep 19 #Python
python统计指定目录内文件的代码行数
Sep 19 #Python
python如何从文件读取数据及解析
Sep 19 #Python
python实现代码统计器
Sep 19 #Python
You might like
php判断变量类型常用方法
2012/04/24 PHP
php截取后台登陆密码的代码
2012/05/05 PHP
PHP7 新特性详细介绍
2016/09/06 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
PHP实现的62进制转10进制,10进制转62进制函数示例
2019/06/06 PHP
php项目中类的自动加载实例讲解
2019/09/12 PHP
Add a Table to a Word Document
2007/06/15 Javascript
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
用jQuery模拟页面加载进度条的实现代码
2011/12/19 Javascript
ASP.NET jQuery 实例11 通过使用jQuery validation插件简单实现用户登录页面验证功能
2012/02/03 Javascript
jQuery 过滤not()与filter()实例代码
2012/05/10 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
浅谈JavaScript函数参数的可修改性问题
2013/12/05 Javascript
js中浮点型运算BUG的解决方法说明
2014/01/06 Javascript
jQuery插件实现大图全屏图片相册
2015/03/14 Javascript
Centos7 中 Node.js安装简单方法
2016/11/02 Javascript
基于input动态模糊查询的实现方法
2017/12/12 Javascript
微信小程序实现手势图案锁屏功能
2018/01/30 Javascript
vue 使用Jade模板写html,stylus写css的方法
2018/02/23 Javascript
angularJS自定义directive之带参方法传递详解
2018/10/09 Javascript
原生JS封装拖动验证滑块的实现代码示例
2020/06/01 Javascript
JS访问对象两种方式区别解析
2020/08/29 Javascript
vue 项目软键盘回车触发搜索事件
2020/09/09 Javascript
python中cPickle用法例子分享
2014/01/03 Python
Python实现求最大公约数及判断素数的方法
2015/05/26 Python
python实现爬虫下载美女图片
2015/07/14 Python
Python wxPython库消息对话框MessageDialog用法示例
2018/09/03 Python
pygame游戏之旅 如何制作游戏障碍
2018/11/20 Python
Python3常用内置方法代码实例
2019/11/18 Python
Python填充任意颜色,不同算法时间差异分析说明
2020/05/16 Python
python 爬虫爬取京东ps4售卖情况
2020/12/18 Python
你的自行车健身专家:FaFit24
2016/11/16 全球购物
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
泰国在线书店:SE-ED
2020/06/21 全球购物
党员教师学习党的群众路线教育实践活动心得体会
2014/10/31 职场文书
python 安全地删除列表元素的方法
2022/03/16 Python