• Bellman-Ford FORMCM


    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
    
    
  • 相关阅读:
    二叉查找树
    Hash算法原理理解
    算法的时间复杂度
    解决Ubuntu14.04下Clementine音乐播放器不能播放wma文件的问题
    Ubuntu 14.04 开启启动器图标最小化功能
    Ubuntu14.04建立WiFi热点
    C语言运算符优先级
    老鸟的Python入门教程
    MD5算法步骤详解
    MD5算法
  • 原文地址:https://www.cnblogs.com/pprp/p/8406146.html
Copyright © 2020-2023  润新知