zoukankan      html  css  js  c++  java
  • ⑨讲图论第五课: BellmanFord算法求最短路

    贝尔曼-福特算法(Bellman-Ford)是由 RichardBellman 和 Lester Ford 创立的,求解单源最短路径问题的一种算法。有时候这种算法也被称为Moore-Bellman-Ford 算法,因为 Edward F. Moore 也为这个算法的发展做出了贡献。它的原理是对图进行V-1次松弛操作,得到所有可能的最短路径。其优于迪科斯彻算法的方面是边的权值可以为负数、实现简单,缺点是时间复杂度过高,高达O(VE)。但算法可以进行若干种优化,提高了效率。

    自然语言描述

    对有向图G(V,E),用贝尔曼-福特算法求以Vs为源点的最短路径的过程:
    建立dist[],表示目前已知源点到各个节点的最短距离,起始值dist[s]=0 ,其余皆为OO。
    建立pred[],pred[]表示某节点路径上的父节点,起始值皆为NULL。
    对(Vi,Vj)∈E,比较dist[Vi]+(Vi,Vj)和dist[Vj],并将小的赋给dist[Vj],如果修改了dist[Vj]则pred[Vj]=Vi(松弛操作)
    重复以上操作V-1次
    再重复操作一次,如dist[Vj]>dist[Vi]+(Vi,Vj),则此图存在负权环。

    原理

    松弛
    每次松弛操作实际上是对相邻节点的访问,第次松弛操作保证了所有深度为n的路径最短。由于图的最短路径最长不会经过超过条边,所以可知贝尔曼-福特算法所得为最短路径。

    负边权操作
    与迪科斯彻算法不同的是,迪科斯彻算法的基本操作“拓展”是在深度上寻路,而“松弛”操作则是在广度上寻路,这就确定了贝尔曼-福特算法可以对负边进行操作而不会影响结果。

    负权环判定
    因为负权环可以无限制的降低总花费,所以如果发现第次操作仍可降低花销,就一定存在负权环。

            for (int loop=1;loop<=n;loop++)
            {
                flag=true;
                for (int i=1;i<=n;i++)
                {
                    for (int j=1;j<=n;j++)
                    {
                        if (a[i][j]!=0)
                        {
                            if (dist[j]>dist[i]+a[i][j])
                            {
                                dist[j]=dist[i]+a[i][j];
                                flag=false;
                            }
                        }
                    }
                }
                if (flag)break;
            }


  • 相关阅读:
    n&(n-1)计算比特位1的个数的原理
    gentoo安装apache、nginx、php、mariadb、openssl(https)
    记一次基于vmware的gentoo安装
    Nim 游戏 -(拿石头游戏)
    八皇后问题(N皇后问题)
    ARM架构和Cortex的关系
    某些STM32芯片在开启看门狗后仿真到断点处看门狗不会停止计数导致程序复位的问题
    STM32F103 PB3,PB4特殊引脚的配置
    pc端自适应方案
    左右躲避障碍-神手ts版本
  • 原文地址:https://www.cnblogs.com/cyendra/p/3038395.html
Copyright © 2011-2022 走看看