本章考虑在给定的有向加权图G=(V, E),对于所有的节点u,v∈V,找到一条从节点u到节点v的最短路径。希望以表格的形式表示输出:第u行第v列给出的是节点u到节点v的最短路径权重。
对于这个问题,如果是运行|V|次单源最短路径算法来解决所有节点对的最短路径问题,每一次使用一个不同的节点做为源节点。如果所有边的权值是非负的,可以采用Dijkstra算法。如果采用数组来实现最小优先队列,算法的运行时间为O()=O(
)。使用二叉堆实现的最小优先队列将使算法的运行时间降低到O(VE lg V),这个时间在稀疏图的情况下有很大改进,因为稀疏图E <
。如果采用斐波那契堆来实现最小优先队列,其算法运行时间为O(
)。
如果图中有权重为负值的边,就必须采用效率更低的Bellman-Ford算法,这样的运行时间将使O(),在稠密图的情况下,该运行时间为O(
)。
本章研究的算法将能做到更好,同时,本章还讨论所有节点对最短路径问题与矩阵乘法之间的关系。
本章的多数算法采用邻接矩阵表示图,假定节点的编号为1,2,...,|V|,因此,算法的输入是n*n的矩阵W,该矩阵代表一个有n个节点的有向图的边的权重:
算法的输出也是一个n*n的矩阵D = ()。其中
= δ(i, j)。
为了解决所有顶点间最短路径问题,不仅要算出最短路径的权值,而且要计算出一个前驱节点矩阵,其中
在i=j或从i到j没有通路时为NIL,其他情况下表示从i到j的某条最短路径上j的前驱顶点。由
矩阵的第i行导出的子图应是根节点为i的一棵最短路径树。下面的算法将打印出从节点i到节点j的一条最短路径,该算法类似于22章的PRINT-PATH过程:
PRINT-ALL-PAIRS-SHORTEST-PATH(, i, j)
if i == j
print i
else if == NIL
print “no path from i to j exists”
else PRINT-ALL-PAIRS-SHORTEST-PATH(, i,
)
print j
本章使用大写字母表示矩阵,如W, L或D,使用带下标的小写字母表示矩阵中的个体元素,如、
或
。
一:最短路径和矩阵乘法
本节讨论一种动态规划算法,动态规划算法的步骤是:分析最优解的结构,递归定义最优解的值,自底向上计算最优解的值。
之前讨论单源最短路径问题时,已经证明一条最短路径的所有子路径都是最短路径。考虑从i到j的一条最短路径p,假定p最多包含m条边,假定没有权值为负值的环路,且m为有限值。如果i=j,则p的权重为0且不包含任何边。如果i和j不同,则将p分解为