算法导论复习——CHP25 多源最短路

问题描述        

        给定一个带权重的有向图G=(V,E),其权重函数为ω:E→R。 在图中,对所有的结点对 u,v∈V,找出从结点u到结点v的最短路径。 该问题的解以表格(二维数组)的形式给出:第u行第v列给出从结点u到结点v的最短路径权重。

约定

        1)结点编号:不失一般性,结点编号为1,2,…,|V|。

        2)成本邻接矩阵:图G用一个n╳n的邻接矩阵W=(wij)表示, 其中,

        3)允许存在权重为负值的边,但不能包含权重为负值的环路,否则无解。
        4)最短路径矩阵:算法的输出为一个n╳n的最短路径矩阵 D=(dij),其中dij表示从结点i到结点j的一条 最短路径的权重。算法结束时有dij=δ(i,j)。

        5)前驱结点矩阵: 前驱结点矩阵记为:П=(πij),其中

        利用前驱结点矩阵П可以计算出每对结点间的最短路径。 前驱结点矩阵П的第i行所诱导的子图是一棵根结点为i的最短路径树。 对于每个结点i∈V,定义图G对于结点i的前驱子图为 Gπ,i=(Vπ,i,Eπ,i),其中

        (见CHP24) 

        打印最短路的过程

动态规划做法

最短路径的最优子结构性质

        每条路径都是最短路径:考虑从结点i到结点j的一条最短路径p。假定p至多包含m条边(假定没有权重为负值的环路),且m为有限值。

         如果i=j,则p中不包含任何边,所以p的权重等于0;

        如果i ≠ j,则将路径p分解为 ,其中  p ’至多包含 m-1 条边,则p ’是从i到k的一条最短路径, 且δ(i,j)=δ(i,k)+Wkj。

递归解

        设l_{ij}^{(m)}是从结点i到结点j的至多包含m条边的任意路径中的最小权重。

        则

自底向上解 

(伪代码在给定W和L(m-1)的情况下计算L(m))

时间复杂度O(n^4)

发现这个计算过程实际上很类似于矩阵乘法(几乎完全一样),可以用矩阵快速幂优化到O(n^3lgn)

另一种DP——Floyd-Warshall算法

         算法允许图中存在负权重的边,但不能存在权重为负值的环路。

思路

        假定图G的结点集为V={1,2,…,n}。考虑其中的一个子集 {1,2,…,k},这里k是小于n的某个整数,并是其中的最大编号。 对于任意一对结点i,j∈V,定义p是从i到j、且所有中间结点均取自于集合{1,2,…,k}的最短路径。

        p是简单路径,且p的中间结点都不大于k。

        p从i 到 j,仅经过集合{1,2,…,k}中的结点,但,

  •                 不一定经过其中的每一个结点;
  •                 也可能不存在这样的路径,此时p的权重等于∞。

在从 i 到 j 之间中间结点均取自集合{1,2,…,k-1}的基础上,试图回答这样一个问题:结点k是否是路径p上的一个中间结点?

        1)如果结点k不是路径p上的中间结点,则p上的所有中间结点都属于集合{1,2,…,k-1}。  此时,从结点i到结点j的中间结点取自集合{1,2,…,k-1}的一条最短路径也是从结点i到结点j的中间结点取自集合 {1,2,…,k}的一条最短路径。

        2)如果结点k是路径p上的中间结点,则k将路径p分解为两段(如下图),最优子结构性,p1是从结点i到结点k的一条最短路径,且中间结点全部取自集合{1,2,…,k-1} 。 因为结点k不是路径p1上的中间结点,所以路径p1上的所有结点都 属于集合{1,2,…,k-1} 。 同理,p2是从结点k到结点j的一条最短路径,且中间结点全部取自集合{1,2,…,k-1}

故有状态转移方程:

         

伪代码

 时间复杂度O(n^3)

加入最短路径构建

        \pi _{ij}^{(k)}为从结点i到结点j的一条所有中间结点都取自集合 {1,2, …, k}的最短路径上j的前驱结点。

         

