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开发之函数定义实例分析
Nov 12 Python
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
Aug 18 Python
python中is与双等于号“==”的区别示例详解
Nov 21 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
Jun 11 Python
django开发post接口简单案例,获取参数值的方法
Dec 11 Python
selenium在执行phantomjs的API并获取执行结果的方法
Dec 17 Python
python3爬虫获取html内容及各属性值的方法
Dec 17 Python
详解Python logging调用Logger.info方法的处理过程
Feb 12 Python
详解Python中的各种转义符\n\r\t
Jul 10 Python
python将音频进行变速的操作方法
Apr 08 Python
在Windows上安装和配置 Jupyter Lab 作为桌面级应用程序教程
Apr 22 Python
Kmeans均值聚类算法原理以及Python如何实现
Sep 26 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使用DOMDocument类生成HTML实例(包含常见标签元素)
2014/06/25 PHP
ThinkPHP跳转页success及error模板实例教程
2014/07/17 PHP
PHP中的类型提示(type hinting)功能介绍
2015/07/01 PHP
PHP中addcslashes与stripcslashes函数用法分析
2016/01/07 PHP
php压缩文件夹最新版
2018/07/18 PHP
PHP保留两位小数的几种方法
2019/07/24 PHP
JavaScript入门学习书籍推荐
2008/06/12 Javascript
JS删除数组元素的函数介绍
2013/03/27 Javascript
基于JQuery实现滚动到页面底端时自动加载更多信息
2014/01/31 Javascript
BootStrap无限级分类(无限极分类封装版)
2016/08/26 Javascript
SpringMVC+bootstrap table实例详解
2017/06/02 Javascript
原生js jquery ajax请求以及jsonp的调用方法
2017/08/04 jQuery
原生JS实现ajax与ajax的跨域请求实例
2017/12/01 Javascript
关于laydate.js加载laydate.css路径错误问题解决
2017/12/27 Javascript
vue.js数据绑定操作详解
2018/04/23 Javascript
微信小程序实现商城倒计时
2020/11/01 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
vue在App.vue文件中监听路由变化刷新页面操作
2020/08/14 Javascript
[01:05:30]VP vs TNC 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Scrapy爬虫实例讲解_校花网
2017/10/23 Python
python游戏开发之视频转彩色字符动画
2019/04/26 Python
Python银行系统实战源码
2019/10/25 Python
对Tensorflow中tensorboard日志的生成与显示详解
2020/02/04 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
python3定位并识别图片验证码实现自动登录功能
2021/01/29 Python
css3.0 图形构成实例练习一
2013/03/19 HTML / CSS
丝芙兰中国官方商城:SEPHORA中国
2018/01/10 全球购物
广州品高软件.net笔面试题目
2012/04/18 面试题
个人求职信范文分享
2013/12/13 职场文书
教育专业毕业生推荐信
2014/07/10 职场文书
房屋租赁授权委托书范本
2014/09/20 职场文书
解除施工合同协议书
2014/10/17 职场文书
李白故里导游词
2015/02/12 职场文书
运动会加油稿30字
2015/07/21 职场文书
2016企业先进集体事迹材料
2016/02/25 职场文书
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python