最短路算法

参考https://www.cnblogs.com/five20/p/7782931.html

一、Dijkstar(迪杰斯特拉)算法:

简介:此算法按路径长度(next点)递增顺序产生最短路。

步骤:

1.先将点集V分成两组:

·S:已求出最短路径的集合

·T:V-S(尚未确定最短路径的集合)

2.初始化

使S = {V0},T={其余顶点},T中顶点对应的距离值,若存在<V0,Vi>,则为<V0,Vi>弧上的权值,如不存在则为inf(无穷)。

3.从T中选区一个距离最小值W(贪心),加入S,对T中顶点的距离值进行修改,若W作为中间点反而比V0到Vi的距离长则修改此距离。

4.重复上述步骤,直到S中包含所有点为止。

PS:Dijkstar无法处理负权边。

二、Floyd算法

思想:从A节点到B节点只有两种方式:1.直接从A到B。2.间接(中间经历若干节点)到B。

如果distance(AK)+distance(KB)<distance(AB)则设置distance(AB) = distance(AK)+distance(KB)。

代码如下:

for(int k = 0;k<n;++k)

{

    for(int i =0;j<n;++i)

    {

        for(int j = 0;j<n;++j)

        {

            if(!(dist[i][k] == inf || dist[k][j] ==inf)&&(dist[i][k]+dist[k][j]<dist[i][j]))

            {

                   dist[i][j] =dist[i][k] + dist[k][j];

            }

        }

    }

}

三、Bellman-Ford(贝尔曼-福特)算法

简介:不停地进行松弛直到n-1次,如果n-1此还能松弛则说明有负环,此算法无法解出。

可以求边上带有负值,但不能求负环,且效率很低不想考虑,直接学习用队列优化的BF算法:SPFA

PS:Dijkstar算法与Bellman-Ford的不同:

Dijkstar:起点到S集合内的最短路径求出后不再改变,只有T集合里面的长度改变(贪心算法)。

Bellman-Ford:每次循环都要改dist[]直到算法结束。

算法使用条件:

1.单元最短路径

2.有向图和无向图(无向图可以看作为(u,v),(v,u)同属于边集E的有向图)

3.边权可正可负(如有负权回路输出错误信息)。

4.差分约束系统。

四、SPFA算法(缺点:复杂度高,不过可以优化)

用队列优化BF算法。

步骤:

1.先将每个节点存成估计值(起点为零,其余为inf)存储在数组dis中,用邻接表存储图,采用动态逼近法:建立一个队列存储待优化的节点,每次优化化时从队首取出节点u,用当前u点的最短路径的估计值对离开u点所指的v点进行松弛操作,如果v点的最短路径估计值变短了,且不在队列中,将其加入队尾,这样不断取出节点进行松弛操作,直至队列为空。

2.在执行第一步之前需要先判断是否有负环:

a.采用拓扑排序,时间很长,一般不用。

b.如果某个节点进入队列次数超过n则存在负环(n为顶点数)。

 

首先建立起始点a到其余各点的
最短路径表格

首先源点a入队,当队列非空时:
1、队首元素(a)出队,对以a为起始点的所有边的终点依次进行松弛操作(此处有b,c,d三个点),此时路径表格状态为:

首先源点a入队,当队列非空时:
1、队首元素(a)出队,对以a为起始点的所有边的终点依次进行松弛操作(此处有b,c,d三个点),此时路径表格状态为:

在松弛时三个点的最短路径估值变小了,而这些点队列中都没有出现,这些点
需要入队,此时,队列中新入队了三个结点b,c,d队首元素b点出队,对以b为起始点的所有边的终点依次进行松弛操作(此处只有e点),此时路径表格状态为:

在最短路径表中,e的最短路径估值也变小了,e在队列中不存在,因此e也要
入队,此时队列中的元素为c,d,e队首元素c点出队,对以c为起始点的所有边的终点依次进行松弛操作(此处有e,f两个点),此时路径表格状态为:

 

在最短路径表中,e,f的最短路径估值变小了,e在队列中存在,f不存在。因此e不用入队了,f要入队,此时队列中的元素为d,e,f

队首元素d点出队,对以d为起始点的所有边的终点依次进行松弛操作(此处只有g这个点),此时路径表格状态为:

在最短路径表中,g的最短路径估值没有变小(松弛不成功),没有新结点入队,队列中元素为f,g

队首元素f点出队,对以f为起始点的所有边的终点依次进行松弛操作(此处有d,e,g三个点),此时路径表格状态为:

 

在最短路径表中,e,g的最短路径估值又变小,队列中无e点,e入队,队列中存在g这个点,g不用入e,此时队列中元素为g,e队首元素g点出队,对以g为起始点的所有边的终点依次进行松弛操作(此处只有b点),此时路径表格状态为:

在最短路径表中,b的最短路径估值又变小,队列中无b点,b入队,此时队列中元素为e,b
队首元素e点出队,对以e为起始点的所有边的终点依次进行松弛操作(此处只有g这个点),此时路径表格状态为:

在最短路径表中,g的最短路径估值没变化(松弛不成功),此时队列中元素为b

队首元素b点出队,对以b为起始点的所有边的终点依次进行松弛操作(此处只有e这个点),此时路径表格状态为:

 

在最短路径表中,e的最短路径估值没变化(松弛不成功),此时队列为空了

最终a到g的最短路径为14

图解转自https://www.cnblogs.com/bofengyu/p/5004398.html

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值