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获取本地计算机名字的方法
Apr 29 Python
python基础教程之分支、循环简单用法
Jun 16 Python
Python实现查找匹配项作处理后再替换回去的方法
Jun 10 Python
梯度下降法介绍及利用Python实现的方法示例
Jul 12 Python
Python3实现的画图及加载图片动画效果示例
Jan 19 Python
Python3实现购物车功能
Apr 18 Python
Python实现SQL注入检测插件实例代码
Feb 02 Python
Python aiohttp百万并发极限测试实例分析
Oct 26 Python
pytorch 指定gpu训练与多gpu并行训练示例
Dec 31 Python
python requests模块的使用示例
Apr 07 Python
Python实现拼音转换
Jun 07 Python
Python实现排序方法常见的四种
Jul 15 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
WINDOWS下php5.2.4+mysql6.0+apache2.2.4+ZendOptimizer-3.3.0配置
2008/03/28 PHP
深入php多态的实现详解
2013/06/09 PHP
一个比较不错的PHP日历类分享
2014/11/18 PHP
CI框架中通过hook的方式实现简单的权限控制
2015/01/07 PHP
extjs之去除s.gif的影响
2010/12/25 Javascript
PHPExcel中的一些常用方法汇总
2015/01/23 Javascript
谈谈JavaScript中的几种借用方法
2016/08/09 Javascript
JavaScript使用键盘输入控制实现数字验证功能
2016/08/19 Javascript
基于Nodejs利用socket.io实现多人聊天室
2017/02/22 NodeJs
无循环 JavaScript(map、reduce、filter和find)
2017/04/08 Javascript
jquery 校验中国身份证号码实例详解
2017/04/11 jQuery
如何使用angularJs
2017/05/08 Javascript
VUE多层路由嵌套实现代码
2017/05/15 Javascript
解决Extjs下拉框不显示的问题
2017/06/21 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
360提示[高危]使用存在漏洞的JQuery版本的解决方法
2017/10/27 jQuery
简化版的vue-router实现思路详解
2018/10/19 Javascript
Vue对象赋值视图不更新问题及解决方法
2019/06/03 Javascript
详解element-ui设置下拉选择切换必填和非必填
2019/06/17 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
2020/08/27 Javascript
[03:36]2014DOTA2 TI小组赛综述 八强诞生进军钥匙球馆
2014/07/15 DOTA
python数据结构链表之单向链表(实例讲解)
2017/07/25 Python
Python基于OpenCV实现视频的人脸检测
2018/01/23 Python
Python3网络爬虫开发实战之极验滑动验证码的识别
2019/08/02 Python
Python时间序列缺失值的处理方法(日期缺失填充)
2019/08/11 Python
python 如何去除字符串头尾的多余符号
2019/11/19 Python
布隆过滤器的概述及Python实现方法
2019/12/08 Python
Pandas直接读取sql脚本的方法
2021/01/21 Python
css3中background新增的4个新的相关属性用法介绍
2013/09/26 HTML / CSS
详解css3中 text-fill-color属性
2019/07/08 HTML / CSS
德国古洛迷亚百货官网:GALERIA Kaufhof
2017/06/20 全球购物
德国50岁以上交友网站:Lebensfreunde
2020/03/18 全球购物
幼儿园师德师风心得体会
2016/01/12 职场文书
Node实现搜索框进行模糊查询
2021/06/28 Javascript
JavaScript原型链详解
2021/11/07 Javascript
MySQL创建管理HASH分区
2022/04/13 MySQL