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


Posted in Python onJune 21, 2019

迪杰斯特拉(Dijkstra)算法主要是针对没有负值的有向图,求解其中的单一起点到其他顶点的最短路径算法。

1 算法原理

迪杰斯特拉(Dijkstra)算法是一个按照路径长度递增的次序产生的最短路径算法。下图为带权值的有向图,作为程序中的实验数据。

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

其中,带权值的有向图采用邻接矩阵graph来进行存储,在计算中就是采用n*n的二维数组来进行存储,v0-v5表示数组的索引编号0-5,二维数组的值表示节点之间的权值,若两个节点不能通行,比如,v0->v1不能通行,那么graph[0,1]=+∞ (采用计算机中最大正整数来进行表示)。那如何求解从v0每个v节点的最短路径长度呢?

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

首先,引进一个辅助数组cost,它的每个值cost[i]表示当前所找到的从起始点v0到终点vi的最短路径的权值(长度花费),该数组的初态为:若从v0到vi有弧,则cost[i]为弧上的权值,否则置cost[i]为+∞。

显然,长度为:cost[j]=Min_i(graph[0,i] | v_i in V)的路径就是从v0出发的长度最短的一条最短路径。此路径为(v_0,v_j) ,那么下次长度次短的路径必定是弧(v_0,v_i)上的权值cost[i](v_i in V),或者是cost[k](v_k in S)和弧(v_k,v_i)的权值之和。其中V:待求解最短路径的节点j集合;S:已求解最短路径的节点集合。

2 算法流程

根据上面的算法原理分析,下面描述算法的实现流程。

初始化:初始化辅助数组cost,从v0出发到图上其余节点v的初始权值为:cost[i]=graph[0,i] | v_i in V ;初始化待求节点S集合,它的初始状态为始点,V集合,全部节点-始节点。

选择节点v_j ,使得cost[j]=Min ( cost[i] | v_i in V -S ) ,v_j 就是当前求的一条从v0出发的最短路径的终点,修改S集合,使得 S=S + V_j ,修改集合V = V - V_j。

修改从v0出发到节点V-S上任一顶点 v_k 可达的最短路径,若cost[j]+graph[j,k]<cost[k] ,则修改cost[k]为:cost[k]=cost[j]+graph[j,k] 。

重复操作2,3步骤,直到求解集合V中的所有节点为止。

其中最短路径的存储采用一个path整数数组,path[i]的值记录vi的前一个节点的索引,通过path一直追溯到起点,就可以找到从vi到起始节点的最短路径。比如起始节点索引为0,若path[3]=4, path[4]=0;那么节点v2的最短路径为,v0->v4->v3。

3 算法实现

采用python语言对第2节中的算法流程进行实现,关键代码如下。

3.1 最短路径代码

#!/bin/python
# -*- coding:utf-8 -*-

def dijkstra(graph, startIndex, path, cost, max):
  """
  求解各节点最短路径,获取path,和cost数组,
  path[i] 表示vi节点的前继节点索引,一直追溯到起点。
  cost[i] 表示vi节点的花费
  """
  lenth = len(graph)
  v = [0] * lenth
  # 初始化 path,cost,V
  for i in range(lenth):
    if i == startIndex:
      v[startIndex] = 1
    else:
      cost[i] = graph[startIndex][i]
      path[i] = (startIndex if (cost[i] < max) else -1)
  # print v, cost, path
  for i in range(1, lenth):
    minCost = max
    curNode = -1
    for w in range(lenth):
      if v[w] == 0 and cost[w] < minCost:
        minCost = cost[w]
        curNode = w
    # for 获取最小权值的节点
    if curNode == -1: break
    # 剩下都是不可通行的节点,跳出循环
    v[curNode] = 1
    for w in range(lenth):
      if v[w] == 0 and (graph[curNode][w] + cost[curNode] < cost[w]):
        cost[w] = graph[curNode][w] + cost[curNode] # 更新权值
        path[w] = curNode # 更新路径
    # for 更新其他节点的权值(距离)和路径
  return path

