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测试驱动开发实例
Oct 08 Python
深入讨论Python函数的参数的默认值所引发的问题的原因
Mar 30 Python
用Python写冒泡排序代码
Apr 12 Python
Python注释详解
Jun 01 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
Apr 23 Python
Python Numpy库安装与基本操作示例
Jan 08 Python
python贪吃蛇游戏代码
Apr 18 Python
python实现本地批量ping多个IP的方法示例
Aug 07 Python
解决python中import文件夹下面py文件报错问题
Jun 01 Python
解决tensorflow/keras时出现数组维度不匹配问题
Jun 29 Python
对python中list的五种查找方法说明
Jul 13 Python
Python OpenCV中的numpy与图像类型转换操作
Dec 11 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 5.3新增魔术方法__invoke概述
2014/07/23 PHP
Yii1.1框架实现PHP极光推送消息通知功能
2018/09/06 PHP
php提取微信账单的有效信息
2018/10/01 PHP
基于jquery的DIV随滚动条滚动而滚动的代码
2012/07/20 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
Jquery实现鼠标移动放大图片功能实例
2015/03/25 Javascript
jquery简单实现带渐显效果的选项卡菜单代码
2015/09/01 Javascript
深入浅析javascript中的作用域(推荐)
2016/07/19 Javascript
图解prototype、proto和constructor的三角关系
2016/07/31 Javascript
浅析BootStrap Treeview的简单使用
2016/10/12 Javascript
jQuery Password Validation密码验证
2016/12/30 Javascript
在node.js中怎么屏蔽掉favicon.ico的请求
2017/03/01 Javascript
如何解决vue与传统jquery插件冲突
2017/03/20 Javascript
Angular实现一个简单的多选复选框的弹出框指令实例
2017/04/25 Javascript
微信小程序 动画的简单实例
2017/10/12 Javascript
浅谈webpack devtool里的7种SourceMap模式
2019/01/14 Javascript
vue-cli构建vue项目的步骤详解
2019/01/27 Javascript
微信小程序之数据绑定原理解析
2019/08/14 Javascript
浅谈Three.js截图并下载的大坑
2019/11/01 Javascript
vue组件内部引入外部js文件的方法
2020/01/18 Javascript
Vue事件处理原理及过程详解
2020/03/11 Javascript
用jQuery实现抽奖程序
2020/04/12 jQuery
解决React在安装antd之后出现的Can't resolve './locale'问题(推荐)
2020/05/03 Javascript
python正则表达式re模块详细介绍
2014/05/29 Python
python 的列表遍历删除实现代码
2020/04/12 Python
python魔法方法-自定义序列详解
2016/07/21 Python
Python遍历文件夹和读写文件的实现方法
2017/05/10 Python
深入理解Django-Signals信号量
2019/02/19 Python
详解pandas.DataFrame中删除包涵特定字符串所在的行
2019/04/04 Python
Python While循环语句实例演示及原理解析
2020/01/03 Python
超市商业计划书
2014/05/04 职场文书
大学生实习介绍信
2015/05/05 职场文书
电工生产实习心得体会
2016/01/22 职场文书
html实现弹窗的实例
2021/06/09 HTML / CSS
CSS实现五种常用的2D转换
2021/12/06 HTML / CSS
Navicat Premium自定义 sql 标签的创建方式
2022/09/23 数据库