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向MySQL批量插数据的实例讲解
Mar 31 Python
python中使用iterrows()对dataframe进行遍历的实例
Jun 09 Python
python3.x实现base64加密和解密
Mar 28 Python
手把手教你使用Python创建微信机器人
Apr 29 Python
Python注释、分支结构、循环结构、伪“选择结构”用法实例分析
Jan 09 Python
Python求平面内点到直线距离的实现
Jan 19 Python
pycharm如何实现跨目录调用文件
Feb 28 Python
Django框架配置mysql数据库实现过程
Apr 22 Python
Python flask框架实现查询数据库并显示数据
Jun 04 Python
Python实现扫码工具的示例代码
Oct 09 Python
Python 远程开关机的方法
Nov 18 Python
VSCODE配置Markdown及Markdown基础语法详解
Jan 19 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警告错误信息的解决方法
2013/06/03 PHP
php中将数组转成字符串并保存到数据库中的函数代码
2013/09/29 PHP
php实现过滤表单提交中html标签的方法
2014/10/17 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
PHP echo()函数讲解
2019/02/15 PHP
laravel框架select2多选插件初始化默认选中项操作示例
2020/02/18 PHP
在表单提交前进行验证的几种方式整理
2013/07/31 Javascript
JavaScript实现表格快速变色效果代码
2015/08/19 Javascript
jquery实现ajax加载超时提示的方法
2016/07/23 Javascript
IOS中safari下的select下拉菜单文字过长不换行的解决方法
2016/09/26 Javascript
Node.js操作redis实现添加查询功能
2017/05/25 Javascript
详谈构造函数加括号与不加括号的区别
2017/10/26 Javascript
Nodejs核心模块之net和http的使用详解
2019/04/02 NodeJs
JavaScript面向对象编程小游戏---贪吃蛇代码实例
2019/05/15 Javascript
bootstrap table实现横向合并与纵向合并
2019/07/18 Javascript
前端插件之Bootstrap Dual Listbox使用教程
2019/07/23 Javascript
Vue Cli3 打包配置并自动忽略console.log语句的方法
2020/04/23 Javascript
Node.js API详解之 dgram模块用法实例分析
2020/06/05 Javascript
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
python不带重复的全排列代码
2013/08/13 Python
python自动化工具日志查询分析脚本代码实现
2013/11/26 Python
一个计算身份证号码校验位的Python小程序
2014/08/15 Python
Python批量生成特定尺寸图片及图画任意文字的实例
2019/01/30 Python
Python jieba库用法及实例解析
2019/11/04 Python
torch 中各种图像格式转换的实现方法
2019/12/26 Python
完美解决pyinstaller打包报错找不到依赖pypiwin32或pywin32-ctypes的错误
2020/04/01 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
2020/08/28 Python
美国女孩洋娃娃店:American Girl
2017/10/24 全球购物
秋季运动会稿件
2014/01/30 职场文书
经济信息系毕业生自荐信范文
2014/03/15 职场文书
应急管理培训方案
2014/06/12 职场文书
学校清明节活动总结
2014/07/04 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
入党政审材料范文
2014/12/24 职场文书
《夹竹桃》教学反思
2016/02/23 职场文书
MySQL普通表如何转换成分区表
2022/05/30 MySQL