最近有个同事问我迪杰斯特拉算法,以前都是直接用,三个循环体直接一套就出来,具体逻辑懒得去理解,这次被问到,就花了点时间理了理算法的底层逻辑。

---------

迪杰斯特拉算法是搜索出所有点起点的最短距离。

怎么找?

第一步,找出距离V0最近距离的点,设为V2。(显然此时V2的最短路径已经找到,就是V2直达路径。)

第二步,以V2为中转点mid_Node,用m替代

(Lx0,表示Vx到V0的距离,Lxm表示Vx到mid_Node的距离,其他同理)

第三步,取其他任意点Vx,比较Lx0和Lxm+Lm0的大小,令cost[X]=min(Lx0,LXm+Lm0),即找到了点x到0的更短路径,并更新进cost数组里。(其实就是让其他点尝试以mid_Node为中转,能否缩短路径,若能,就更新最短路径。)在for循环里把所有的点都尝试一遍中转方案,并把最短路径更新。(对应代码里 for NEXT_Node in range(lenth):循环体的内容)

第四步,搜索cost数组里的最短路径(除被选为mid_Node的点外,点是否选过为mid_Node是用数组v[]做标记,在if语句中判断,V[X]代表X是否已找到最短路径,1是,0不是。实际上被选为mid_Node就表示该点已经找到抵达V0的最短路径。这个等下会解释,先把流程弄清

第五步,把第三步里搜索到最短路径的端点设置为mid_Node,并且在V数组里把该端点的标志位置1.

第六步,判断是否所有点都设置为过mid_Node,是则结束,否则跳转到第三步。

--------

结合图片走一下步骤

贴一下几个代码会用到的数组变量

cost[i] 表示V0到Vi的已知最短路径长度
    mid_Node:中转点,以已求得V0到Vi的最短路径的Vi作为中转点。
    NEXT_Node:尝试优化的点,以中转点为中心,检测NEXT_Node直达V0方案,和经过mid_Node中转到V0的方案哪个更优
    check_Node:索引,搜索cost数组里最短路径的点,最短的点会赋值给mid_Node,作为中转点。

V数组用来存放标志位,表示是否已经找到x点的最短路径,找到则V[x]=1,否则为0,这是为了避免陷入死循环,一直卡在第一条最短路径出不来。

cost数组初始化时是所有点到V0的距离,即cost=[0,4,1,max,5,max,max,max]

第一步,显然选中V2,

第二步,V2作为中转点,

第三步,尝试优化其他点,其他点把中转点作为中转,比较能否缩短到V0的距离,这里能看到,V4经过V2中转后,到V0距离短了由5变为3,V3由无穷远变为6,其他点经过V2中转反而更长(变为无法抵达,即无穷远,因为其他点无法直达V2,到V2的距离是max)。把优化后的值更新进cost数组。

此时cost=[0,4,1,6,3,max,max,max]

第四步,选取cost数组里除cost[0],cost[2]以外最短的路径,显然是3,即cost[4],取得的端点是V4

第五步,把V4作为中转点,并把V数组的标志位置1,表示已找到V4的最短路径。

第六步,跳转到第三步循环,直到所有点都找到最短路径。

前面遗留的问题:被选为mid_Node就表示该点已经找到抵达V0的最短路径

这也是迪杰斯特拉算法里最绕的一个地方-----凭什么确定这个点已经找到了最短路径?

迪杰斯特拉算法的核心思想就是每次选mid_Node都是取cost数组待探索点里距离最小的( for check_Node in range(lenth):循环里做的)。也就是说,这条路径在剩下其他已知路径里已经是最小了,没法再优化了。为什么说没法优化了?

因为唯一可行的优化方法就是用比该点Vx到V0的路径Lx0更短的路径Lm0作为中转,中转距离就是Lxm+L0m,(这个路径优化就是for NEXT_Node in range(lenth)循环里做的事,选取mid_Node前已经做完了,所以可行的优化方法已经优化过了),

剩下的所有优化方案,只剩下用比Lx0(或Lm0+Lxm,取决于哪个更小)更长的路径作为中转。这显然是绕弯路了,必然增加长度,没必要尝试,所以没法再优化了,故得到的就是Vx到V0的最短路径。

python代码实现如下:

代码和前文示例的图片不对应,图片是随手画的,强迫症可以复制一下代码改一下数组和cost,path,range的长度,就能对应到图片了

def dijkstra(graph, start_Node, path, cost, max):"""graph:二维数组,就是用行列坐标表示图形上两点之间的距离。start_Node:起始点path[i] 表示vi节点的前一个节点,即中转点。cost[i] 表示V0到Vi的已知最短路径长度mid_Node:中转点,以已求得V0到Vi的最短路径的Vi作为中转点。NEXT_Node:尝试优化的点,以中转点为中心,检测NEXT_Node直达V0方案,和经过mid_Node中转到V0的方案哪个更优check_Node:索引,搜索cost数组里最短路径的点,最短的点会赋值给mid_Node,作为中转点。"""lenth = len(graph)v = [0] * lenth  # V数组初始化为0,用于标记该点是否已取得最短路径# 初始化 path,cost,Vfor i in range(lenth):if i == start_Node:v[start_Node] = 1else:cost[i] = graph[start_Node][i]  # cost获取起点至其他点的直达权重path[i] = (start_Node if (cost[i] < max) else -1)  # 前置点为起点或-1(无法直达起点)# print v, cost, pathfor i in range(1, lenth):  # 遍历的数等于除去起点的点的数量minCost = max  # 初始值取最大mid_Node = -1for check_Node in range(lenth):  # 搜索一个到起点V0最近的点,作为中转点mid_Nodeif v[check_Node] == 0 and cost[check_Node] < minCost:  # mid_Node点未取得最短路径,且路径权重小于最小值,则获取w,也就是先取得minCost = cost[check_Node]mid_Node = check_Nodeif mid_Node == -1: break  # 找不到权重小于max的点# 剩下都是不可通行的节点,跳出循环v[mid_Node] = 1  # check_Node已取得最短路径for NEXT_Node in range(lenth):if v[NEXT_Node] == 0 and (graph[mid_Node][NEXT_Node] + cost[mid_Node] < cost[NEXT_Node]):  # 检查所有未遍历的点NEXT_Node,检测前面获取的mid_Node对NEXT_Node的影响cost[NEXT_Node] = graph[mid_Node][NEXT_Node] + cost[mid_Node]  # 更新权值path[NEXT_Node] = mid_Node  # 更新路径# for 更新其他节点的权值(距离)和路径return pathif __name__ == '__main__':max = 999999  # max即表示为无法直达graph = [[5, max, 10, max, 30, 100],[max, max, 5, max, max, max],[max, 15, max, 50, max, max],[max, max, max, max, max, 10],[max, max, max, 20, max, 60],[max, 15, max, max, max, max],]path = [0] * 6cost = [0] * 6print(dijkstra(graph, 0, path, cost, max))print(cost)

讲清迪杰斯特拉(DIJKSTRA)算法,附python代码相关推荐

  1. 迪杰斯特拉dijkstra算法的python实现

    原图链接:http://www.cnblogs.com/skywang12345/p/3711516.html 本文以下图为例,用dijkstra算法计算由节点D至其它所有节点的最短路径 此时,起点D ...

  2. 数据结构与算法(7-4)最短路径(迪杰斯特拉(Dijkstra)算法、弗洛伊德(Floyd)算法)

    目录 一.最短路径概念 二.迪杰斯特拉(Dijkstra)算法(单源最短路径) 1.原理 2.过程 3.代码 三.弗洛伊德(Floyd)算法(多源最短路径) 1.原理 2.存储 3.遍历 4.代码 参 ...

  3. 059.迪杰斯特拉(Dijkstra)算法的原理以及解决最短路径问题

    1. 迪杰斯特拉(Dijkstra)算法的原理 1.1. 算法应用场景-最短路径问题 1.2. 基本介绍 1.3. 步骤详解 1.4. 思路解析 1.5. 图解步骤 2. 迪杰斯特拉(Dijkstra ...

  4. java数据结构和算法——迪杰斯特拉(Dijkstra)算法

    目录 一.迪杰斯特拉(Dijkstra)算法介绍 二.迪杰斯特拉(Dijkstra)算法过程 三.迪杰斯特拉(Dijkstra)算法--应用场景(最短路径问题) 四.迪杰斯特拉(Dijkstra)算法 ...

  5. 迪杰斯特拉(Dijkstra)算法解决最短路径问题

    Dijkstra 算法介绍 迪杰斯特拉算法(Dijkstra)是由荷兰计算机科学家狄克斯特拉于1959年提出的,因此又叫狄克斯特拉算法.迪杰斯特拉(Dijkstra)算法是最经典的最短路径算法之一,用 ...

  6. 最短路径算法-迪杰斯特拉(Dijkstra)算法

    最短路径算法-迪杰斯特拉(Dijkstra)算法 迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径. 它的主要特点是以起始点为中心向外层层扩展(广度优先遍历思 ...

  7. Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法

    1.Java迪杰斯特拉(Dijkstra)算法与弗洛伊德(Floyd)算法 1.1 迪杰斯特拉(Dijkstra)算法 1.1.1 迪杰斯特拉(Dijkstra)算法介绍 迪杰斯特拉(Dijkstra ...

  8. java实现迪杰斯特拉(Dijkstra)算法求解最短路问题

    迪杰斯特拉(Dijkstra)算法是由荷兰计算机科学家狄克斯特拉于1959年提出的.是寻找从一个顶点到其余各顶点的最短路径算法,可用来解决最短路径问题. 迪杰斯特拉算法采用贪心算法的策略,将所有顶点分 ...

  9. 数据结构——图——迪杰斯特拉(Dijkstra )算法

    数据结构--图--迪杰斯特拉(Dijkstra )算法 这是一个按路径长度递增的次序产生最短路径的算法.它的思路大体是这样的. 比如说要求图7-7-3中顶点v0到顶点v1的最短距离,没有比这更简单的了 ...

最新文章

  1. JS+Canvas的棋盘游戏和Java的动态结合
  2. localdatetime获得时间搓_得用户者得天下,一禅小和尚×往事若茶如何获得消费者认同...
  3. redis实现session共享,哨兵
  4. Python系列之入门篇——HDFS
  5. python io多路复用框架_python之IO多路复用
  6. python xml转字典_python xml转成dict
  7. Google Code的简单使用
  8. python爬取小猪短租信息
  9. Matlab计算器设计
  10. 优化网页加载各项的讨论
  11. ICMAX解析无线路由器WAN口应该怎么设置
  12. android ListView中含有按钮事件实时更新ListView数据案例-1
  13. 360°幻影成像展示产品,带来逼真的视觉效果
  14. 为什么Android没有iOS顺滑zz
  15. 人工智能在医疗发展突破分析
  16. 李建忠老师-设计模式
  17. 谷歌实现移动VR“白日梦”
  18. 如何在Microsoft Edge中更改主页
  19. mysql用于检索的关键字_Mysql全文搜索match...against的用法
  20. 新能源车,许家印的雄心,恒大的第二战场

热门文章

  1. C# 数组拷贝 数组截取前几个值 的方法
  2. 磁盘在计算机管理中能找到,事实:u盘可以显示在磁盘管理中,但是在计算机中找不到...
  3. 2021-11-07交通仿真数据准备
  4. PS移除图片上的文字或人物
  5. Java的一些基础知识笔记
  6. 电容器法拉、库仑、放电毫安时换算
  7. 资治通鉴直解 (张居正)内容摘要
  8. 视频教程-软件设计是怎样炼成的?-软件设计
  9. python闹钟源码_使用python编写一个语音朗读闹钟功能的示例代码
  10. 阿里巴巴、英特尔携手深度布局人工智能