Dijkstra算法为什么不能用于负权图

Dijkstra算法是贪心算法,大概前提是,从当前的所有可能中就能找到全局的最优解,而负权图不满足这个条件(比如本文末尾的图例

让我们从它的算法步骤上仔细分析一下:(如果需要算法详解点这里

    1.将图上的初始点看作一个集合S,其它点看作另一个集合

    2.根据初始点,求出其它点到初始点的距离d[i] (若相邻,
        则d[i]为边权值;若不相邻,则d[i]为无限大)

    3.选取最小的d[i](记为d[x]),并将此d[i]边对应的点
        (记为x)加入集合S

    4.再根据x,更新跟 x 相邻点 y 的d[y]值:d[y] = min{
         d[y], d[x] + 边权值w[x][y] },因为可能把距离调小,所以这个更新操作叫做松弛操作。

    5.重复3,4两步,直到目标点也加入了集合,此时目标点所
        对应的d[i]即为最短路径长度。

在第三步中,若点 x 的 d[x] 值是最小的,就将此点加入集合,而这个 d[x] 便也就是 x 到初始点的最短距离了。

所以d[x]的确定尤其重要,而第三,四步中,d[x] 是根据已经处于集合中的点来更新的。

如果是正权图,集合内的点到初始点的最短距离已经确认了,把没在集合内的点加入路径只可能会增加无用的边,也就增加了路径长度;所以只根据集合内点的邻边来更新,就能得到当前的最小d[x]了。

但如果是负权图,注意上句话中的文字 “把没在集合内的点加入路径”,这个时候,如果边的长度是负的,就有可能产生更小的d[x]!而Dijkstra根本没有不会考虑 “把没在集合内的点加入路径”这种情况,这也就是Dijkstra算法目光短浅的原因。

 

这里有一个简单的例子:

    从A到B的最短路。

    用Dijkstra算法,第一步就能得到所谓的最短路径长度4,不会去考虑边(C,B)。

    而实际上最短路径却需要加入边(C, B),长度是2

评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值