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实现排序算法
Feb 14 Python
python中sleep函数用法实例分析
Apr 29 Python
Python实现的RSS阅读器实例
Jul 25 Python
Python实现模拟登录及表单提交的方法
Jul 25 Python
5款非常棒的Python工具
Jan 05 Python
python 计算平均平方误差(MSE)的实例
Jun 29 Python
利用python-pypcap抓取带VLAN标签的数据包方法
Jul 23 Python
PyCharm 配置远程python解释器和在本地修改服务器代码
Jul 23 Python
python try except返回异常的信息字符串代码实例
Aug 15 Python
python实现生成Word、docx文件的方法分析
Aug 30 Python
Python 基于wxpy库实现微信添加好友功能(简洁)
Nov 29 Python
Python greenlet和gevent使用代码示例解析
Apr 01 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的类 功能齐全的发送邮件类
2006/10/09 PHP
PHP性能优化工具篇Benchmark类调试执行时间
2011/12/06 PHP
php中instanceof 与 is_a()区别分析
2015/03/03 PHP
PHP面向对象程序设计之对象克隆clone和魔术方法__clone()用法分析
2019/06/12 PHP
JS 控制非法字符的输入代码
2009/12/04 Javascript
juqery 学习之三 选择器 层级 基本
2010/11/25 Javascript
父子窗体间传递JSON格式的数据的代码
2010/12/25 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
50 个 jQuery 插件可将你的网站带到另外一个高度
2016/04/26 Javascript
js实现文字超出部分用省略号代替实例代码
2016/09/01 Javascript
总结Javascript中数组各种去重的方法
2016/10/04 Javascript
jquery 实现回车登录详解及实例代码
2016/10/23 Javascript
AngularJS的Filter的示例详解
2017/03/07 Javascript
基于JS对象创建常用方式及原理分析
2017/06/28 Javascript
js事件委托和事件代理案例分享
2017/07/25 Javascript
Bootstrap 模态框多次显示后台提交多次BUG的解决方法
2017/12/26 Javascript
jquery实现搜索框功能实例详解
2018/07/23 jQuery
在vue中使用Base64转码的案例
2020/08/07 Javascript
vue中解决微信html5原生ios虚拟键返回不刷新问题
2020/10/20 Javascript
使用python编写脚本获取手机当前应用apk的信息
2014/07/21 Python
TensorFlow变量管理详解
2018/03/10 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
python Django里CSRF 对应策略详解
2019/08/05 Python
Python爬虫库requests获取响应内容、响应状态码、响应头
2020/01/25 Python
Python日志logging模块功能与用法详解
2020/04/09 Python
在Python中使用K-Means聚类和PCA主成分分析进行图像压缩
2020/04/10 Python
Python并发爬虫常用实现方法解析
2020/11/19 Python
Python+kivy BoxLayout布局示例代码详解
2020/12/28 Python
HTML5 语义化结构化规范化
2008/10/17 HTML / CSS
为什么如下的代码int a=100,b=100;long int c=a * b;不能工作
2013/11/29 面试题
学前教育毕业生自荐信
2013/10/29 职场文书
国旗下演讲稿
2014/05/08 职场文书
学习十八届四中全会依法治国心得体会
2014/11/03 职场文书
企业办公室主任岗位职责
2015/04/01 职场文书
剑指Offer之Java算法习题精讲二叉树专项训练
2022/03/21 Java/Android