荷兰数学家 E.W.Dijkstra 于 1959 年提出了 Dijkstra 算法,它是一种适用于 非负权值 网络的 单源最短路径算法,同时也是目前求解最短路径问题的理论上最完备、应用最广的经典算法。它可以给出从指定节点到图中其他节点的最短路径,以及任意两点的最短路径。

Dijkstra 算法是一种基于 贪心策略 的最短路径算法,该种算法的原理是按照路径长度逐点增长的方法构造一棵路径树,从而得出从该树的根节点(即指定节点)到其他所有节点的最短路径。

Dijkstra 算法的 核心思想 是:设置两个点的集合 S 和 T。集合 S 中存放已找到最短路径的节点,集合 T 中存放当前还未找到最短路径的节点。

具体实现过程如下图所示:

下面将用一个示例来讲述算法的原理过程。

如图所示,一个有向权值图,利用 Dijkstra算法 找到从 节点1节点 6 的最短路径。

  1. 首先进行初始化,初始化一个空的 open listclose list 以及 parent。将起点及其距离信息放入到 open list 中,将起点及其父亲节点放入 parent 中,由于其是起点,所以设置其父节点为 None

    open list 中存放那些已经访问的从该节点到起点有路径的结点(有路径但不一定是最优路径)。

    close list 中存放那些已经找到最优路径的结点。

    parent 存放结点的父子关系,方便后面路径回溯。

    注意: 其实 open list 中应该存放所有未找到最短路径的结点,存放时由于要设置其距起点的距离,初始化时通常设置为+Inf.后面逐个访问结点时到再更新其相应的距离值。其实和现在的做法是一样的,将 open list 初始化为 空,逐个访问到结点时再往里添加或者更新。两者皆可。

  2. 按步骤执行。

    • close list 中新加入的结点为 1(0), 遍历其邻接结点 2 、4,两结点均未在 close list 中,所以计算其距离(即到起点的距离)如下图所示,并将其添加如 open list 中。将结点 2 、4的继承关系即 {2: 1,4: 1}添加进 parent 中。
    • 从 open list 中 找到距离最小的结点,即 4(1),并添加到 close list 中。

  3. 按步骤执行。

    • 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 中。

  4. 按步骤执行。

    • 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 中。

  5. 按步骤执行。

    • 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 中。

  6. 按步骤执行。

    • close list 中新加入的结点为 5(3), 遍历其邻接结点 7,结点 7 未在close list 中,计算其距离,如下图所示,计算后的距离为 9,大于 open list 中 结点 7 的距离 5,所以不进行更新。同时也不更新 parent 中结点 7 的继承关系。
    • 从 open list 中 找到距离最小的结点,即 7(5),并添加到 close list 中。

  7. 按步骤执行。

    • 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 中。
    • 至此,找到终点。

  8. 路径回溯。

    根据 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 代码实现相关推荐

  1. KNN算法原理详解及python代码实现

    KNN算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python) 算法原理 计算待测样本与train_data的距离d并保存数组中 对d进行排序,取d最近的k个样本 统计样 ...

  2. 视频教程-深度学习原理详解及Python代码实现-深度学习

    深度学习原理详解及Python代码实现 大学教授,美国归国博士.博士生导师:人工智能公司专家顾问:长期从事人工智能.物联网.大数据研究:已发表学术论文100多篇,授权发明专利10多项 白勇 ¥88.0 ...

  3. Xgboost算法原理详解及python实现

    Xgboost算法(回归树) 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.XGB.GBDT.LR与RF 5.python代码实现 导入相关包 读取数据并预处理 训练 贝叶斯初步 ...

  4. SVM算法原理详解及python实现

    SVM算法 算法原理 对数据的要求 算法的优缺点 算法需要注意的点 算法实现(python)(待更.........) 算法原理 {wTx+b>0yi=1⟺y(xi)>0wTx+b< ...

  5. 模糊聚类的代码实现python_Fuzzy C-Means(模糊C均值聚类)算法原理详解与python实现...

    目录 模糊理论 Fuzzy C-Means算法原理 算法步骤 python实现 参考资料 本文采用数据集为iris,将iris.txt放在程序的同一文件夹下.请先自行下载好. 模糊理论 模糊控制是自动 ...

  6. 感知器算法原理详解及python实现

    感知器算法PLA 感知器算法是对一种分类学习机模型的称呼,属于有关机器学习的仿生学领域中的问题,由于无法实现非线性分类而下马.但"赏罚概念(reward-punishment concept ...

  7. 随机森林原理详解及python代码实现

    随机森林(RF)算法 1.算法原理 2.对数据的要求(无需规范化) 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理(必须处理缺失值) ...

  8. 决策树原理详解及python代码实现

    决策树算法(信贷中常用来寻找规则) 1.算法原理 1.1 ID3(多叉树分类) 1.2 C4.5(多叉树分类) 1.3 Cart(二叉树分类+回归) 2.ID3.C4.5与Cart比较 3.算法优缺点 ...

  9. GBDT(回归树)原理详解与python代码实现

    GBDT算法 1.算法原理 2.对数据的要求 3.算法的优缺点 4.算法需要注意的点 5.python代码实现(待更......) 导入相关包 读取数据并预处理 训练及评估 1.算法原理 步骤: 1. ...

最新文章

  1. 从源码出发:JAVA中对象的比较
  2. Django模版(二)
  3. test libvirt
  4. 《C++ Primer》14.3节练习
  5. apache服务器配置Net的实践
  6. 【C++grammar】断言与表达式常量
  7. 软件工程学习笔记《三》代码优化和性能测试
  8. No fallback instance of type class found for feign client user-service(转)
  9. Java得到请求的IP地址
  10. inodesusedpercent_Linux系统中常用的监控指标整理
  11. Xcode 7制作动态Framework
  12. 论文笔记——多源融合SLAM的现状与挑战
  13. 4.1 心跳机制和垃圾回收机制
  14. lumen 框架学习
  15. QDataStream类的官方简介
  16. 如何用样本估计总体?(均值、方差、标准差)
  17. 【论文阅读】Fully Convolutional Networks for Semantic Segmentation【CVPR,PAMI】
  18. matlab中resample重采样函数
  19. python读取输入数据的第二行_Python读取键盘输入的2种方法
  20. Shopex乱码解决方案

热门文章

  1. android rndis
  2. mt管理器逆向了解安卓----【mt管理器介绍】
  3. 先进先出(FIFO)页面置换算法 C语言实现
  4. 项目经理 VS 产品经理 (工作职责和要求)
  5. AcWing 1089 烽火传递 题解(动态规划—DP—单调队列优化DP)
  6. Python 散点图线性拟合_简单线性回归——相关性分析
  7. jQuery 验证码输入错误后自动刷新验证码 点击验证码图片刷新验证码
  8. 影视剪辑,自学剪辑,视频剪辑7天学习计划
  9. 代码精进之路-读后感
  10. 由JVM深入了解Java的线程安全与锁优化