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 12 Python
Python实现判断给定列表是否有重复元素的方法
Apr 11 Python
Python使用matplotlib模块绘制图像并设置标题与坐标轴等信息示例
May 04 Python
Python功能点实现:函数级/代码块级计时器
Jan 02 Python
解决新版Pycharm中Matplotlib图像不在弹出独立的显示窗口问题
Jan 15 Python
Python通过for循环理解迭代器和生成器实例详解
Feb 16 Python
Python中拆分字符串的操作方法
Jul 23 Python
使用Pyinstaller转换.py文件为.exe可执行程序过程详解
Aug 06 Python
python线程的几种创建方式详解
Aug 29 Python
通过实例简单了解Python中yield的作用
Dec 11 Python
Python使用type动态创建类操作示例
Feb 29 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 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封装的smartyBC类完整实例
2016/10/19 PHP
PHP安装BCMath扩展的方法
2019/02/13 PHP
js事件冒泡实例分享(已测试)
2013/04/23 Javascript
JavaSciprt中处理字符串之sup()方法的使用教程
2015/06/08 Javascript
IE8 内存泄露(内存一直增长 )的原因及解决办法
2016/04/06 Javascript
javascript实现下雪效果【实例代码】
2016/05/03 Javascript
indexedDB bootstrap angularjs之 MVC DOMO (应用示例)
2016/06/20 Javascript
D3.js封装文本实现自动换行和旋转平移等功能
2016/10/14 Javascript
javascript实现将数字转成千分位的方法小结【5种方式】
2016/12/11 Javascript
使用smartupload组件实现jsp+jdbc上传下载文件实例解析
2017/01/05 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
2017/03/04 Javascript
AngularJS与BootStrap模仿百度分页的示例代码
2018/05/23 Javascript
详解JavaScript作用域 闭包
2020/07/29 Javascript
[40:55]Liquid vs LGD 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
Python实现批量下载文件
2015/05/17 Python
Python设置Socket代理及实现远程摄像头控制的例子
2015/11/13 Python
Python set常用操作函数集锦
2017/11/15 Python
python监控进程脚本
2018/04/12 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
Python爬取爱奇艺电影信息代码实例
2019/11/26 Python
Python 改变数组类型为uint8的实现
2020/04/09 Python
Python如何读写字节数据
2020/08/05 Python
python日志通过不同的等级打印不同的颜色(示例代码)
2021/01/13 Python
荟萃全球保健品:维他购
2018/05/09 全球购物
英国假睫毛购买网站:FalseEyelashes.co.uk
2018/05/23 全球购物
Set里的元素是不能重复的,那么用什么方法来区分重复与否呢?
2016/08/18 面试题
乡镇干部先进事迹材料
2014/02/03 职场文书
高中教师评语大全
2014/04/25 职场文书
专项法律服务方案
2014/06/11 职场文书
车辆工程专业求职信
2014/06/14 职场文书
党员自我剖析材料范文
2014/10/06 职场文书
详解nodejs内置模块
2021/05/06 NodeJs
分析ZooKeeper分布式锁的实现
2021/06/30 Java/Android
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL
笔记本自带的win11如何跳过联网激活?
2022/04/20 数码科技