1.基础
最短路径简单说就是,一个带权重的有向图,图中从u到v的最短路径就是所有从u到v的路径中权重之和最小的。
最短路径具有最优子结构:两个节点之间的最短路径包含着其他的最短路径。这使得我们可以用动态规划或贪心算法来解决该问题。
最短路径可以包含负权重的边,但是不能包含权重为负值的环路。当然也不能包含权重为正值的环路。
下面介绍比较重要的最短路径和松弛操作的性质:
三角不等式性质:对于任何边(u,v) in E,我们有delta(s,v) <= delta(s,u)+w(u,v)。
上界性质:对于所有的节点v in V,总是有v.d >= delta(s,v)。一旦v.d的取值达到delta(s,v),其值将不再变化。
非路径性质:如果从节点s到节点v不存在路径,则总是有v.d = delta(s,v) = +inf。
收敛性质:对于某些节点u,v in V,如果s~u-->v是图G中的一条最短路径,并且在对边(u,v)进行松弛前的任意时间有u.d = delta(s,u),则在之后的所有时间有v.d = delta(s,v)。
路径松弛性质:如果p = <v_0,v_1,...,v_k>是从源节点s =v_0到节点v_k的一条最短路径,并且我们对p中的边所进行松弛的次序为(v_0,v_1),(v_1,v_2),...,(v_k-1,v_k),则v_k.d = delta(s,v_k)。该性质的成立与任何其他的松弛操作无关,即使这些松弛操作是与对p上的边所进行的松弛操作穿插进行的。
上面的性质并不难理解,但是对于理解后面的算法有着非常重要的作用,尤其是路径松弛性质,直接体现在后面的算法中。
2.算法
2.1 Bellman-Ford算法
通过对边进行松弛操作来渐进的降低从源节点s到每个节点v的最短路径的估计值v.d,直到该估计值与实际的最短路径权重delta(s,v)相同为止。该算法返回true,当且仅当输入图不包含可以从源节点到达的权重为负值的环路。如果存在权重为负值的环路,该算法可以检测到。
伪代码:
BELLMAN-FORD(G,w,s)
1. INITIALIZE-SINGLE-SOURCE(G,s)
2. for i = 1 to |G.V| - 1