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实现Decorator模式实例代码
Feb 09 Python
python opencv之分水岭算法示例
Feb 24 Python
浅谈Python2、Python3相对路径、绝对路径导入方法
Jun 22 Python
PyCharm鼠标右键不显示Run unittest的解决方法
Nov 30 Python
python使用magic模块进行文件类型识别方法
Dec 08 Python
python3 深浅copy对比详解
Aug 12 Python
python实现画出e指数函数的图像
Nov 21 Python
python实现猜数游戏
Mar 27 Python
Windows+Anaconda3+PyTorch+PyCharm的安装教程图文详解
Apr 03 Python
python matplotlib工具栏源码探析三之添加、删除自定义工具项的案例详解
Feb 25 Python
Python趣味实战之手把手教你实现举牌小人生成器
Jun 07 Python
python实现简单石头剪刀布游戏
Oct 24 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
星际争霸 Starcraft 游戏介绍
2020/03/14 星际争霸
PHP转盘抽奖接口实例
2015/02/09 PHP
php中引用符号(&amp;)的使用详细介绍
2016/12/06 PHP
Yii框架连表查询操作示例
2019/09/06 PHP
select组合框option的捕捉实例代码
2008/09/30 Javascript
ajax无刷新动态调用股票信息(改良版)
2008/11/01 Javascript
Javascript 获取滚动条位置等信息的函数
2009/09/08 Javascript
js获取url中指定参数值的示例代码
2013/12/14 Javascript
JS实现的数组全排列输出算法
2015/03/19 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
Vue.js快速入门教程
2016/09/07 Javascript
原生javascript实现的ajax异步封装功能示例
2016/11/03 Javascript
JS中用childNodes获取子元素换行会产生一个子元素
2016/12/08 Javascript
深入学习Bootstrap表单
2016/12/13 Javascript
js防刷新的倒计时代码 js倒计时代码
2017/09/06 Javascript
Bootstrap table使用方法汇总
2017/11/17 Javascript
vue-cli开发环境实现跨域请求的方法
2018/04/07 Javascript
Javascript中parseInt的正确使用方式
2018/10/17 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
JavaScript相等运算符的九条规则示例详解
2019/10/20 Javascript
解决vue页面刷新,数据丢失的问题
2020/11/24 Vue.js
[01:13:18]Secret vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第一场 8.23
2019/09/05 DOTA
python实现批量注册网站用户的示例
2019/02/22 Python
django框架模板语言使用方法详解
2019/07/18 Python
python之PyQt按钮右键菜单功能的实现代码
2019/08/17 Python
PYTHON如何读取和写入EXCEL里面的数据
2019/10/28 Python
给Python学习者的文件读写指南(含基础与进阶)
2020/01/29 Python
windows、linux下打包Python3程序详细方法
2020/03/17 Python
python读取hdfs上的parquet文件方式
2020/06/06 Python
Css3新特性应用之视觉效果实例
2016/12/12 HTML / CSS
2014三八妇女节活动总结范文四篇
2014/03/09 职场文书
基层工作经验证明样本
2014/11/16 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
党员转正党支部意见
2015/06/02 职场文书
煤矿隐患排查制度
2015/08/05 职场文书
CSS font-variation 可变字体的魅力(实例详解)
2022/03/03 HTML / CSS