Dijkstra 路径规划算法原理详解及 Python 代码实现
荷兰数学家 E.W.Dijkstra 于 1959 年提出了 Dijkstra 算法,它是一种适用于 非负权值 网络的 单源最短路径算法,同时也是目前求解最短路径问题的理论上最完备、应用最广的经典算法。它可以给出从指定节点到图中其他节点的最短路径,以及任意两点的最短路径。
Dijkstra 算法是一种基于 贪心策略 的最短路径算法,该种算法的原理是按照路径长度逐点增长的方法构造一棵路径树,从而得出从该树的根节点(即指定节点)到其他所有节点的最短路径。
Dijkstra 算法的 核心思想 是:设置两个点的集合 S 和 T。集合 S 中存放已找到最短路径的节点,集合 T 中存放当前还未找到最短路径的节点。
具体实现过程如下图所示:
下面将用一个示例来讲述算法的原理过程。
如图所示,一个有向权值图,利用 Dijkstra算法 找到从 节点1
到 节点 6
的最短路径。
首先进行初始化,初始化一个空的
open list
、close list
以及parent
。将起点及其距离信息放入到open list
中,将起点及其父亲节点放入parent
中,由于其是起点,所以设置其父节点为None
。open list 中存放那些已经访问的从该节点到起点有路径的结点(有路径但不一定是最优路径)。
close list 中存放那些已经找到最优路径的结点。
parent 存放结点的父子关系,方便后面路径回溯。
注意: 其实 open list 中应该存放所有未找到最短路径的结点,存放时由于要设置其距起点的距离,初始化时通常设置为
+Inf
.后面逐个访问结点时到再更新其相应的距离值。其实和现在的做法是一样的,将 open list 初始化为 空,逐个访问到结点时再往里添加或者更新。两者皆可。按步骤执行。
- close list 中新加入的结点为 1(0), 遍历其邻接结点 2 、4,两结点均未在 close list 中,所以计算其距离(即到起点的距离)如下图所示,并将其添加如 open list 中。将结点 2 、4的继承关系即 {2: 1,4: 1}添加进 parent 中。
- 从 open list 中 找到距离最小的结点,即 4(1),并添加到 close list 中。
按步骤执行。
- close list 中新加入的结点为 4(1), 遍历其邻接结点 3、 6、 7、 5,四个结点均未在 close list 中,所以计算其距离(即到起点的距离),如下图所示。并将其添加如 open list 中。将结点 3、 6、 7、 5的继承关系即 {3: 4, 6: 4, 7: 4,5: 4}添加进 parent 中。
- 从 open list 中 找到距离最小的结点,即 2(2),并添加到 close list 中。
按步骤执行。
- close list 中新加入的结点为 2(2), 遍历其邻接结点 4、 5,由于结点 4 已经在 close list 中,所以只需计算 结点5的距离,如下图所示,由于计算的新的距离为13,大于open list 中结点 5 原来的距离 3,所以不进行更新。同时也不更新 parent 中结点 5 的继承关系
- 从 open list 中 找到距离最小的结点,此时有两个距离最小的结点,3(3) 和 5(3), 任选其一即可,在此选 3(3), 并添加到 close list 中。
按步骤执行。
- close list 中新加入的结点为 3(3), 遍历其邻接结点 1、 6,由于结点 1 已经在 close list,所以不用考虑,只需计算 结点 6 的距离,如下图所示,计算后得到的距离为 8, 小于 open list 中结点6 原来的距离 9,所以更新 open list 中结点 6 的距离为 8. 同时更新 parent 中结点 6 的继承关系为 {6: 3}
- 从 open list 中 找到距离最小的结点,即 5(3),并添加到 close list 中。
按步骤执行。
- close list 中新加入的结点为 5(3), 遍历其邻接结点 7,结点 7 未在close list 中,计算其距离,如下图所示,计算后的距离为 9,大于 open list 中 结点 7 的距离 5,所以不进行更新。同时也不更新 parent 中结点 7 的继承关系。
- 从 open list 中 找到距离最小的结点,即 7(5),并添加到 close list 中。
按步骤执行。
- close list 中新加入的结点为 7(5), 遍历其邻接结点 6. 结点 6 未在 close list 中,所以计算其距离,如下图所示。计算后的距离为 6,小于 open list 中 结点 6 的距离 8,所以将 open list 中结点 6 的距离更新为 6.同时更新 parent 中结点 6 的继承关系为 {6:7}
- 从 open list 中 找到距离最小的结点,即 6(6),并添加到 close list 中。
- 至此,找到终点。
路径回溯。
根据 parent 中的继承关系,从终点向起点回溯,得到从起点 1 到 终点 6 的最短路径为:1 => 4 => 7 => 6, 最短路径长为:6.
总结上述流程,可以得到以下算法代码框架:
Python 代码实现
class Dijkstra:def __init__(self, graph, start, goal):self.graph = graph # 邻接表self.start = start # 起点self.goal = goal # 终点self.open_list = {} # open 表self.closed_list = {} # closed 表self.open_list[start] = 0.0 # 将起点放入 open_list 中self.parent = {start: None} # 存储节点的父子关系。键为子节点,值为父节点。方便做最后路径的回溯self.min_dis = None # 最短路径的长度def shortest_path(self):while True:if self.open_list is None:print('搜索失败, 结束!')breakdistance, min_node = min(zip(self.open_list.values(), self.open_list.keys())) # 取出距离最小的节点self.open_list.pop(min_node) # 将其从 open_list 中去除self.closed_list[min_node] = distance # 将节点加入 closed_list 中if min_node == self.goal: # 如果节点为终点self.min_dis = distanceshortest_path = [self.goal] # 记录从终点回溯的路径father_node = self.parent[self.goal]while father_node != self.start:shortest_path.append(father_node)father_node = self.parent[father_node]shortest_path.append(self.start)print(shortest_path[::-1]) # 逆序print('最短路径的长度为:{}'.format(self.min_dis))print('找到最短路径, 结束!')return shortest_path[::-1], self.min_dis # 返回最短路径和最短路径长度for node in self.graph[min_node].keys(): # 遍历当前节点的邻接节点if node not in self.closed_list.keys(): # 邻接节点不在 closed_list 中if node in self.open_list.keys(): # 如果节点在 open_list 中if self.graph[min_node][node] + distance < self.open_list[node]:self.open_list[node] = distance + self.graph[min_node][node] # 更新节点的值self.parent[node] = min_node # 更新继承关系else: # 如果节点不在 open_list 中self.open_list[node] = distance + self.graph[min_node][node] # 计算节点的值,并加入 open_list 中self.parent[node] = min_node # 更新继承关系if __name__ == '__main__':g = {'1': {'2': 2, '4': 1},'2': {'4': 3, '5': 11},'3': {'1': 4, '6': 5},'4': {'3': 2, '6': 8, '7': 4, '5': 2},'5': {'7': 6},'7': {'6': 1}}start = '1'goal = '6'dijk = Dijkstra(g, start, goal)dijk.shortest_path()
运行结果:
如果对您有帮助,记得在下面点赞呦!如果有问题也欢迎在下面评论区留言。
Dijkstra 路径规划算法原理详解及 Python 代码实现相关推荐
- KNN算法原理详解及python代码实现
KNN算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python) 算法原理 计算待测样本与train_data的距离d并保存数组中 对d进行排序,取d最近的k个样本 统计样 ...
- 视频教程-深度学习原理详解及Python代码实现-深度学习
深度学习原理详解及Python代码实现 大学教授,美国归国博士.博士生导师:人工智能公司专家顾问:长期从事人工智能.物联网.大数据研究:已发表学术论文100多篇,授权发明专利10多项 白勇 ¥88.0 ...
- Xgboost算法原理详解及python实现
Xgboost算法(回归树) 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.XGB.GBDT.LR与RF 5.python代码实现 导入相关包 读取数据并预处理 训练 贝叶斯初步 ...
- SVM算法原理详解及python实现
SVM算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python)(待更.........) 算法原理 {wTx+b>0yi=1⟺y(xi)>0wTx+b< ...
- 模糊聚类的代码实现python_Fuzzy C-Means(模糊C均值聚类)算法原理详解与python实现...
目录 模糊理论 Fuzzy C-Means算法原理 算法步骤 python实现 参考资料 本文采用数据集为iris,将iris.txt放在程序的同一文件夹下.请先自行下载好. 模糊理论 模糊控制是自动 ...
- 感知器算法原理详解及python实现
感知器算法PLA 感知器算法是对一种分类学习机模型的称呼,属于有关机器学习的仿生学领域中的问题,由于无法实现非线性分类而下马.但"赏罚概念(reward-punishment concept ...
- 随机森林原理详解及python代码实现
随机森林(RF)算法 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理(必须处理缺失值) ...
- 决策树原理详解及python代码实现
决策树算法(信贷中常用来寻找规则) 1.算法原理 1.1 ID3(多叉树分类) 1.2 C4.5(多叉树分类) 1.3 Cart(二叉树分类+回归) 2.ID3.C4.5与Cart比较 3.算法优缺点 ...
- GBDT(回归树)原理详解与python代码实现
GBDT算法 1.算法原理 2.对数据的要求 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理 训练及评估 1.算法原理 步骤: 1. ...
最新文章
- 从源码出发:JAVA中对象的比较
- Django模版(二)
- test libvirt
- 《C++ Primer》14.3节练习
- apache服务器配置Net的实践
- 【C++grammar】断言与表达式常量
- 软件工程学习笔记《三》代码优化和性能测试
- No fallback instance of type class found for feign client user-service(转)
- Java得到请求的IP地址
- inodesusedpercent_Linux系统中常用的监控指标整理
- Xcode 7制作动态Framework
- 论文笔记——多源融合SLAM的现状与挑战
- 4.1 心跳机制和垃圾回收机制
- lumen 框架学习
- QDataStream类的官方简介
- 如何用样本估计总体?(均值、方差、标准差)
- 【论文阅读】Fully Convolutional Networks for Semantic Segmentation【CVPR,PAMI】
- matlab中resample重采样函数
- python读取输入数据的第二行_Python读取键盘输入的2种方法
- Shopex乱码解决方案