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 相关文章推荐
pandas进行数据的交集与并集方式的数据合并方法
Jun 27 Python
浅析Python函数式编程
Oct 06 Python
对dataframe数据之间求补集的实例详解
Jan 30 Python
python中报错&quot;json.decoder.JSONDecodeError: Expecting value:&quot;的解决
Apr 29 Python
详解Python Qt的窗体开发的基本操作
Jul 14 Python
python连接PostgreSQL数据库的过程详解
Sep 18 Python
python3图片文件批量重命名处理
Oct 31 Python
python函数定义和调用过程详解
Feb 09 Python
Python连接Oracle之环境配置、实例代码及报错解决方法详解
Feb 11 Python
Django分组聚合查询实例分享
Apr 29 Python
Python调用REST API接口的几种方式汇总
Oct 19 Python
python区块链持久化和命令行接口实现简版
May 25 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
jquery对元素拖动排序示例
2014/01/16 Javascript
JS中FRAME的操作问题实例分析
2014/10/21 Javascript
2014 HTML5/CSS3热门动画特效TOP10
2014/12/07 Javascript
js仿土豆网带缩略图的焦点图片切换效果实现方法
2015/02/23 Javascript
jQuery使用元素属性attr赋值详解
2015/02/27 Javascript
jQuery选择器源码解读(四):tokenize方法的Expr.preFilter
2015/03/31 Javascript
浅析Node.js的Stream模块中的Readable对象
2015/07/29 Javascript
详解JavaScript中this关键字的用法
2016/05/26 Javascript
深入理解React中es6创建组件this的方法
2016/08/29 Javascript
给easyui的datebox控件添加清空按钮的实现方法
2016/11/09 Javascript
原生JS实现图片左右轮播
2016/12/30 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
EsLint入门学习教程
2017/02/17 Javascript
three.js中文文档学习之创建场景
2017/11/20 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
Vue表单输入绑定的示例代码
2018/11/01 Javascript
VUE 实现复制内容到剪贴板的两种方法
2019/04/24 Javascript
uni-app 支持多端第三方地图定位的方法
2020/01/03 Javascript
JS指定音频audio在某个时间点进行播放
2020/11/28 Javascript
python算法学习之桶排序算法实例(分块排序)
2013/12/18 Python
Python数组条件过滤filter函数使用示例
2014/07/22 Python
Python使用Pycrypto库进行RSA加密的方法详解
2016/06/06 Python
Python中input与raw_input 之间的比较
2017/08/20 Python
Django 连接sql server数据库的方法
2018/06/30 Python
在python中创建指定大小的多维数组方式
2019/11/28 Python
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
澳大利亚家具和家居用品在线商店:Interiors Online
2018/03/05 全球购物
美国家居装饰店:Pier 1
2019/09/04 全球购物
size?法国官网:英国伦敦的球鞋精品店
2020/03/15 全球购物
委托书范本
2014/04/02 职场文书
企业授权委托书范本
2014/04/02 职场文书
法人委托书范本
2014/04/04 职场文书
本科毕业生自荐信
2014/05/26 职场文书
幼儿教师师德师风演讲稿
2014/08/22 职场文书
2016年中学法制宣传日活动总结
2016/04/01 职场文书
导游词之桂林山水
2019/09/20 职场文书