详解图的应用(最小生成树、拓扑排序、关键路径、最短路径)

2020-01-06 13:45:16王旭

算法的基本思想是:

设置两个顶点的集合S 和T=V-S,集合S 中存放已找到最短路径的顶点,集合T 存放当前还未找到最短路径的顶点。

初始状态时,集合S 中只包含源点v0,然后不断从集合T 中选取到顶点v0 路径长度最短的顶点u 加入到集合S 中,集合S 每加入一个新的顶点u,都要修改顶点v0 到集合T 中剩余顶点的最短路径长度值,集合T 中各顶点新的最短路径长度值为原来的最短路径长度值与顶点u 的最短路径长度值加上u 到该顶点的路径长度值中的较小值。此过程不断重复,直到集合T 的顶点全部加入到S 中为止。

Dijkstra 算法的实现:

首先,引进一个辅助向量D,它的每个分量D[i] 表示当前所找到的从始点v 到每个终点vi 的最短路径的长度。它的初态为:若从v 到vi 有弧,则D[i]为弧上的权值;否则置D[i]为∞。显然,长度为:

D[j]=Min{D[i]| vi∈V}
的路径就是从v 出发的长度最短的一条最短路径。此路径为(v ,vj)。

那么,下一条长度次短的最短是哪一条呢?假设该次短路径的终点是vk ,则可想而知,这条路径或者是(v, vk),或者是(v, vj, vk)。它的长度或者是从v 到vk 的弧上的权值,或者是D[j]和从vj 到vk 的弧上的权值之和。

依据前面介绍的算法思想,在一般情况下,下一条长度次短的最短路径的长度必是:
D[j]=Min{D[i]| vi∈V-S}
其中,D[i] 或者弧(v, vi)上的权值,或者是D[k]( vk∈S 和弧(vk, vi)上的权值之和。

根据以上分析,可以得到如下描述的算法:
(1)假设用带权的邻接矩阵edges 来表示带权有向图,edges[i][j] 表示弧〈vi, vj〉上的权值。若〈vi, vj〉不存在,则置edges[i][j]为∞(在计算机上可用允许的最大值代替)。S 为已找到从v 出发的最短路径的终点的集合,它的初始状态为空集。那么,从v 出发到图上其余各顶点(终点)vi 可能达到最短路径长度的初值为:
D[i]= edges[Locate Vex(G,v)][i] vi∈V
(2)选择vj,使得
D[j]=Min{D[i]| vi∈V-S}
vj 就是当前求得的一条从v 出发的最短路径的终点。令
S=S∪{j}
(3)修改从v 出发到集合V-S 上任一顶点vk 可达的最短路径长度。如果
D[j]+ edges[j][k]<D[k]
则修改D[k]为
D[k]=D[j]+ edges[j][k]
重复操作(2)、(3)共n-1 次。由此求得从v 到图上其余各顶点的最短路径是依路径长度递增的序列。