Bellman-Ford
    date: 2018/2/2
    author:pprp
    theme:Dijstra

简介

  • 单源最短路问题
  • 要求: 图中不能出现负圈
  • 思路:
    Bellman-Ford算法就是遍历所有的边进行\(n-1\)次更新(每次更新就是对所有的可用节点进行松弛)
  • 对比:Dijkstra算法:重复比较多,对每个都要进行松弛,这事实上是没有必要的,但是也是可以保证结果的准确性

代码实现

  • C++实现
#include <iostream>

using namespace std;
const int MAX_E = 1000;
const int MAX_V = 1000;
const int inf = 0x3f3f3f3f;
struct edge{
    int from;
    int to;
    int cost;
};

edge es[MAX_E];
int d[MAX_V];
int V, E;

void shortest_path(int s){
    for(int i = 0 ; i < V; i++){
        d[i] = inf;
    }
    d[s] = 0;
    while(true){
        bool update = false;
        for(int i = 0 ; i < E; i++){
            edge e = es[i];
            if(d[e.from] != inf && d[e.to] > d[e.from] + e.cost){
                d[e.to] = d[e.from] + e.cost;
                update = true;
            }
        }
        if(!update)break;
    }
}
int main() {
    cin >> V >> E;
    int x, y, z;
    for(int i = 0 ; i < E; i++){
        cin >> es[i].from >> es[i].to >> es[i].cost;
    }
    shortest_path(0);
    for(int i = 0 ; i < V; i++){
        cout << d[i] << " ";
    }
    cout << endl;
    return 0;
}
clear all;close all;clc
%初始化邻接压缩表
b=[1 2 6;
4 7
3 5;
4 8;
5 -4;
2 -2;
3 -3;
5 9;
1 2;
3 7];

m=max(max(b(:,1:2)));            %压缩表中最大值就是邻接矩阵的宽与高
A=compresstable2matrix(b);  %从邻接压缩表构造图的矩阵表示
netplot(A,1)                %形象表示

S=inf(1,m);                 %源到其他节点的最短距离,开始为inf
S(1)=0;                     %源点到自己的距离为0
pa=zeros(1,m);              %寻找到的节点的前趋
pa(1)=1;                    %源点的前趋是自己

pre_pa=ones(1,m);
while sum(pre_pa==pa)~=m    %终止条件,判断终止的方法很多,这个应该不是最佳实践
    pre_pa=pa;
    for k=1:m
        if pre_pa(k)~=0                 %对每一个已搜寻到的节点,从此节点寻找后继节点
            i=k;
            for j=1:m
                if A(i,j)~=inf
                    if S(j)>S(i)+A(i,j)
                        S(j)=S(i)+A(i,j);       %边缘松弛,取两节点间最小权值作为实际权值
                        pa(j)=i;                %寻找前趋
                    end
                end
            end
         end
    end
end
%最终我们需要的就是这两个值
S       %源点到其他每一点的距离
pa      %其他每一节点的前趋

%算法到此结束,下面只是为了形象的表示而写的。
re=[];
for i=2:m
    re=[re;pa(i) i A(pa(i),i)];
end
A=compresstable2matrix(re);  %从邻接压缩表构造图的矩阵表示
figure;
netplot(A,1)                %形象表示

function A=compresstable2matrix(b)
    [n ~]=size(b);
    m=max(max(b(:,1:2)));
    A=inf(m,m);

    for i=1:n
        A(b(i,1),b(i,2))=b(i,3);
    end

end

代码改变世界