【数据结构】图-最短路径问题

时间:2024-04-03 14:49:00

最短路径问题的抽象
·在网络中,求两个不同顶点之间的所有路径中,边的权值之和最小的那一条路径
这条路径就是两点之间的最短路径(shortest path)
第一个顶点为源点(source)
最后一个顶点为终点(destination)

问题分类:
单源最短路径问题:从某固定源点出发,求其到所有其他顶点的最短路径。
(有向)无权图
(有向)有权图
多源最短路径问题:求任意两顶点间的最短路径

无权图的单元最短路算法
按照递增(非递减)的顺序找出到各个顶点的最短路
【数据结构】图-最短路径问题
如图,求v3到其余各点的最短路
Step 1 : 直接从v3出发,能直接到达v1和v6,将其记录,表示v3到这两个点的路程为1
Step 2 : 从step1中获取到的两点出发,先从v1出发,能直接到达v2和v4,即表示v3到这两个点的路程为1+1=2;从v6出发,发现v6并没有箭头指向其它点,结束
Step 3 : 同上 从v2出发,v4已经访问过了,不访问,可以访问v5;从v4出发,v5已经访问过,不访问,可以访问v7,那么v5,v7就是从v3出发的两点路程为2+1=3的点
至此,所有点已经访问完毕。

有没有觉得和BFS很像

实际上代码也和BFS差不多,但是有修改:
【数据结构】图-最短路径问题
需要一个更加具体的数组来表示到每个点的最短路径是多少,还可以顺便准备一个数组,表示路径
【数据结构】图-最短路径问题
S是其本身,因此dist[S] = 0;其余dist[]的初始值可以设置一个奇妙的值,比方说-1,比方说-9999等。
访问到一个点之后,它的路径就是我此时出发点的路径+1
【数据结构】图-最短路径问题
如果dist的初始值都设为0,那么在if判断那边就是if(dist[W] == 0),这样源点会一直入队出队入队出队,进入死循环。
【数据结构】图-最短路径问题
最后模拟结果如上,文字描述参考上文,path模拟方法类似不多赘述了。

有权图的单元最短路算法
【数据结构】图-最短路径问题
图1,设权重指代通行费,想求v1到v6最省钱路线,可以得出v1-v4-v7-v6 = 6
图2,同样的,但v2->v5为-10,此时想求v5到v4最省钱路线,则会进入v5-v4-v2-v5死循环(一时赚钱一时爽,一直赚钱一直爽),这个-10称为负值圈,在算法中一般都需要避免负值圈的出现。

Dijkstra算法
一个用于有权图最短路径的算法,直接贴出代码和模拟:
【数据结构】图-最短路径问题
【数据结构】图-最短路径问题
寻找v1开始到各点的最短路径:
准备工作:将v1的dist设为0(自己),并设置标记(已录入),再把v1相邻的点录入(v2,v4)
疑惑:v2的权重是2,但万一有一条路径是1呢?v4的路径是1可以直接录入,但是v2我保持疑问 如果真有这种情况,也会通过其它路径走到,到时候更新v2就可以了)

代码解释:
collected[V] 代表的是这个点V是否已经作为一个源点在四周查找邻接点过了;
E<V,W> 表示带权路径<V,W>的权重值
dist[W] 距离源点的距离(最终结果都是最短距离)
path[W] 走到这个点的上一点是什么(最终能通过path定位到数组下标,一直回溯就会回到起点,路径数字化表现可以用堆栈实现)

进入函数:传参vertex s为顶点v1的下标(实质上就是int v),进入while循环
Step 1 : 从dist数组进行遍历,寻找未收录顶点中 dist最小者为新的出发点,此时是v4。然后将其标记为“已访问”,开始遍历v4的每个邻接点(v3, v5, v6, v7),并且这些邻接点都得是“未访问过” (如果已访问过,表示这个点已经求出最短路了,再去访问浪费时间)。如果v4的dist加上v4->vi的权重小于vi已保存的dist(这条路更近),那就更新vi的dist,并且更新vi的path为v4,第一轮循环结果如下:
【数据结构】图-最短路径问题
Step 2 : v4结束,继续从dist数组中遍历寻找新的出发点,易得为v2,此时将v2作为V,标记“已访问”,再开始访问v2的邻接点。v4已访问过,因此不考虑;v5未访问过,但是dist[V]+E<v2,v5> = 12 > 3,因此不更新。v2循环结束。

Step 3 :这时该从v3开始,v3的邻接点为v6,此时dist[V] + E<v3,v6> = 8 < 9,因此更新dist[v6]和path[v6]。

以下类似不多赘述,最终更新结果为:
【数据结构】图-最短路径问题

举例:求v1到v6的最短路的路径
直接找到v6,再通过path[v6]能得出v6的上一点为v7,找到v7
再通过path[v7]找到上一点为v4,以此类推能得到一串数字:6-7-4-1,放入堆栈就能转换为1-4-7-6即路径。

多元最短路算法
就是将每个点都作为起点,然后都给求一次各点的最短路
【数据结构】图-最短路径问题
【数据结构】图-最短路径问题

相关文章