7.5.1 弧上权值为非负情形的单源点最短路径问题
弧上权值为非负情形的单源点最短路径概念
- 弧上权值为非负情形的单源点最短路径问题:对于给定一个带权有向图G(G中所有弧上的权均为非负值)与源点v,求从v到G中其余各顶点的最短路径。
- 如图7-23所示的带权有向图。设源点为A,则源点A到其余顶点的最短路径分别为:
(A,B)路径长度为10,(A,D,C)路径长度为50,(A,D)路径长度为30,(A,D, C,E)路径长度为60。
- 对于这个问题的求解,迪杰斯特拉(Dijkstra)提出了按路径长度的递增次序,逐条产生最短路径的方法。
首先求出从源点vo到其余各顶点中长度最短的一条,然后参照它求出长度次短的一条最短路径,依此类推,直到从源点v。到其余各顶点的最短路径全部求出为止。
具体做法是:设集合S存放已经求出的最短路径的终点,初始状态时,集合S中只有一个源点vo(S={v0})。以后每求得一条最短路径(v0,…,vk),就将vk加入到集合S中,直到全部顶点都加入到集合S中,算法即可结束。图7-24给出了按照迪杰斯特拉算法对图7-23所示带权有向图逐步求最短路径的过程。
迪杰斯特拉算法实现过程
算法思路
- 在迪杰斯特拉算法中,为了记录当前找到的从源点v0到其余各顶点的最短路径长度,需引入一个辅助数组 dist[ ]。它的每一个分量dist[ i ]表示当前找到的从源点v0到终点vi的相对最短路径的长度。它的初始状态是:若从源点v0到顶点vi有弧,则dist[i]为该弧上的权值;否则dist[i]为∞。
- 同时,为了记录从源点v0到其余各顶点的最短路径,还需引入一个辅助数组 path[]。它的每一个分量path[ i ]表示从源点v0到顶点vi的最短路径上的顶点vi的直接前驱顶点。
- 设第一条最短路径为(v0,vi),则有 dist[ i ]=Min{dist[ j ] l vj属于V-S}
- 对于下一条最短路径:假设下一条最短路径的终点是vk,则下一条最短路径或者是(v0,vk).或者是(v0,vi,vk)。其长度或者是弧<v0,vk>上的权值,或者是dist[i]与弧<vi,vk>上的权值之和(可以用反证法证明)。因此,一般情况下,下一条长度次短的最短路径长度必是dist[x]=Min{dist[y] | vy属于V-S}
- 在每一次求得一条最短路径之后,就将其终点Vx,加入到顶点集合S,然后对其余各顶点Vy,(Vy属于V-S)修改其dist[y]:dist[y]=Min{dist[y],dist[x]+arcs[x][y]}。其中,arcs[xl[y]是弧<x,y>上的权值。
此图展示了上图7-23的辅助数组变化过程。
代码实现
template<class ElemType,class WeightType