最短路径算法
- Dijkstra算法
- Floyd算法
Dijkstra算法
基本思想:每次找到离源点(如1号结点)最近的一个顶点,然后以该顶点为中心进行扩展,最终得到源点到其余所有点的最短路径。
解决单源最短路径
理论
该算法包含四个步骤:
找出“最便宜”并没有访问过的节点,既在最短时间内可以到达的节点
这里应该是指距离开始节点最接近的节点
更新该节点的邻居节点的开销
既 distance(起点,当前节点) + distance(当前节点,它的邻居节点) = distance(起点,邻居节点)
重复这个过程,直到对图中的每个节点都这样做了。
计算最终路径。
图解
初始状态:
用一个数组记录各个节点到起点的距离,除起点设为0外,其他全部为无穷大。
第一步,找出最便宜的节点:
由起点距离起点最近,故起点为找到的节点
第二步,计算经最便宜的节点前往其各个邻居所需的时间:
通过起点前往A,B的时间为:
邻居节点 | 距离 |
---|---|
A | 6 |
B | 2 |
此时,起点距离B,A的距离分别为2,6。在数组中记录
dis[起点] = 0, dis[A] = 6, dis[B] = 2
第三步,重复以上两步
找出未访问过且最便宜的节点
此时为B
计算经最便宜节点前往其各个邻居所需的时间
B的邻居有:A,终点
邻居节点 新的距离 A dis(起点,B)+dis(B,A) < dis(起点,A),故更新为5 终点 dis(起点,B)+dis(B,终点)<dis(起点,终点),故更新为7 此时,距离数组更新如下:
dis[起点] = 0, dis[A] = 5, dis[B] = 2, dis[终点]=7
此时,已经访问起点,和B,还有两个节点没有访问
第四步,重复以上两步
找出未访问过且最便宜的节点
此时为A
计算经最便宜节点前往其各个邻居所需的时间:
A的邻居有:B,终点
邻居节点 距离 B dis(起点,A)+dis(A,B) > dis(起点,B),不更新,其实这步可以不要,因为前面已经证明B小于A 终点 dis(起点,A)+dis(A,终点)<dis(起点,终点),故更新为6 此时,距离数组更新如下:
dis[起点] = 0, dis[A] = 5, dis[B] = 2, dis[终点]=6
此时,已经访问起点,A 和B,还有1个节点没有访问
第五步,重复以上两步
在这里会退出。
代码
1 | cost = [[float("inf") for _ in range(6)] for _ in range(6)] |
参考文档:
- 算法图解
- 代码
例题
美团外卖是知名的外卖平台,现在有一名新入职的外卖小哥。请你给他写一段程序根据外卖地图和交通拥堵情况,告诉他从“配送点”V0,到各个目的地的最短配送距离。其中拥堵程度可以与路径参数直接相加,例如:V0点拥堵,拥堵系数是2,那么在地图上V0点的3条线路的参数都要加2,由原来的1、2、7变为3、4、9再进行。
Floyd算法
所有点对的最短路径
从出发地到目的地的过程中,我们并不是一下子就到达目的地,而是要经过很多的中转站来帮助我们一步一步地到达目的地。
参考链接:https://blog.csdn.net/Lwenjiyou_/article/details/79548577
代码
1 | N = 4 |
NC158 单源最短路
描述
在一个有 n 个点, m 个边的有向图中,已知每条边长,求出 1 到 n 的最短路径,返回 1 到 n 的最短路径值。如果 1 无法到 n ,输出 -1
图中可能有重边,无自环。
解法:迪杰斯特拉
1 | class Solution: |
解法:佛洛依德算法
超时
1 | class Solution: |