Python实现迪杰斯特拉算法过程解析


Posted in Python onSeptember 18, 2020

一、 迪杰斯特拉算法思想

Dijkstra算法主要针对的是有向图的单元最短路径问题,且不能出现权值为负的情况!Dijkstra算法类似于贪心算法,其应用根本在于最短路径的最优子结构性质。

最短路径的最优子结构性质:

如果P(i,j)={Vi…Vk…Vs…Vj}是从顶点i到j的最短路径,k和s是这条路径上的一个中间顶点,那么P(k,s)必定是从k到s的最短路径。

证明:

假设P(i,j)={Vi…Vk…Vs…Vj}是从顶点i到j的最短路径,则有P(i,j)=P(i,k)+P(k,s)+P(s,j)。而P(k,s)不是从k到s的最短距离,那么必定存在另一条从k到s的最短路径P(k,s),那么P(i,j)=P(i,k)+P(k,s)+P(s,j)<P(i,j)。则与P(i,j)是从i到j的最短路径相矛盾。因此该性质得证。

因此,Dijkstra算法描述如下:

Dijikstra算法描述如下:

假设存在G=<V,E>,源顶点为V0,S={V0},distance[i]记录V0到i的最短距离,matrix[i][j]记录从i到j的边的权值,即两点之间的距离。

1)从V-S中选择使dist[i]值最小的顶点i,将i加入到U中;

2)更新与i直接相邻顶点的dist值。dist[j]=min{dist[j],dist[i]+matrix[i][j]}

3)直到S=V,所有顶点都包含进来了,算法停止。

二、 具体操作步骤

根据其算法思想,确立操作步骤如下:

(1) 初始时,S只包含起点s;U包含除s外的其他顶点,且U中顶点的距离为"起点s到该顶点的距离"[例如,U中顶点v的距离为(s,v)的长度,然后s和v不相邻,则v的距离为∞]。

(2) 从U中选出"距离最短的顶点k",并将顶点k加入到S中;同时,从U中移除顶点k。

(3) 更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。

(4) 重复步骤(2)和(3),直到遍历完所有顶点。

三、代码

def dijkstra(s, used, cost, distance, n):
  distance[s] = 0
  while True:
    # v在这里相当于是一个哨兵,对包含起点s做统一处理!
    v = -1
    # 从未使用过的顶点中选择一个距离最小的顶点
    for u in range(n):
      if not used[u] and (v == -1 or distance[u] < distance[v]):
        v = u
    if v == -1:
      # 说明所有顶点都维护到S中了!
      break

    # 将选定的顶点加入到S中, 同时进行距离更新
    used[v] = True
    # 更新U中各个顶点到起点s的距离。之所以更新U中顶点的距离,是由于上一步中确定了k是求出最短路径的顶点,从而可以利用k来更新其它顶点的距离;例如,(s,v)的距离可能大于(s,k)+(k,v)的距离。
    for u in range(n):
      distance[u] = min(distance[u], distance[v] + cost[v][u])

  return distance


n, m, T = map(int, input().split())

# 标记数组:used[v]值为False说明改顶点还没有访问过,在S中,否则在U中!
used = [False for _ in range(n)]
# 距离数组:distance[i]表示从源点s到i的最短距离,distance[s]=0
distance = [float('inf') for _ in range(n)]
# cost[u][v]表示边e=(u,v)的权值,不存在时设为INF
cost = [[float('inf') for _ in range(n)] for _ in range(n)]

for _ in range(m):
  e = list(map(int, input().split()))
  cost[e[0] - 1][e[1] - 1] = e[2]

dis1 = dijkstra(0, used[:], cost, distance[:], n)
d1 = dis1[-1]
dis2 = dijkstra(n-1, used[:], cost, distance[:], n)
d2 = dis2[0]

print((d1+d2)*T)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
35个Python编程小技巧
Apr 01 Python
详解C++编程中一元运算符的重载
Jan 19 Python
Python数据类型详解(一)字符串
May 08 Python
详解python如何在django中为用户模型添加自定义权限
Oct 15 Python
500行Python代码打造刷脸考勤系统
Jun 03 Python
pyqt 多窗口之间的相互调用方法
Jun 19 Python
Python Django 封装分页成通用的模块详解
Aug 21 Python
Python matplotlib绘制饼状图功能示例
Sep 10 Python
Python高级property属性用法实例分析
Nov 19 Python
Python Django form 组件动态从数据库取choices数据实例
May 19 Python
python切割图片的示例
Nov 12 Python
用python查找统一局域网下ip对应的mac地址
Jan 13 Python
Python 操作 MySQL数据库
Sep 18 #Python
python实现人工蜂群算法
Sep 18 #Python
Python猫眼电影最近上映的电影票房信息
Sep 18 #Python
python实现简单遗传算法
Sep 18 #Python
详解python 支持向量机(SVM)算法
Sep 18 #Python
python利用线程实现多任务
Sep 18 #Python
Pycharm的Available Packages为空的解决方法
Sep 18 #Python
You might like
PHP判断表单复选框选中状态完整例子
2014/06/24 PHP
PHP中绘制图像的一些函数总结
2014/11/19 PHP
Jquery判断IE6等浏览器的代码
2011/04/05 Javascript
Javascript 按位左移运算符使用介绍(
2014/02/04 Javascript
node.js中的fs.fchmodSync方法使用说明
2014/12/16 Javascript
jquery 重写 ajax提交并判断权限后 使用load方法报错解决方法
2016/01/19 Javascript
原生js实现图片层叠轮播切换效果
2016/02/02 Javascript
JavaScript遍历求解数独问题的主要思路小结
2016/06/12 Javascript
javascript中sort排序实例详解
2016/07/24 Javascript
window.open打开窗口被拦截的快速解决方法
2016/08/04 Javascript
前端图片懒加载(lazyload)的实现方法(提高用户体验)
2017/08/21 Javascript
vue系列之动态路由详解【原创】
2017/09/10 Javascript
Angular中使用MathJax遇到的一些问题
2017/12/15 Javascript
浅谈Vue.js组件(二)
2019/04/09 Javascript
Vue插件之滑动验证码
2019/09/21 Javascript
Vue监听滚动实现锚点定位(双向)示例
2019/11/13 Javascript
详解vue路由
2020/08/05 Javascript
Nuxt.js 静态资源和打包的操作
2020/11/06 Javascript
Python中的yield浅析
2014/06/16 Python
python连接oracle数据库实例
2014/10/17 Python
Python对列表去重的多种方法(四种方法)
2017/12/05 Python
Python程序包的构建和发布过程示例详解
2019/06/09 Python
python清空命令行方式
2020/01/13 Python
OpenCV中VideoCapture类的使用详解
2020/02/14 Python
python GUI库图形界面开发之PyQt5多线程中信号与槽的详细使用方法与实例
2020/03/08 Python
python实现数据结构中双向循环链表操作的示例
2020/10/09 Python
使用CSS3来制作消息提醒框
2015/07/12 HTML / CSS
HTML5语音识别标签写法附图
2013/11/18 HTML / CSS
html5视频常用API接口的实战示例
2020/03/20 HTML / CSS
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
车祸赔偿收入证明
2014/01/09 职场文书
班组安全员工作职责
2014/02/01 职场文书
中文专业毕业生自荐信
2014/05/24 职场文书
公务员年终个人总结
2015/02/12 职场文书
小学毕业感言200字
2015/07/30 职场文书
Golang 语言控制并发 Goroutine的方法
2021/06/30 Golang