算法导论 - 第25章 每对顶点间的最短路径
2011-12-16 22:50
232 查看
每对顶点间的最短路径的算法有三种,每一种都可以检测图是否存在weighg小于0的cycle。
前两种算法用了动态规划的方法,最后一种算法对每个定点计算单源最短路径。
与求单源最短路径的算法不同,求每对顶点间的最短路径的算法采用网的矩阵表示法(除了最后一种算法,最后一种算法采用图的邻接表表示法)。用矩阵W表示一个网,其中矩阵的元素W(i,j)表示顶点i到顶点j的edge的weight。如果顶点i到顶点j之间没有edge,则W(i,j)等于无穷大。W(i,i)等于0。
用n表示图中顶点的个数。
算法1:
用矩阵L(m)来表示每对顶点间的最短路径的weight,每对顶点之间的最短路径最多只有m条edge。
L(1)=W
L(m)(i,j) = min{L(m-1)(i,k) + W(k,j)};k=[1,n]
由于最短路径的长度(指edge的个数,不是只路径的weight)必然小于等于n-1,所以L(n-1)就是我们所需要求的。
L(1) ---> L(2) ---> L(3) ---> L(4) ---> ... ---> L(n-1)
该方法的时间复杂度为O(n^4)。
计算过程中,如果某个矩阵的对角线元素小于0,(对角线元素只能等于0或小于0),说明网中存在weight小于0的cycle。
算法2:
算法2的名字叫Floyd-Warshall Algorithm。该方法也是采用动态规划的方法。思路与算法1差不多。
用矩阵D(m)来表示每对顶点间的最短路径的weight,每对顶点之间的最短路径的中间结点(也就是最短路径中去掉source和destination后剩下的所有顶点)的编号最大为m。
D(0)=W (表示没有中间结点)
D(1)(i,j)=min{D(0)(i,1)+D(0)(1,j)}
D(m)(i,j)=min{D(m-1)(i,m)+D(m-1)(m,j)}
D(n)就是我们需要求的。
D(0) ---> D(1) ---> D(2) ---> D(3) ---> D(n)
算法复杂度为O(n^3)
计算过程中,如果某个矩阵的对角线元素小于0,(对角线元素只能等于0或小于0),说明网中存在weight小于0的cycle。
算法3:
算法3的名字叫Johnson's algorithm。该算法对每个顶点计算单源最短路径。单源最短路径的算法包括Bellman-Ford算法和Dijkstra算法。
如果对每个顶点采用Bellman-Ford算法,那就没什么事情。Bellman-Ford算法本身可以检测是否存在weight小于0的cycle。但Bellman-Ford的时间复杂度比Dijkstra算法没有优势,因此Johnson's algorithm是对每个顶点采用Dijkstra算法。由于Dijkstra算法的要求是网中不能存在weight小于0的edge。因此需要采取一些办法来解决这个问题。
Johnson's algorithm通过对每条edge重新赋予weight来保证每条edge的weight大于等于0。用W(u,v)表示顶点u到顶点v的weight,如果edge(u,v)不存在,则W(u,v)为无穷大。用W’(u,v)来表示新的weight。用D(i,j)来表示原来weight条件下,顶点i到顶点j之间的最短路径的weight,用D'(i,j)表示用W‘时,顶点i到顶点j之间最短路径的weight。G=(V,E,W), G' = (V,E,W')。
则显然,我们特地生成出个G’,肯定是要满足一定条件的。这些条件就是:
1 在G中,设p为顶点i到顶点j之间的最短路径,则p也必须是在G’中,顶点i到顶点j之间的最短路径。反之亦然。
2 显然,W‘(i,j)必须都大于等于0。
那么怎么生成W',使得G’满足以上两个条件呢?
假设对每个顶点映射一个值,用函数h来表示,即h(u)是某个数,u是图G中的任何一个顶点。
让W'(i,j) = W(i,j)+h(i)-h(j)
则不管h这个映射如何实现,用该方法产生的G‘满足条件1。
设p(i,j)是G中任何一对顶点的任一条路径的weight,p'(i,j)是该路径在G’中的weight。则有关系:p'(i,j) = p(i,j)+h(i)-h(j)
那如何构造h,使得G'满足条件2?
在G’中增加一个顶点s,增加n条edge:(s,v1),(s,v2)....(s,vn)。每条边的weight为0。
我们看看新构造的G‘。由于顶点s没有入边,所以v1,v2,v3...vn之间的任何最短路径都不会经过s。所以v1,v2,v3...vn中每对顶点的最短路径,最短路径的weight都保持不变。
以顶点s作为source,用Bellman-Ford算法求单源最短路径。求得d1,d2,d3...dn。显然,di必然小于等于0。
我们采用映射h(u)=du来计算W’,就可以使得G‘满足条件2。
证明:对edge(v,u),有du <= dv+W(v,u)。也就是h(u) <= h(v)+W(v,u),把v换成i,把u换成j,就是h(j) <= h(i)+W(i,j),即h(i)-h(j)>=-W(i,j)。
W'(i,j) = W(i,j)+h(i)-h(j)>=W(i,j) + (-W(i,j)) = 0。
Done!!
Johnson's algorithm伪代码如下所示:
1 构造G’
2 以顶点s为source,用Bellman-Ford算法求单源最短路径。如果存在weight小于0的cycle,返回。
3 计算W'(i,j) = W(i,j)+h(i)-h(j)。
4 对G‘中每个顶点(s除外)调用Dijkstra方法,每对顶点的最短路径的weight保存在矩阵D'(i,j)中。
5 D(i,j) = D'(i,j)+h(j)-h(i).
前两种算法用了动态规划的方法,最后一种算法对每个定点计算单源最短路径。
与求单源最短路径的算法不同,求每对顶点间的最短路径的算法采用网的矩阵表示法(除了最后一种算法,最后一种算法采用图的邻接表表示法)。用矩阵W表示一个网,其中矩阵的元素W(i,j)表示顶点i到顶点j的edge的weight。如果顶点i到顶点j之间没有edge,则W(i,j)等于无穷大。W(i,i)等于0。
用n表示图中顶点的个数。
算法1:
用矩阵L(m)来表示每对顶点间的最短路径的weight,每对顶点之间的最短路径最多只有m条edge。
L(1)=W
L(m)(i,j) = min{L(m-1)(i,k) + W(k,j)};k=[1,n]
由于最短路径的长度(指edge的个数,不是只路径的weight)必然小于等于n-1,所以L(n-1)就是我们所需要求的。
L(1) ---> L(2) ---> L(3) ---> L(4) ---> ... ---> L(n-1)
该方法的时间复杂度为O(n^4)。
计算过程中,如果某个矩阵的对角线元素小于0,(对角线元素只能等于0或小于0),说明网中存在weight小于0的cycle。
算法2:
算法2的名字叫Floyd-Warshall Algorithm。该方法也是采用动态规划的方法。思路与算法1差不多。
用矩阵D(m)来表示每对顶点间的最短路径的weight,每对顶点之间的最短路径的中间结点(也就是最短路径中去掉source和destination后剩下的所有顶点)的编号最大为m。
D(0)=W (表示没有中间结点)
D(1)(i,j)=min{D(0)(i,1)+D(0)(1,j)}
D(m)(i,j)=min{D(m-1)(i,m)+D(m-1)(m,j)}
D(n)就是我们需要求的。
D(0) ---> D(1) ---> D(2) ---> D(3) ---> D(n)
算法复杂度为O(n^3)
计算过程中,如果某个矩阵的对角线元素小于0,(对角线元素只能等于0或小于0),说明网中存在weight小于0的cycle。
算法3:
算法3的名字叫Johnson's algorithm。该算法对每个顶点计算单源最短路径。单源最短路径的算法包括Bellman-Ford算法和Dijkstra算法。
如果对每个顶点采用Bellman-Ford算法,那就没什么事情。Bellman-Ford算法本身可以检测是否存在weight小于0的cycle。但Bellman-Ford的时间复杂度比Dijkstra算法没有优势,因此Johnson's algorithm是对每个顶点采用Dijkstra算法。由于Dijkstra算法的要求是网中不能存在weight小于0的edge。因此需要采取一些办法来解决这个问题。
Johnson's algorithm通过对每条edge重新赋予weight来保证每条edge的weight大于等于0。用W(u,v)表示顶点u到顶点v的weight,如果edge(u,v)不存在,则W(u,v)为无穷大。用W’(u,v)来表示新的weight。用D(i,j)来表示原来weight条件下,顶点i到顶点j之间的最短路径的weight,用D'(i,j)表示用W‘时,顶点i到顶点j之间最短路径的weight。G=(V,E,W), G' = (V,E,W')。
则显然,我们特地生成出个G’,肯定是要满足一定条件的。这些条件就是:
1 在G中,设p为顶点i到顶点j之间的最短路径,则p也必须是在G’中,顶点i到顶点j之间的最短路径。反之亦然。
2 显然,W‘(i,j)必须都大于等于0。
那么怎么生成W',使得G’满足以上两个条件呢?
假设对每个顶点映射一个值,用函数h来表示,即h(u)是某个数,u是图G中的任何一个顶点。
让W'(i,j) = W(i,j)+h(i)-h(j)
则不管h这个映射如何实现,用该方法产生的G‘满足条件1。
设p(i,j)是G中任何一对顶点的任一条路径的weight,p'(i,j)是该路径在G’中的weight。则有关系:p'(i,j) = p(i,j)+h(i)-h(j)
那如何构造h,使得G'满足条件2?
在G’中增加一个顶点s,增加n条edge:(s,v1),(s,v2)....(s,vn)。每条边的weight为0。
我们看看新构造的G‘。由于顶点s没有入边,所以v1,v2,v3...vn之间的任何最短路径都不会经过s。所以v1,v2,v3...vn中每对顶点的最短路径,最短路径的weight都保持不变。
以顶点s作为source,用Bellman-Ford算法求单源最短路径。求得d1,d2,d3...dn。显然,di必然小于等于0。
我们采用映射h(u)=du来计算W’,就可以使得G‘满足条件2。
证明:对edge(v,u),有du <= dv+W(v,u)。也就是h(u) <= h(v)+W(v,u),把v换成i,把u换成j,就是h(j) <= h(i)+W(i,j),即h(i)-h(j)>=-W(i,j)。
W'(i,j) = W(i,j)+h(i)-h(j)>=W(i,j) + (-W(i,j)) = 0。
Done!!
Johnson's algorithm伪代码如下所示:
1 构造G’
2 以顶点s为source,用Bellman-Ford算法求单源最短路径。如果存在weight小于0的cycle,返回。
3 计算W'(i,j) = W(i,j)+h(i)-h(j)。
4 对G‘中每个顶点(s除外)调用Dijkstra方法,每对顶点的最短路径的weight保存在矩阵D'(i,j)中。
5 D(i,j) = D'(i,j)+h(j)-h(i).
相关文章推荐
- 算法导论代码 第25章 每对顶点间的最短路径
- 第25章:每对顶点间的最短路径—基于矩阵乘法的动态规划算法
- 算法导论 第二十五章:每对顶点间的最短路径
- 算法导论学习笔记(19)——每对顶点间的最短路径(基于Floyd_Warshall算法)
- 算法导论 ch25 每对顶点间的最短路径
- 算法导论 | 第25章 所有结点对的最短路径问题
- 算法导论第25章 所有结点对的最短路径问题Floyd等
- 算法导论-每对顶点间的最短路径习题解
- hnu12519 Travelling Tom 求所有顶点的最短路径(floyd)
- 第十三周--从一个顶点到其余各顶点的最短路径
- 第十三周上机实践—项目1(3)—Dijkstra算法的验证,从一个顶点到其余各顶点的最短路径
- 每对顶点间的最短路径之二——floyd warshall 收藏
- 每对顶点间最短路径;Floyd算法;写的很乱,判断太多了;没有用动态规划过程中构建路径;用O(n三次方)时间构造路径;
- 第十二周——项目一—最短路径(4)Floyd算法验证(每对顶点之间的最短路径)
- Geeks面试题:Floyd Warshall Algorithm 所有顶点之间的最短路径问题
- 第十三周 项目四 每对顶点之间的最短路径
- 算法导论 所有节点对的最短路径
- 算法导论 - 第24章 单源最短路径
- 设计一个算法,採用BFS方式输出图G中从顶点u到v的最短路径(不带权的无向连通图G採用邻接表存储)
- HDU6166Senior Pan(顶点子集最短路径-二进制划分集合)