最短路径
备注:求解最短路径的算法通常都依赖于一种性质,即两点之间的最短路径也包含了路径上其他顶点间的最短路径。
- 带权有向图G的最短路径问题一般可分为两类:
(1)单源最短路径:求图中某一顶点到其他各顶点的最短路径。
(2)多源最短路径:求每对顶点间的最短路径。
单源最短路径-Dijkstra算法(迪杰斯特拉)
(1) Dijkstra整体思路:
Dijkstra算法设置一个集合S记录已求得的最短路径的顶点,初始时把源点
v0放入
S,集合
S每并入一个新顶点
vi,都要修改源点
v0到集合
V−S中顶点当前的最短路径长度值
(2) 些符号说明:
- dist[]:记录从源点vo到其他各顶点当前的最短路径长度,它的初态为:若从v0到vi有弧,则dist[i]为弧上的权值;否则置dist[i]为∞。
邻接矩阵arcs表示带权有向图,arcs[i][j]表示有向边<i,j>的权值,若不存在有向边<i,j>则arcs[i][j]为∞。
(3) Dijkstra算法流程: (求解vo到其他节点的最短路径)
-
初始化:集合S初始为
0,
dist[]的初始值
dist[i]=arcs[0][i],
i=1,2…,n−1
-
2)从顶点集合
V−S中选出
vj,满足
dist[j]=Mindist[i]∣i∈V−S,vj就是当前求得的一条从v_0出发的最短路径的终点,令
S=SUj
-
修改从
v0出发到集合
V−S上任一顶点
vk可达的最短路径长度:若
dist[j]+arcs[j][k]<dist[k],则更新dist[k]=dist[j]+arcs[j][k]。
4)重复2)-3)操作共n-1次,直到所有的顶点都包含在S中。
备注:步骤3举例:
如下图所示,源点为vo,初始时S={vo},dist[1]=3,dist[2]=7,当将v1并入集合S后, dist[2]需要更新为4。
(4)模拟Dijkstra的过程
初始化:集合
S初始为
vi,
v1可达
v2和
v3,
v1不可达
v3和
v4,因此
dist[]数组各元素的初
值依次设置为
dist[2]=10,dist[3]=∞,dist[4]=∞,dist[5]=5。
第一轮:选出最小值
dist[5],将顶点
v5并入集合
S,即此时已找到
v1到
v5的最短路径。当v_5
加入S
后,从v_1
到集合V-S
中可达顶点的最短路径长度可能会产生变化,因此需要更新dist[]
数组。v_5
可达v_2
,因v_1→v_5→v_2
的距离8比dist[2]=10
小,更新dist[2]=8
;v_5
可达v_3
,V_1→V_5→V_2→V_3
的距离14,更新dist[3]=14
;v_5
可达v_4
,V_1→V_5→V_4
的距离7,更新dist[4]=7$.
第二轮:选出最小值
dist[4],将顶点
v4并入集合
S。继续更新
dist[]数组。
v4不可达
v2,
dist[2]不变;
v4可达
v3,
V1→V5→V4→V3的距离
13比
dist[3]小,故更新
dist[3]=13.
第三轮:选出最小值
dist[2],将顶点
v2并入集合
S。继续更新
dist[]数组。
v2可达
V3,
v1→v5→v2→v3的距离
9比
dist[3]小,更新
dist[3]=9
第四轮:选出唯一最小值
dist[3],将顶点
v3并入集合
S,此时全部顶点都已包含在
S中。
(5)时间复杂度分析
邻接矩阵存储图
:0(∣V∣2)
邻接表存储图:
0(∣V∣2)(虽然修改
dist[]的时间可以减少,但由于在
dist[]中选
择最小分量的时间不变)
(6)不适用条件
当图中含有负权边时,
Dijkstra算法将不适用。(
Dijkstra算法是基于贪心的)。