python实现狄克斯特拉算法


Posted in Python onJanuary 17, 2019

一、简介

是从一个顶点到其余各顶点的最短路径算法,解决的是有向图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止

二、步骤

(1) 找出“最便宜”的节点,即可在最短时间内到达的节点。
(2) 更新该节点的邻居的开销,其含义将稍后介绍。
(3) 重复这个过程,直到对图中的每个节点都这样做了。
(4) 计算最终路径。

三、图解

python实现狄克斯特拉算法

上图中包括5个节点,箭头表示方向,线上的数字表示消耗时间。
首先根据上图做出一个初始表(父节点代表从哪个节点到达该节点):

python实现狄克斯特拉算法

然后从“起点”开始,根据图中的信息更新一下表,由于从“起点”不能直接到达“终点”节点,所以耗时为∞(无穷大):

python实现狄克斯特拉算法

有了这个表我们可以根据算法的步骤往下进行了。

第一步:找出“最便宜”的节点,这里是节点B:

python实现狄克斯特拉算法

第二步:更新该节点的邻居的开销,根据图从B出发可以到达A和“终点”节点,B目前的消耗2+B到A的消耗3=5,5小于原来A的消耗6,所以更新节点A相关的行:

python实现狄克斯特拉算法

同理,B目前消耗2+B到End的消耗5=7,小于∞,更新“终点”节点行:

python实现狄克斯特拉算法

B节点关联的节点已经更新完成,所以B节点不在后面的更新范围之内了:

python实现狄克斯特拉算法

找到下一个消耗最小的节点,那就是A节点:

python实现狄克斯特拉算法

根据A节点的消耗更新关联节点,只有End节点行被更新了:

python实现狄克斯特拉算法

这时候A节点也不在更新节点范围之内了:

python实现狄克斯特拉算法

最终表的数据如下:

python实现狄克斯特拉算法

根据最终表,从“起点”到“终点”的最少消耗是6,路径是起点->B->A->终点.

四、代码实现

# -*-coding:utf-8-*-
# 用散列表实现图的关系
# 创建节点的开销表,开销是指从"起点"到该节点的权重
graph = {}
graph["start"] = {}
graph["start"]["a"] = 6
graph["start"]["b"] = 2

graph["a"] = {}
graph["a"]["end"] = 1

graph["b"] = {}
graph["b"]["a"] = 3
graph["b"]["end"] = 5
graph["end"] = {}

# 无穷大
infinity = float("inf")
costs = {}
costs["a"] = 6
costs["b"] = 2
costs["end"] = infinity

# 父节点散列表
parents = {}
parents["a"] = "start"
parents["b"] = "start"
parents["end"] = None

# 已经处理过的节点,需要记录
processed = []


# 找到开销最小的节点
def find_lowest_cost_node(costs):
 # 初始化数据
 lowest_cost = infinity
 lowest_cost_node = None
 # 遍历所有节点
 for node in costs:
 # 该节点没有被处理
 if not node in processed:
  # 如果当前节点的开销比已经存在的开销小,则更新该节点为开销最小的节点
  if costs[node] < lowest_cost:
  lowest_cost = costs[node]
  lowest_cost_node = node
 return lowest_cost_node


# 找到最短路径
def find_shortest_path():
 node = "end"
 shortest_path = ["end"]
 while parents[node] != "start":
 shortest_path.append(parents[node])
 node = parents[node]
 shortest_path.append("start")
 return shortest_path


# 寻找加权的最短路径
def dijkstra():
 # 查询到目前开销最小的节点
 node = find_lowest_cost_node(costs)
 # 只要有开销最小的节点就循环(这个while循环在所有节点都被处理过后结束)
 while node is not None:
 # 获取该节点当前开销
 cost = costs[node]
 # 获取该节点相邻的节点
 neighbors = graph[node]
 # 遍历当前节点的所有邻居
 for n in neighbors.keys():
  # 计算经过当前节点到达相邻结点的开销,即当前节点的开销加上当前节点到相邻节点的开销
  new_cost = cost + neighbors[n]
  # 如果经当前节点前往该邻居更近,就更新该邻居的开销
  if new_cost < costs[n]:
  costs[n] = new_cost
  #同时将该邻居的父节点设置为当前节点
  parents[n] = node
 # 将当前节点标记为处理过
 processed.append(node)
 # 找出接下来要处理的节点,并循环
 node = find_lowest_cost_node(costs)
 # 循环完毕说明所有节点都已经处理完毕
 shortest_path = find_shortest_path()
 shortest_path.reverse()
 print(shortest_path)
