参见贪心算法——最短路径Dijkstra算法
参见动态规划
目录
- 0.最短路径问题
0.1 最短路径问题描述
0.1.1 最短路径的定义
0.1.2 最短路径问题的几个变体
0.2 最短路径性质
0.2.1 最优子结构
0.2.2 最短路径的表示
0.2.3 松弛操作
0.2.4 最短路径和松弛操作的性质 - 1.单源最短路径
1.1 Bellman-Ford算法——针对每个结点进行|E|次松弛
1.1-1 SPFA算法——Bellman-Ford算法的改进
1.2 有向无环图中的单源最短路径问题——按拓扑排序进行松弛
1.3 非负权重有向无环图中的单源最短路径问题——Dijkstra算法(贪心)
1.4 (线性规划)差分约束和最短路径——(三角不等式)归约到单源最短路径问题 - 2.所有结点对的最短路径问题
2.1 最短路径和矩阵乘法
2.1.1 最优子结构
2.1.2 递归解
2.1.3 自底向上计算最短路径权重——Θ(n4)
2.1.4 改进算法的运行时间——Θ(n3lgn)
2.2 Floyd-Warshall算法——Θ(V3)(或Θ(n3))
2.2.1 最优子结构
2.2.2 递归解
2.2.3 自底向上计算最短路径权重
2.2.4 构建最短路径
2.2.5 有向图的传递闭包
2.3 基本方法Θ(n4)与Floyd-Warshall方法Θ(n3)对比
2.3.1 基本方法的核心(动态规划)
2.3.2 Floyd-Warshall方法的核心(动态规划)
2.3.3 两种方法的对比
2.4 用于稀疏图的Johnson算法
2.4.1 重新赋予权重维持最短路径(h是结点的函数,有点类似于摊还分析中的势函数)
2.4.2 通过重新赋值来生成非负权重——参考差分约束系统(三角不等式)
2.4.3 Johnson算法
2.5 三种计算所有结点对的算法对比
0.最短路径问题
0.1 最短路径问题描述
0.1.1 最短路径的定义
- 给定一个带权重的有向图G=(V, E)和权重函数w:E ->R,该权重函数将每条边映射到实数值的权重上。
图中一条路径p=0, v1, ..., vk>的权重w(p)是构成该路径的所有边的权重之和:
定义从结点u到结点v的最短路径权重δ(u, v)如下:
从结点u到结点v的最短路径则定义为任何一条权重为w(p) = δ(u, v)的从u到v的路径p。
0.1.2 最短路径问题的几个变体
- 单源最短路径问题
给定一个图G=(V, E),希望找到从给定源节点s∈V到每个结点v∈V的最短路径。 - 单目的地最短路径问题
找到从每个结点v到给定目的地结点t的最短路径。如果将图的每条边的方向翻转过来,可以将该问题转换为单元最短路径问题 - 单节点对最短路径问题
找到从给定结点u到给定v的最短路径。如果解决了针对单个结点u的单源最短路径问题,那么也就解决了这个问题 - 所有结点对最短路径问题
对于每对结点u和v,找到从结点u到结点v的最短路径。
0.2 最短路径性质
0.2.1 最优子结构
-
两个结点之间的一条最短路径包含着其他的最短路径。
0.2.2 最短路径的表示
- 最短路径不能包含权重为负值的环路。
- 最短路径也不能包含权重为正值的环路,因为只要将环路从路径上删除就可以得到一条源结点和终结点与原来路径相同的一条权重更小的路径。
- 最短路径也不包含权重为0的环路,总是可以去掉。
(针对单源最短路径问题)不失一般性,假定在找到的最短路径中没有环路,即它们都是简单路径。由于图G=(V, E)中的任意无环路径最多包含|V|个不同的结点,它也最多包含|V| - 1条边。
- 前驱子图Gπ = (Vπ, Eπ)
Vπ = {v ∈ V: v.π ≠ NIL} ∪ {s}
Eπ = {(v.π, v) ∈ E: v∈Vπ - {s}}
在单源最短路径算法终止时,Gπ是一棵最短路径树。 - 最短路径树:是一棵有根结点树,该树包括了从源节点s到每个可以从s到达的结点的一条最短路径。
一棵根节点为s的最短路径树是一个有向子图G' = (V', E'),这里V'属于V,E'属于E:
1)V'是图G中从源节点s可以到达的所有结点的集合
2)G'形成一棵根节点为s的树
3)对于所有的结点v∈V',图G'中从结点s到结点v的唯一简单路径是图G中从结点s到结点v的一条最短路径。
最短路径不一定是唯一的,最短路径树也不一定是唯一的
0.2.3 松弛操作
- v.d:记录从源节点s到结点v的最短路径权重的上界。v.d为s到v的最短路径估计。
- 松弛操作是唯一导致最短路径估计和前驱结点发生变化的操作。
- Dijkstra算法对每条边仅松弛一次;Bellman-Ford算法对每条边松弛|V| - 1次
0.2.4 最短路径和松弛操作的性质
1)三角不等式性质——最短路径的定义
2)上界性质
3)非路径性质
4)收敛性质——最优子结构
5)路径松弛性质
6)前驱子图性质
- 24.16本质上说明两点:
1)Gπ是一个有向无环图
2)对于每个结点v ∈Vπ,在图Gπ中存在一条从源节点s到结点v的唯一简单路径。
这里有一个说明:前驱结点赋值只在松弛操作的时候进行,一旦松弛操作发生,就表明源结点s到该结点v的和v.π的距离为有限值。s不可达的结点u当且仅当u.d = ∞。
归纳法:
初始时,开始时s从s可达,第一次运行之后,加入Vπ的结点是v.π = s的结点。也即v.π和v都属于Vπ,且v和v.π都可达
归纳步,假设v和v.π属于Vπ,v.π可达。因为(v.π, v)属于Eπ,则v可达,所以存在一条简单路径到v。
- 证明需要证明三点:
一棵根节点为s的最短路径树是一个有向子图G' = (V', E'),这里V'属于V,E'属于E:
1)V'是图G中从源节点s可以到达的所有结点的集合
2)G'形成一棵根节点为s的树
3)对于所有的结点v∈V',图G'中从结点s到结点v的唯一简单路径是图G中从结点s到结点v的一条最短路径。 - 24.17说明:
1)v.π≠NIL,则为从s可达
2)Gπ中的简单路径,说明经过了松弛了操作,即在操作前,一定有vi.d ≥ vi-1.d + w(vi-1, vi),否则不会成为前驱结点。
1.单源最短路径
1.1 Bellman-Ford算法——针对每个结点进行|E|次松弛
1)算法描述
- 该算法解决的是一般情况下的单元最短路径问题。边的权重可以为负值。
- 该算法返回一个布尔值,表明是否存在一个从源节点可以到达的权重为负值的环路。如果没有这种环路存在,算法将给出最短路径和它们的权重。
- 算法对图的每条边进行|V| - 1次处理。
- Bell-Ford算法的总运行时间为O(VE)
2)算法正确性证明
- 引理24.2关键是路径松弛性质
推论24.3关键是非路径性质
- 定理24.4关键是三角不等式、前驱子图性质
1.1-1 SPFA算法——Bellman-Ford算法的改进
1)算法描述
- 建立一个先进先出的队列用来保存待优化的结点,优化时每次取出队首结点u,并且用u点当前的最短路径估计值对离开u点所指向的结点v进行松弛操作,如果v点的最短路径估计值有所调整,且v点不在当前的队列中,就将v点放入队尾。这样不断从队列中取出结点来进行松弛操作,直至队列空为止。
- (参考prim最小生成树算法)关于SEARCH(Q, v),可以附加一个标志位来辅助,如果加入队列,则将结点的标志位置1,出对置0.初始化为0,这样可以在O(1)内对v是否属于队列Q进行判断。
2)算法正确性证明
- SPFA算法也是使用了松弛操作,松弛操作只会让路径距离越来越小
- SPFA将一个结点v松弛之后,如果v不在队列中,则将v加入队列。这是一个很直观的操作:结点v的距离减小了,那么从结点v发出的所有临近结点距离都可能减小,所以要一一检查。SPFA这样将距离更改的影响一层一层往下扩散,直至所有距离都是最小为止。
- 那么最短路径不存在呢?如果存在负权圈,并且起点可以通过一些顶点到达负权圈,那么利用SPFA算法会进入一个死循环,因为d值会越来越小,并且没有下限,使得最短路不存在。那么我们假设不存在负权圈,则任何最短路上的点必定小于等于|V|个(没有圈),换言之,用一个数组c[i]来记录i这个点入队的次数,所有的c[i]必定都小于等于n,所以一旦有一个c[i] > |V|,则表明这个图中存在负权圈。
证明循环不变式: 每次while循环前,所有可能引起松弛的点都在队列中
- 初始化:队列中只有s,s.d + w(s, v) < v.d = ∞,其他点不满足这个条件,只有s会引起松弛操作
- 保持:假设i次while循环之前,所有可能引起松弛的点都在队列中,那么i次while循环之后,去掉了u,将引起了松弛操作的所有v加入到队列中。
考虑v.d > u.d + w(u, v)的情况下x.d > v.d + w(x, d):
1)如果是循环之前已经成立,则v已经在队列中
2)如果是循环后的成立,那么要么是x.d增大(不可能)或者v.d减小,如果v.d减小,则要将v加入到队列中。
无论哪种情况都满足情况。 - 终止:队列为空,则所有的顶点都不能松弛了,都到了最小。
3)SPFA算法改进——贪心策略(迅速降低结点的路径,收敛更快)
- SLF:Small Label First 策略,设要加入的节点是j,队首元素为i,若dist(j)
- LLL:Large Label Last 策略,设队首元素为i,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,则将i出队进行松弛操作。
- SLF 可使速度提高 15 ~ 20%;SLF + LLL 可提高约 50%。
1.2 有向无环图中的单源最短路径问题——按拓扑排序进行松弛
1)算法描述
- 可以有权重为负值的边。
- 根据结点的拓扑排序来对带权重的有向无环图G=(V, E)进行边的松弛的操作,便可以在Θ(V + E)时间内计算出从单个源节点到所有结点之间的最短路径。
拓扑排序:有向无环图包含从结点u到结点v的一条路径,则u在拓扑排序的次序中位于v的前面。
- DAG——Directed Acyclic Graph有向无环图
- 运行时间:
1)拓扑排序时间为Θ(V + E)
2)初始化时花费Θ(V),松弛次数为Θ(E)
因此总时间为Θ(V + E)
2)算法正确性证明
- 关键在路径松弛性质
3)PERT图中的关键路径
- PERT——Program Evaluation and Review Technique。计划评审技术,简单地说,PERT是利用网络分析制定计划以及对计划予以评价的技术。它能协调整个计划的各道工序,合理安排人力、物力、时间、资金,加速计划的完成。在现代计划的编制和分析手段上,PERT被广泛地使用,是现代项目管理的重要手段和方法。
- PERT图是一个有向无环图,在图中,每条边代表需要进行的工作,边上的权重代表执行该工作所需的时间。
如果边(u, v)进入结点v,边(v, x)离开结点v,则工作(u, v)必须在工作(v, x)前完成。
PERT图中的一个路径代表的是一个工作执行序列。 - 关键路径是该有向无环图中一条最长的路径,该条路径代表执行任何工作序列所需要的最长时间。
因此,关键路径上的权重提供的是执行所有工作所需时间的下界 - 两种方法找到PERT图中的关键路径:
1)将所有权重变为负数,然后运行DAG-SHORTEST-PATHS
2)运行DAG-SHORTEST-PATHS,但进行如下修改:在INITIALIZE-SINGLE-SOURCE的第二行将正无穷改为负无穷,在RELAX过程中将>变为<
这里求的是源点s到各点的最长距离路径(这里默认PERT图所有权重都为正值),因此,要符号要变向,直观上是方法2);
当将所有权重变为负之后,求最小,即为求最大。
1.3 非负权重有向无环图中的单源最短路径问题——Dijkstra算法
1)算法描述——广度优先搜索
- 要求所有边的权重为非负值。
- 算法维持集合S,从源节点s到该集合中每个结点之间的最短路径已经被找到。
算法重复从结点集V-S中选择最短路径估计最小的结点u,将u加入到集合S,然后对所有从u发出的边进行松弛。
- 算法运行时间分析
三种优先队列操作:
1)第3行的INSERT操作——|V|
2)第5行的EXTRACT-MIN——|V|
3)第8行的DECREASE-MIN——|E|(聚合分析)
数组(1-|V|编号来维持)——O(V² + E),INSERT和DECREASE-KEY操作的时间为O(1),EXTRACT-MIN操作时间为O(V);
二叉堆——O((V+E)lgV);
斐波那契堆——O(VlgV+E);
2)算法正确性证明
- 理解的关键点有:收敛性质得到y.d = δ(s, y)
-
Dijkstra算法的贪心选择性质:
1)加入集合S的,都有u.d = δ(s, u);此时与S中点相邻的点v都已经被松弛过了。并且s到最小的v必然存在一条最短路径,并且已经被松弛过了,因此v.d=δ(s, v)肯定成立。
2)为什么s到最小的v存在一条最短路径,而且必然是s~u-v,因为所有的路径是非负的,并且v还未加入到S中,所以任何经过其他路径再到v的路径都要比这条路径长。
1.4 (线性规划)差分约束和最短路径——(三角不等式)归约到单源最短路径问题
1.4.1 线性规划
- 单源单目的地最短路径问题和最大流问题都是线性规划问题的特例。存在着更快的算法。
1.4.2 差分约束系统——判断是否存在可行解
1)差分约束系统
等价于:
- 差分约束系统在许多不同的应用里都会出现。
xi可能代表事件发生的时间。每个约束条件给出的是在两个事件之间必须间隔的最短时间或最长时间。
2)约束图——从图论的观点来理解差分约束系统
- 在Ax ≤ b的差分约束系统中,将m x n的线性规划矩阵A看作是一张由n个结点和m条边构成的图的邻接矩阵的转置。
a.每个结点vi(其中i=1,2,...,n)对应n个未知变量xi中的一个
b.每条有向边对于m个不等式中的一个,如果xj - xi ≤ bk是一个差分约束条件,则边(vi, vj)的权重为bk。
上图对应的约束图为:
- 关键在于三角不等式
3)求解差分约束系统——Bellman-Ford算法
- 现在的算法是n+1个结点和n+m条边,因此运行时间为O((n+1)(n+m))
-
可以修改算法,使其能够在O(nm)时间内完成运算,即使m远远小于n。
4)求解差分约束系统——Bellman-Ford算法的改进
- 差分约束系统转换为的约束图有三个特点:
1)如果首先按照边{(0,1) (0,2) (0,3) (0,4) (0,5)}进行松弛,则vi.d(其中1≤ i ≤5)均为0
2)因为v0只有出边,所以v0.d一直不变,一直为0
3)因此后面每次按照边{(0,1) (0,2) (0,3) (0,4) (0,5)}进行松弛时,vi.d(其中1≤ i ≤5)的值都不会变化
因为,松弛只会减小vi.d(其中1≤ i ≤5)的值,而第一次松弛已经就变为0
- 因此,根据上述特点,有如下的修改:
一个可行的方案是,将每个结点赋初值0,从而省略掉初始源点。因为初始源点只有出边,没有入边,所以迭代过程不会影响初始源点以及初始源点到任一点的路径权值。这样可以将边的数量降为m,结点数量降为n,总时间为O(n*m)。
2.所有结点对的最短路径问题
- 可以运行|V|次单源最短路径算法,来解决所有结点对之间的最短路径问题。
- 使用邻接矩阵表示图。权重矩阵W=(wij)
- 最短路径输出表示为矩阵D = (dij),其中dij代表的是从结点i到结点j的一条最短路径的权重。
- 还需要计算前驱结点矩阵Π = (πij),其中πij在i = j或从i到j不存在路径时为NIL,在其他情况下给出的是从结点i到结点j的某条最短路径上结点j的前驱结点。
对于每个结点i ∈V,定义图G对于结点i的前驱子图为Gπ,i = (Vπ,i, Eπ,i),其中:
Vπ,i = {j ∈V: πij ≠ NIL}∪{i}
Eπ,i = {(πij, j): j ∈Vπ,i - {i}}
如果Gπ,i是一棵最短路径树,则下面的过程将打印出从结点i到结点j的一条最短路径。
2.1 最短路径和矩阵乘法
2.1.1 最优子结构
- 一条最短路径的所有子路径都是最短路径。(假定没有负值的环路)
2.1.2 递归解
-
设lij(m)为从结点i到结点j的至多包含m条边的任意路径中的最小权重。
1)当m=0
2)当m≥1
因为对于j有wjj=0,所以后面的等式成立。 -
没有负值环路,由于该路径是简单路径,其包含的边最多是n-1条。从结点i到结点j的由多于n-1条边构成的路径(含有正值环路)不可能比从i到j的最短路径权重更小的权重。
2.1.3 自底向上计算最短路径权重——Θ(n4)
- 递归计算出矩阵序列L(1), L(2),..., L(n-1)。有L(m) = (lij(m))。
最后的矩阵L(n-1)包含的是最短路径的实际权重。
并且有L(1) = W。
2.1.4 改进算法的运行时间——Θ(n3lgn)
1)矩阵乘法与EXTEND-SHORTEST-PATHS的对比
2)利用矩阵乘法的思想改进算法
关键点1.目标不是要计算所有的L(m),感兴趣的仅仅是L(n-1)。
-
关键点2.对于所有的m ≥ n-1,有L(m) = L(n-1)。
-
关键点3.为什么这样算也是可以的?
因为EXTEND-SHORTEST-PATHS过程定义的乘法满足结合律。
EXTEND-SHORTEST-PATHS过程只要将矩阵乘法中的+改为min,乘法改为+即可:
2.2 Floyd-Warshall算法——Θ(V3)(或Θ(n3))
- 不能存在负值环路
2.2.1 最优子结构
- Floyd-Warshall算法考虑的是一条最短路径上的中间结点,简单路径p =
1, v2,..., vk>的中间结点指的是除v1,vk之外的任意结点。 - 假设G的所有结点为V={1, 2, ..., n},考虑其中的一个子集{1, 2, ..., k},k是某个小于n的整数。
对于任意结点对i,j,考虑从结点i到结点j的所有结点均取自集合{1, 2, ..., k}的路径,设p为其中权重最小的路径(p是简单路径)。
1)如果k不是路径p的中间结点,则路径p上的所有中间结点都属于集合{1, 2, ..., k-1};
2)如果k是路径p的中间结点,将p分解为(i ~ k)p1和(k~j)p2。因此p1和p2的中间结点均是取自集合{1, 2, ..., k-1}的一条最短路径。
2.2.2 递归解
- 设dij(k)表示从结点i到结点j的所有中间结点全部取自集合{1, 2, ..., k}的一条最短路径的权重。
对于任何路径来说,所有的中间结点都属于集合{1, 2, ..., n},矩阵D(n) = (dij(n))给出最后的答案。
2.2.3 自底向上计算最短路径权重
-
该算法的空间可以降低到Θ(n2)
-
有一种解释dik(k) = dik(k-1),因为两个端点为i和k,那么中间的点肯定不包括k,否则包括两个k点,形成环路,必然是负值环路。
算法运行时间为Θ(n3)
-
证明dij(k)计算的最短路径上没有环路(环路都是非负值)
这个证明也等同于证明i-k和k-j上的最短路径不可能经过相同的点,作为Floyd-Warshall算法正确性证据之一。
2.2.4 构建最短路径
1)方法1
- 先计算出最短路径权重矩阵D,然后从D矩阵来构造前驱矩阵Π,该方法的运行时间可限制在O(n3)。
2)方法2
-
可以在计算矩阵D(k)的同时计算前驱矩阵Π(k)。
Π = Π(n);
πij(k)为从结点i到结点j的一条所有中间结点都取自集合{1, 2, ..., k}的最短路径上j的前驱结点。
1)k = 0
从i到j的一条最短路径没有中间结点,因此
2)k ≥ 1, k ≠ j
-
证明:对于所有的结点i ∈V,前驱子图Gπ,i是一棵根节点为i的最短路径树。
也即证明矩阵π的第i行所诱导的子图应当是一棵根节点为i的最短路径树。
(本质)也即证明从任何结点出发的到其他所有结点的最短路径构成一棵最短路径树。
1)前驱子图的定义
πij在i = j或从i到j不存在路径时为NIL,在其他情况下给出的是从结点i到结点j的某条最短路径上结点j的前驱结点。
πij(k)为从结点i到结点j的一条所有中间结点都取自集合{1, 2, ..., k}的最短路径上j的前驱结点。
对于每个结点i ∈V,定义图G对于结点i的前驱子图为Gπ,i = (Vπ,i, Eπ,i),其中:
Vπ,i = {j ∈V: πij ≠ NIL}∪{i}
Eπ,i = {(πij, j): j ∈Vπ,i - {i}}
如果Gπ,i是一棵最短路径树,则下面的过程将打印出从结点i到结点j的一条最短路径。
2)证明关键点
πij(k) = l,意味着dij(k) > il(k) + wlj。(严格对于时,l ≠ j)因为确定为前驱时,一定意味着dij变小了,在调整之前,则肯定是大于。
因此借助于定理24.16可以证明是正确的。
这里有一个说明:前驱结点赋值只在松弛操作的时候进行,一旦松弛操作发生,就表明源结点s到该结点v的和v.π的距离为有限值。s不可达的结点u当且仅当u.d = ∞。
归纳法:
初始时,开始时s从s可达,第一次运行之后,加入Vπ的结点是v.π = s的结点。也即v.π和v都属于Vπ,且v和v.π都可达
归纳步,假设v和v.π属于Vπ,v.π可达。因为(v.π, v)属于Eπ,则v可达,所以存在一条简单路径到v。
2.2.5 有向图的传递闭包
- 传递闭包
给定有向图G=(V, E),结点集合为V={1, 2, ..., n},判断对于所有的结点i和j,图G是否包含一条从结点i到结点j的路径,定义图G的传递闭包为图G* = (V, E*)
E* = {(i, j):如果图G中包含一条从结点i到j的路径} - 方法1——Floyd-Warshall算法——Θ(n3)
给E中每条边赋予权重1,然后运行Floyd-Warshall算法。如果存在一条从i到j的路径,则有dij < n;否则,dij = ∞。 - 方法2——Θ(n3)
用逻辑或和逻辑与操作替换Floyd-Warshall算法中的算术操作min和+。
对于i, j, k ∈ {1, 2, ..., n},定义:如果G中存在一条从结点i到结点j的,且所有中间结点都取自集合 {1, 2, ..., k}的路径,则tij(k)为1,否则为0。
构建G* = (V, E*)的方法为:将边(i, j)置于集合E*中当且仅当tij(n)为1。
1)如果k = 0,
2)如果k ≥ 1,
2.3 基本方法Θ(n4)与Floyd-Warshall方法Θ(n3)对比
2.3.1 基本方法的核心
- 设lij(m)为从结点i到结点j的至多包含m条边的任意路径中的最小权重。
1)当m=0
2)当m≥1,因为对于j有wjj=0,所以后面的等式成立。
- 递归计算出矩阵序列L(1), L(2),..., L(n-1)。有L(m) = (lij(m))。
最后的矩阵L(n-1)包含的是最短路径的实际权重。
并且有L(1) = W。
2.3.2 Floyd-Warshall方法的核心
-
假设G的所有结点为V={1, 2, ..., n},考虑其中的一个子集{1, 2, ..., k},k是某个小于n的整数。
对于任意结点对i,j,考虑从结点i到结点j的所有结点均取自集合{1, 2, ..., k}的路径,设p为其中权重最小的路径(p是简单路径)。
1)如果k不是路径p的中间结点,则路径p上的所有中间结点都属于集合{1, 2, ..., k-1};
2)如果k是路径p的中间结点,将p分解为(i ~ k)p1和(k~j)p2。因此p1和p2的中间结点均是取自集合{1, 2, ..., k-1}的一条最短路径。
-
设dij(k)表示从结点i到结点j的所有中间结点全部取自集合{1, 2, ..., k}的一条最短路径的权重。
对于任何路径来说,所有的中间结点都属于集合{1, 2, ..., n},矩阵D(n) = (dij(n))给出最后的答案。
- 该算法的空间可以降低到Θ(n2)
2.3.3 两种方法的对比
- 基本方法是将dij分解为dik和一条边(k, j),当然dik的边数减一。
因此,计算的时候,要针对k的所有可能性进行遍历。 - Floyd-Warshall的方法是将dij分解为两段,dik和dkj
- Floyd-Warshall相对于基本方法,是怎样去掉大量冗余计算的,这种思路是怎样得来的?
Floyd-Warshall利用的是去掉特定的点,比如顶点集合{1, 2, ..., k},逐渐去掉点k, k-1, ..., 1。
这跟去掉一个边不同(去掉与j相连的边),因为你不知道去掉的是哪个边,所以要遍历与j相连的所有顶点(k->j),找出最小的,确定去掉的是哪个边。
这里最大的不同是:Floyd-Warshall去掉中间一个确定的点,不用遍历求最小;基本方法去掉一个不确定的边,需要遍历找到是哪个边
2.4 用于稀疏图的Johnson算法
Johnson可以在O(V²lgV+VE)时间内找到所有结点对之间的最短距离。
对于稀疏图,Johnson算法的渐近表现要优于重复平方法和Floyd-Warshall算法。Johnson可以报告包含一个权重为负值的环路。
Johnson算法使用Dijkstra算法和Bellman-Ford算法作为子程序。Johnson算法的核心技术是重新赋予权重。
1)如果G=(V, E)中所有的权重w为非负值,可以通过对每个结点运行一次Dijkstra来找到所有结点对之间的最短路径。如果使用斐波那契堆最小优先队列,该算法的运行时间为O(V²lgV+VE)。
2)如果G包含权重为负值的边,但没有负值的环路,那么只要计算出一组新的非负权重值,然后使用1)中的方法。
3)对于有负值环路的,报告存在负值环路。新赋予的权重w'必须满足两个重要性质:
1)(重新赋予权重维持最短路径)对于所有结点对u, v ∈V,一条路径p是在使用权重函数w时从u到v的一条最短路径,当且仅当p是使用权重函数w'时从u到v的一条最短路径。
2)(权重为非负值)对于所有的边(u, v),新权重w'(u, v)为非负值。
2.4.1 重新赋予权重维持最短路径(h是结点的函数,有点类似于摊还分析中的势函数)
-
关键是将h定义为结点的函数,类似于势函数,这样路径上中间可以进行裂项抵消。
2.4.2 通过重新赋值来生成非负权重——参考差分约束系统(三角不等式)
对于原图G=(V, E)制作一个对应的新图。
新图G' = (V', E'),其中:
V' = V ∪ {s},s是一个新结点s ∉ V;
E' = E ∪ {(s, v): v ∈ V};w权重函数进行扩展
1)对于所有的结点v ∈ V, w(s, v) = 0。
结点s没有进入的边,除了以s为源节点的最短路径外,图G'中没有其他包含结点s的最短路径。且G'不包含权重为负值的环路当且仅当图G不包含权重为负值的环路。
2)假设G和G'都不包含权重为负值的环路
对于所有的结点v ∈ V',h(v) = δ(s, v)。
根据三角不等式,对于所有的边(u, v) ∈ E',有h(v) ≤ h(u) + w(u, v).
因此定义w'(u, v) = w(u, v) + h(u) - h(v) ≥ 0.
因此所有的边都是非负的。
2.4.3 Johnson算法
2.5 三种计算所有结点对的算法对比
基本方法和重复平方法——Θ(n4)和Θ(n3lgn)
1)动态规划
2)基本方法去掉一个不确定的边,需要遍历找到是哪个边
3)重复平方法与基本方法的区别在于:基本方法到最终解,每次增加一条边;重复平方法每次增加一倍。Floyd-Warshall——Θ(n3)
1)动态规划
2)Floyd-Warshall去掉中间一个确定的点,不用遍历求最小Johnson算法——O(V²lgV+VE)(稀疏图特别适合)
1)基于Bellman-Ford判断是否有负值环路
2)最大的特色是基于单源最短路径算法来进行,对每一点分别利用Dijkstra算法(时间效率最好的单源最短路径算法)
2)Dijkstra算法有限值,就利用“差分约束系统”里面的方法,利用三角不等式,将w'(u, v)变成非负的