最短路径一般来说是简单路径,即不包含环路的路径。一方面最短路径不能包含权重为负值的环路,因为若包含权重为负值的环路,则我们可以遍历这环路任意遍,则总是得到比之前权重值比之前少的最短路径,我们规定如果从源结点到某一结点的某条路径上存在权重为负值的环路,我们认为其最短路径权重值为负无穷。另一方面,如果最短路径包含权重值和为正值或0的环路,我们可以把这个环路删除,得到一个权重值更少或和之前一样的的最短路径,并且该路径是简单路径。因此不失一般性,我们可以假定找到的最短路径中没有环路,即它们都是简单路径。
有一个关于最短路径的定理,那就是最短路径的子路径也是最短路径,证明见算法导论第24章。
书中介绍了bellman-ford,利用拓扑排序和Dijkstra这三种算法来解决单源最短路径问题。它们的适用情形如下:
算法 | 适用情形 |
---|---|
bellman-ford | 有向图(能应用于无向图,因为可以把无向图理解为有向图),边的权重可以为负值,允许有环路,如果该环路权重和为负值,则算法会探测并报告其存在 |
利用拓扑排序 | 有向图,边的权重可以为负值,但不能有环路,所以不能应用于无向图 |
Dijkstra | 有向图(也能应用于无向图),边的权重必须不能为非负值,可以有环路,当然该环路的权重和为非负值 |
一:bellman-ford算法
bellman-ford算法解决的是一般情况下的单源最短路径问题,在这里,边的权重可以为负值。给定带权重的有向图**G=(V,E)和权重函数w: E->**R,bellman-ford算法返回一个布尔值,以表明是否存在一个从源结点可以到达的权重为负值的环路。如果存在这样一个环路,算法将告诉我们不存在解决方案,返回false;如果没有这种环路存在,算法将给出最短路径和它们的权重
bellman-ford算法通过对边进行松弛操作来渐渐地降低从源结点s到每个结点v的最短路径的估计值v.d,知道该估计值与实际的最短路径权重 δ