**转载sharpdew《https://blog.csdn.net/sharpdew/article/details/446510》
在此基础上增加了一点自己的理解
推荐与论文《A SHORTEST PATHS RANKING ALGORITHM》一起看会比较好理解。**
前K个最短路径生成方法:
Step 1:
利用Dijkstra算法求得有向图(N,A)中以开始节点s为根的最短路径树,标记从开始节点s到结束节点t之间的最短路径为pk,K=1。
记录原点到当前节点k的最短路径πk和最短路径中节点k的前驱节点
Step 2:
如果k小于要求的最短路径的最大数目K,并且仍然有候选路径存在,令当前路径p=pk,转3。否则,程序结束。
Step 3:
找出当前路径p中从第一个节点开始的入度大于1的第一个节点,记为nh。
如果nh的扩展节点n’h不在节点集N中,则转4;否则找出路径p中nh后面所有节点中,其对应的扩展节点不在N中的第一个节点,记为ni,转5。
(入度:节点作为头部的连线数量,(i,j):i代表tail,j代表head)
Step 4:
为节点nh构建一个扩展节点n’h,并把其添加到集合N中。
同时从图(N,A)中所有nh的前驱节点连接一条到n’h的弧,弧对应的权重不变,添加这些弧到弧集A中,但nh在p中的前一个节点nh-1除外。
计算从开始节点s到n’h的最短路径,并记ni=nh+1。
Step 5:
对于p中从ni开始的所有后续节点,不妨记为nj,依次执行如下操作:
Step 5.1 添加nj的扩展节点n’j到节点集合N中。
Step 5.2 除了路径p中nj的前一个节点nj-1外,分别连接一条从nj前驱节点到其扩展节点n’j的弧,弧上的权值保持不变,并把这些弧添加到弧集A中。
另外,如果p中nj的前一个节点nj-1具有扩展节点n’j-1的话,也需要连接一条从n’j-1到n’j的弧,权值和弧(nj-1,nj)的权值相等。
Step 5.3计算从开始节点s到n’j的最短路径。
注:当节点nj为结束节点t时,由于t没有流出弧,因此去除t和其前驱节点的原有弧,生成新的弧:①前驱节点到t ②nj-1到t
Step 6:
更新当前最短路径树,求得从开始节点s到结束节点的当前扩展节点之间的最短路径为第k条最短路径,令k=k+1,转2继续。
注:在上述步骤4、5、6中均需要计算从开始节点到当前扩展节点的最短路径,因为程序开始时便生成了以开始节点为根的最短路径树,那么只要在扩充节点时,记录下每个新节点相对于开始节点的最短路径中其前一个节点编号,以及从开始节点到当前节点的最短路径长度。其中,最短路径长度通过下式计算:
因为从原点到当前节点的最短路径一定通过当前节点,而当前节点仅与前驱节点或前一个扩展节点(如果有)相连,因此,只要分别计算原点到前驱节点和前一个扩展节点的最短路径,再加上前驱节点和前一个扩展节点到当前节点的距离,将二者相比,即可得到当前节点的最短路径πk。
由此,就可以很容易求得任意时刻有向图中从开始节点到结束节点(或其扩充节点)之间的最短路径(标号法)。
K=1
K=2
K=3
K=4
K=5