# 测试
dijkstra()

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

Python 相关文章推荐
python使用在线API查询IP对应的地理位置信息实例
Jun 01 Python
对于Python的Django框架使用的一些实用建议
Apr 03 Python
pygame学习笔记(3):运动速率、时间、事件、文字
Apr 15 Python
python实现微信自动回复功能
Apr 11 Python
Python单向链表和双向链表原理与用法实例详解
Aug 31 Python
django框架CSRF防护原理与用法分析
Jul 22 Python
Python随机函数库random的使用方法详解
Aug 21 Python
python中从for循环延申到推导式的具体使用
Nov 29 Python
Pytorch之finetune使用详解
Jan 18 Python
python next()和iter()函数原理解析
Feb 07 Python
python3中使用__slots__限定实例属性操作分析
Feb 14 Python
Anaconda+Pycharm环境下的PyTorch配置方法
Mar 13 Python
在PyCharm下使用 ipython 交互式编程的方法
Jan 17 #Python
python最小生成树kruskal与prim算法详解
Jan 17 #Python
解决PyCharm不运行脚本,而是运行单元测试的问题
Jan 17 #Python
在PyCharm导航区中打开多个Project的关闭方法
Jan 17 #Python
Python设计模式之模板方法模式实例详解
Jan 17 #Python
Python设计模式之外观模式实例详解
Jan 17 #Python
Python pycharm 同时加载多个项目的方法
Jan 17 #Python
You might like
php数组函数序列之array_search()- 按元素值返回键名
2011/11/04 PHP
深入解析PHP的引用计数机制
2013/06/14 PHP
PHP中include/require/include_once/require_once使用心得
2016/08/28 PHP
用jscript实现列出安装的软件列表
2007/06/18 Javascript
document.forms[].submit()使用介绍
2014/02/19 Javascript
关于javascript模块加载技术的一些思考
2014/11/28 Javascript
angular.element方法汇总
2015/01/07 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
javascript运动框架用法实例分析(实现放大与缩小效果)
2016/01/08 Javascript
一系列Bootstrap导航条使用方法分享
2016/04/29 Javascript
深入分析javascript中的错误处理机制
2016/07/17 Javascript
vue实现多个元素或多个组件之间动画效果
2018/09/25 Javascript
jQuery实现文本显示一段时间后隐藏的方法分析
2019/06/20 jQuery
JavaScript遍历数组的方法代码实例
2020/01/14 Javascript
python修改文件内容的3种方法详解
2019/11/15 Python
Python使用PyQt5/PySide2编写一个极简的音乐播放器功能
2020/02/07 Python
django admin 根据choice字段选择的不同来显示不同的页面方式
2020/05/13 Python
No module named ‘win32gui‘ 的解决方法(踩坑之旅)
2021/02/18 Python
HTML5 新旧语法标记对我们有什么好处
2012/12/13 HTML / CSS
HTML5基于flash实现播放RTMP协议视频的示例代码
2020/12/04 HTML / CSS
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
Nike墨西哥官网:Nike MX
2020/08/30 全球购物
一篇.NET面试题
2014/09/29 面试题
欢送退休感言
2014/02/08 职场文书
《油菜花开了》教学反思
2014/02/22 职场文书
企业文化演讲稿
2014/05/20 职场文书
阅兵口号
2014/06/19 职场文书
飞机制造技术专业求职信
2014/07/27 职场文书
安全保卫工作竞聘材料
2014/08/25 职场文书
村党支部书记个人对照材料汇报
2014/10/26 职场文书
学生会生活部工作总结2015
2015/03/31 职场文书
公司人事任命通知
2015/04/20 职场文书
小人国观后感
2015/06/11 职场文书
2016护理专业求职自荐书
2016/01/28 职场文书
2016年暑期社会实践活动总结报告
2016/04/06 职场文书
MySQL里面的子查询的基本使用
2021/08/02 MySQL