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 30 Python
Python3.x和Python2.x的区别介绍
Feb 12 Python
Python创建文件和追加文件内容实例
Oct 21 Python
Django自定义认证方式用法示例
Jun 23 Python
Python编程实现正则删除命令功能
Aug 30 Python
python3.5 tkinter实现页面跳转
Jan 30 Python
python django框架中使用FastDFS分布式文件系统的安装方法
Jun 10 Python
python实现点击按钮修改数据的方法
Jul 17 Python
django实现更改数据库某个字段以及字段段内数据
Mar 31 Python
django API 中接口的互相调用实例
Apr 01 Python
Django表单提交后实现获取相同name的不同value值
May 14 Python
python 动态渲染 mysql 配置文件的示例
Nov 20 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如何执行非缓冲查询API
2016/07/22 PHP
实现PHP搜索加分页
2016/10/12 PHP
php的无刷新操作实现方法分析
2020/02/28 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
jQuery.prototype.init选择器构造函数源码思路分析
2013/02/05 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
2013/04/15 Javascript
javascript中的undefined和not defined区别示例介绍
2014/02/26 Javascript
jQuery中find()方法用法实例
2015/01/07 Javascript
Javascript实现飞动广告效果的方法
2015/05/25 Javascript
JavaScript实现基于十进制的四舍五入实例
2015/07/17 Javascript
Javascript 计算字符串在localStorage中所占字节数
2015/10/21 Javascript
适用于javascript开发者的Processing.js入门教程
2016/02/24 Javascript
用NODE.JS中的流编写工具是要注意的事项
2016/03/01 Javascript
jQuery实现左侧导航模块的显示与隐藏效果
2016/07/04 Javascript
Bootstrap源码解读网格系统(3)
2016/12/22 Javascript
浅谈angular2路由预加载策略
2017/10/04 Javascript
微信小程序画布圆形进度条显示效果
2020/11/17 Javascript
python通过exifread模块获得图片exif信息的方法
2015/03/16 Python
深入解答关于Python的11道基本面试题
2017/04/01 Python
Python内置函数—vars的具体使用方法
2017/12/04 Python
浅谈Django REST Framework限速
2017/12/12 Python
python opencv 直方图反向投影的方法
2018/02/24 Python
对Python Class之间函数的调用关系详解
2019/01/23 Python
Python filter过滤器原理及实例应用
2020/08/18 Python
解决html5中video标签无法播放mp4问题的办法
2017/05/07 HTML / CSS
乌克兰网上服装店:Bolf.ua
2018/10/30 全球购物
澳大利亚家庭花园和DIY工具网店:VidaXL
2019/05/03 全球购物
饿了么订餐官网:外卖、网上订餐
2019/06/28 全球购物
日本最大的购物网站:日本乐天市场(Rakuten Ichiba)
2020/11/04 全球购物
Java程序员面试90题
2013/10/19 面试题
社区交通安全实施方案
2014/03/22 职场文书
创建文明城市倡议书
2015/04/28 职场文书
员工福利申请报告
2015/05/15 职场文书
学生病假条范文
2015/08/17 职场文书
Axios代理配置及封装响应拦截处理方式
2022/04/07 Vue.js
关于对TypeScript泛型参数的默认值理解
2022/07/15 Javascript