应用——计算传递闭包 

        定有向图G=(V,E),定义图G的传递闭包G*=(V,E*),其中 E*={(i,j):如果图G中包含一条从结点i到结点j的路径}。

        求有向图的传递闭包: 方法一:给E中每条边赋权重1,然后运行FLOYD-WARSHALL算法, 可以在Θ(n3)求出权重路径矩阵D。在D中若dij<n,则表示存在一条从结点i到结点j的路径;否则dij=∞。

        方法二:定义矩阵T ={tij},若存在一条从结点i到结点j的路径,tij=1,否则tij=0。
                        计算T:
                                对FLOYD-WARSHALL算法进行改造:用逻辑或操作(V)和
                        逻辑与操作(Λ)替换算术操作min和+,得以下计算公式:

用于稀疏图的Johnson算法

        Johnson算法:在稀疏图中求每对结点之间的最短路径权重。

        对稀疏图,Johnson算法优于Floyd-Warshall算法,时间复杂度可达O(V2lgV+VE)。

        Johnson算法使用Dijkstra算法和Bellman-Ford算法作为自己的子程序,可处理带有负权重的图。

        如果图中包含所有结点对的最短路径,Johnson算法输出一个包含所有结点对的最短路径权重矩阵;否则报告图中包含权重为负值的环路。

        重赋权重:Johnson算法使用重新赋予权重的技术求解。

        工作原理

                如果图G=(V,E)中所有的边权重ω皆为非负值,则通过对每个结点运行一次Dijkstra算法来找到所有结点对之间的最短路径;

                如果图G包含权重为负值的边,但没有权重为负值的环路, 则通过重赋权重,构造出一组新的非负权重值,然后使用上面同样的方法求解。

                新赋予的权重函数记为:\widehat{\omega} ,必须满足以下两个重要性质:

                1. 路径等价性:对于所有结点对u,v∈V,一条路径p是在使用权重函数ω时的从结点u到结点v的一条最短路径,当且仅当 p是在使用权重\widehat{\omega}时的从u到v的一条最短路径。 即不管是使用原来的权重函数还是新的权重函数,所能求出来的最短路径应是一致的。

                2. 非负性:对于所有的边(u, v),新权重为非负值。 即需要经过技术处理,把负权重的边的权重改造成非负值。

        引理

        (重新赋予权重并不改变最短路径) 给定带权重的有向图G=(V,E),其权重函数为ω:E→R,设h:V→R为任意函数, 该函数将结点映射到实数上。对于每条边(u,v)∈E,定义

        设p = <v_0,v_1,...v_k> 为从结点v0到结点vk的任意一条路径,那么,p是在使用权重函数ω时从结点v0到结点vk的一条最短路径, 当且仅当p是在使用权重函数\widehat{\omega}时从结点v0到结点vk的一条最短路径,即: ω(p)=δ(v0 ,vk ) 当且仅当 。 而且,图G在使用权重函数ω时不包含权重为负值的环路, 当且仅当p在使用权重函数\widehat{\omega}也不包含权重为负值的环路。

        剩下的问题就是如何找到使\widehat{\omega}非负的 h 函数

        对于图G构造一幅新图G’ =(V’ , E’),其中 V’ =V∪{s},s是一个新结点,s \notin V , 并令,对于所有结点v∈V,有ω(s,v)=0。 由于结点s没有入边,所以除了以s为源点的最短路径外,图G’ 中没 有其它包含s的最短路径。而且G'不包含权重为负值的环路当且仅当图G不包含权重为负值的环路。

        假定图G和图G’都不包含权重为负值的环路。 对于所有的结点v∈V’ ,定义:h(v)=δ(s,v)。 根据三角不等式,对于所有的边(u,v)∈E’ ,有 h(v)≤h(u)+ω(u,v)。 定义新权重 \widehat{\omega},有

        即满足要求。 

        伪代码

                先用Bellman-Ford算法计算s到各个结点的最短路径,并判断是否存在负权重的环路。

                再利用Bellman-Ford算法计算得到的δ(s,v)定义h(v)的值,并重新赋边的权重。

                然后对每个点跑一遍Dijkstra算法。

        时间分析

        算法的运行时间依赖于Dijkstra算法中最小优先队列的实现方式:

                如果使用斐波那契堆实现,则Johnson算法的运行时间为 O(V^2lgV + VE)

                如果使用二叉最小堆实现,则Johnson算法的运行时间为 O(VElgV)。

                在稀疏图的情况下,该算法的时间比Floyd-Warshall算法 的表现(O(V^3))要好

  • 40
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值