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使用新浪微博api上传图片到微博示例
Jan 10 Python
使用Python实现BT种子和磁力链接的相互转换
Nov 09 Python
python交互式图形编程实例(二)
Nov 17 Python
Python3多线程爬虫实例讲解代码
Jan 05 Python
python3实现多线程聊天室
Dec 12 Python
Python 做曲线拟合和求积分的方法
Dec 29 Python
Flask框架工厂函数用法实例分析
May 25 Python
200行python代码实现2048游戏
Jul 17 Python
pandas的to_datetime时间转换使用及学习心得
Aug 11 Python
python opencv 图像边框(填充)添加及图像混合的实现方法(末尾实现类似幻灯片渐变的效果)
Mar 09 Python
Python如何实现线程间通信
Jul 30 Python
利用Python读取微信朋友圈的多种方法总结
Aug 23 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网页游戏学习之Xnova(ogame)源码解读(七)
2014/06/23 PHP
php在apache环境下实现gzip配置方法
2015/04/02 PHP
php文件操作之小型留言本实例
2015/06/20 PHP
php封装的smarty类完整实例
2016/10/19 PHP
PHP面向对象程序设计之类与反射API详解
2016/12/02 PHP
Mac系统下搭建Nginx+php-fpm实例讲解
2020/12/15 PHP
javascript创建数组之联合数组的使用方法示例
2013/12/26 Javascript
jquery validate 自定义验证方法介绍 日期验证
2014/02/27 Javascript
经过绑定元素时会多次触发mouseover和mouseout事件
2014/02/28 Javascript
jquery队列queue与原生模仿其实现方法分享
2014/03/25 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
jQuery满屏焦点图左右滚动特效代码分享
2015/09/07 Javascript
jQuery解析与处理服务器端返回xml格式数据的方法详解
2016/07/04 Javascript
Javascript 一些需要注意的细节(必看篇)
2017/07/08 Javascript
浅谈JsonObject中的key-value数据解析排序问题
2017/12/06 Javascript
vue全局组件与局部组件使用方法详解
2018/03/29 Javascript
使用vuex的state状态对象的5种方式
2018/04/19 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
vue-cli脚手架build目录下utils.js工具配置文件详解
2018/09/14 Javascript
详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)
2019/04/09 Javascript
vue实现图片按比例缩放问题操作
2020/08/11 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
Python中的高级数据结构详解
2015/03/27 Python
Python3.2中的字符串函数学习总结
2015/04/23 Python
python正则实现提取电话功能
2018/02/24 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
python 函数的缺省参数使用注意事项分析
2019/09/17 Python
linux系统下pip升级报错的解决方法
2021/01/31 Python
宝拉珍选美国官网:Paula’s Choice美国
2018/01/07 全球购物
CAT鞋加拿大官网:CAT Footwear加拿大
2020/08/05 全球购物
公司前台辞职报告
2014/01/19 职场文书
租房协议书样本
2014/08/20 职场文书
党章培训心得体会
2014/09/04 职场文书
2014年大学班级工作总结
2014/11/14 职场文书
助学金感谢信
2015/01/20 职场文书
员工工作失职检讨书范文!
2019/07/03 职场文书