if __name__ == '__main__':
  max = 2147483647
  graph = [
    [max, max, 10, max, 30, 100],
    [max, max, 5, max, max, max],
    [max, max, max, 50, max, max],
    [max, max, max, max, max, 10],
    [max, max, max, 20, max, 60],
    [max, max, max, max, max, max],
    ]
  path = [0] * 6
  cost = [0] * 6
  print dijkstra(graph, 0, path, cost, max)

4 运行结果

 [0, -1, 0, 4, 0, 3]

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

Python 相关文章推荐
Python文件操作类操作实例详解
Jul 11 Python
浅析python中的分片与截断序列
Aug 09 Python
python3学生名片管理v2.0版
Nov 29 Python
在Python文件中指定Python解释器的方法
Feb 18 Python
Python实现账号密码输错三次即锁定功能简单示例
Mar 29 Python
python3人脸识别的两种方法
Apr 25 Python
python 直接赋值和copy的区别详解
Aug 07 Python
python随机数分布random均匀分布实例
Nov 27 Python
pytorch之Resize()函数具体使用详解
Feb 27 Python
vue学习笔记之动态组件和v-once指令简单示例
Feb 29 Python
执行Python程序时模块报错问题
Mar 26 Python
python中操作文件的模块的方法总结
Feb 04 Python
解决pyinstaller打包发布后的exe文件打开控制台闪退的问题
Jun 21 #Python
pyqt5移动鼠标显示坐标的方法
Jun 21 #Python
python解析xml简单示例
Jun 21 #Python
对pyqt5中QTabWidget的相关操作详解
Jun 21 #Python
python实现得到当前登录用户信息的方法
Jun 21 #Python
python-django中的APPEND_SLASH实现方法
Jun 21 #Python
Python2.7版os.path.isdir中文路径返回false的解决方法
Jun 21 #Python
You might like
PHP格式化显示时间date()函数代码
2018/10/03 PHP
PHP结合jquery ajax实现上传多张图片,并限制图片大小操作示例
2019/03/01 PHP
采用CSS和JS,刚好我最近有个站点要用到下拉菜单!
2006/06/26 Javascript
用javascript获取地址栏参数
2006/12/22 Javascript
用js实现的页面关键字密度查询代码
2007/12/27 Javascript
javascript 另一种图片滚动切换效果思路
2012/04/20 Javascript
使用PHP+JQuery+Ajax分页的实现
2013/04/23 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
JavaScript中数据结构与算法(四):串(BF)
2015/06/19 Javascript
jQuery实现手机版页面翻页效果的简单实例
2016/10/05 Javascript
JavaScript中关于iframe滚动条的去除和保留
2016/11/17 Javascript
JavaScript使用正则表达式获取全部分组内容的方法示例
2017/01/17 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
浅谈ES6 模板字符串的具体使用方法
2017/11/07 Javascript
详解基于Koa2开发微信二维码扫码支付相关流程
2018/05/16 Javascript
Angular实现模版驱动表单的自定义校验功能(密码确认为例)
2018/05/17 Javascript
react实现换肤功能的示例代码
2018/08/14 Javascript
socket io与vue-cli的结合使用的示例代码
2018/11/01 Javascript
p5.js实现故宫橘猫赏秋图动画
2019/10/23 Javascript
学前端,css与javascript重难点浅析
2020/06/11 Javascript
jquery实现有过渡效果的tab切换
2020/07/17 jQuery
vue自定义树状结构图的实现方法
2020/10/18 Javascript
[05:31]DOTA2英雄梦之声_第08期_莉娜
2014/06/23 DOTA
Python探索之实现一个简单的HTTP服务器
2017/10/28 Python
python实现石头剪刀布小游戏
2021/01/20 Python
Python分支语句与循环语句应用实例分析
2019/05/07 Python
python绘制直方图和密度图的实例
2019/07/08 Python
使用Python制作表情包实现换脸功能
2019/07/19 Python
python中使用paramiko模块并实现远程连接服务器执行上传下载功能
2020/02/29 Python
介绍下Java中==和equals的区别
2013/09/01 面试题
节约用电标语
2014/06/17 职场文书
员工安全责任书范本
2014/07/24 职场文书
园艺专业毕业生求职信
2014/09/02 职场文书
教师反腐倡廉演讲稿
2014/09/03 职场文书
爱心募捐通知范文
2015/04/27 职场文书
优秀团员主要事迹范文
2015/11/05 职场文书