• Bellman—Ford算法思想


    ---恢复内容开始---

    Bellman—Ford算法能在更普遍的情况下(存在负权边)解决单源点最短路径问题。对于给定的带权(有向或无向)图G=(V,E),其源点为s,加权函数w是边集E的映射。对图G运行Bellman—Ford算法的结果是一个布尔值,表明图中是否存在着一个从源点s可达的负权回路。若存在负权回路,单源点最短路径问题无解;若不存在这样的回路,算法将给出从源点s到图G的任意顶点v的最短路径值d[v]

    Bellman—Ford算法流程
     
    分为三个阶段:
          (1)初始化:将除源点外的所有顶点的最短距离估计值
             dis[v]ß+∞,dis[s]ß0;
          (2)迭代求解:反复对边集E中的每条边进行松弛操作,使得顶点集v中的每个顶点v的最短距离估计值逐步逼近其最短距离;
          (3)检验负权回路:判断边集E中的每一条边的两个端点是否收敛。如果存在未收敛的顶点,则算法返回false,表明问题无解;否则算法返回true,并且从源点可达的顶点v的最短距离保存在dis[v]中。
     
    【程序】
     1 {单源最短路径的Bellman-ford算法执行v-1次,每次对每条边进行松弛操作如有负权回路则输出"Error"}
     2  const
     3   maxn=100;
     4   maxe=maxn*(maxn-1)div 2;
     5  type
     6   edge=record
     7          a,b,w  :integer;
     8        end;
     9  var
    10   edges :array[1..maxe]of edge;
    11   dis   :array[1..maxn]of integer;
    12   pre   :array[1..maxn]of integer;
    13   e,n,s :integer;
    14  procedure init;
    15  var
    16   i     :integer;
    17  begin
    18   e:=0;
    19   assign(input,'g.in');reset(input);
    20   readln(n,s);
    21   while not eof do
    22     begin
    23       inc(e);
    24       with edges[e] do readln(a,b,w);
    25     end;
    26   fillchar(dis,sizeof(dis),$7f);//初始值为无穷大
    27   dis[s]:=0;pre[s]:=s;
    28  end;
    29  procedure relax(u,v,w:integer);
    30  begin
    31   if dis[u]+w<dis[v] then
    32     begin
    33       dis[v]:=dis[u]+w;
    34       pre[v]:=u;
    35     end
    36  end;
    37  function bellman_ford:boolean;
    38  var
    39   i,j   :integer;
    40  begin
    41   for i:=1 to n-1 do
    42     for j:=1 to e do
    43       with edges[j] do relax(a,b,w);
    44   for i:=1 to e do
    45     with edges[i] do
    46       if dis[a]+w<dis[b] then exit(false);
    47   exit(true)
    48  end;
    49  procedure print_path(i:integer);
    50  begin
    51   if pre[i]<>s then print_path(pre[i]);
    52   write('-->',i)
    53  end;
    54  procedure show;
    55  var
    56   i     :integer;
    57  begin
    58   for i:=1 to n do
    59     begin
    60       write(i:3,':',dis[i]:3,':',s);
    61       print_path(i);
    62       writeln
    63     end;
    64  end;
    65  {========main========}
    66  begin
    67  init;
    68  if bellman_ford then show
    69   else writeln('Error!!')
    70  end.

    ---恢复内容结束---

  • 相关阅读:
    2012年互联网教育行业观察
    SharePoint 2013的简单介绍
    让Node.js在Azure上运行3
    让Node.js在Azure上运行2
    有一个字符串 "I am a good man",设计一个函数,返回 "man good a am I"。
    json序列化与反序列化
    golang连接mysql数据库进行查询
    简单的WCF服务
    百钱买百鸡问题
    大叔程序员的第九天 @广播启动Activity
  • 原文地址:https://www.cnblogs.com/vacation/p/4863678.html
Copyright © 2020-2023  润新知