• Dijkstra FORMCM


    Dijkstra 算法

        date: 2018/2/2
        author:pprp
        theme:Dijstra
    

    简述

    • 辅助空间

      • vis数组:记录是否已经判断过
        • dis数组:记录指定原点到其他点的距离
        • mp二维数组:记录图的信息
    • 初始化

      • vis数组:设置为false
      • dis:设置为原点为0,其余为inf
      • mp:初始化为inf
      • 最重要的初始化是将dis[i]=mp[st][i]
    • 遍历操作

      • 每次找到dis中最小且没有被访问过的点,将其作为起始点
      • 进行松弛操作
    • 得到结果

    形象化记忆

    以起始点为中心向外层层扩展,直到扩展到终点为止。
    参考

    程序源码

    • C++实现
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    
    using namespace std;
    
    const int inf = 0x3f3f3f3f;
    const int maxn = 1000;
    const int m = 6; //顶点个数
    const int n = 8; //边的个数
    
    int mp[maxn][maxn];
    int dis[maxn];
    bool vis[maxn];
    
    void dijkstra(int st){
    
        for(int i = 1 ;i <= m; i++ )
            dis[i] = mp[st][i];
        vis[st] = 1;
        dis[st] = 0;
        for(int i  = 1; i <= m ; i++){
            int Min = inf;
            int rec = -1;
            for(int j = 1; j <= m ; j++){
                if(!vis[j] && Min > dis[j])
                {
                    rec = j;
                    Min = dis[j];
                }
            }
            if(rec == -1)return ;
            vis[rec] = 1;
            for(int j = 1; j <= m ; j++){
                if(!vis[j] && mp[rec][j] != inf && dis[rec]+mp[rec][j] < dis[j]){
                    dis[j] = dis[rec] + mp[rec][j];
                }
            }
        }
    }
    
    
    int main(){
        for(int i = 0 ; i < maxn ; i++)
        {
            for(int j = 0 ; j < maxn ; j++)
            {
                mp[i][j] = inf;
            }
        }
        int x, y , z;
        memset(vis,0,sizeof vis);
        for(int i = 0; i < n ; i++){
            cin >> x >> y >> z;
            mp[x][y] = z;
        }
        dijkstra(1);
        for(int i = 1; i <= m ;i++)
            cout << dis[i] << " ";
        cout << endl;
    
    
        return 0;
    }
    
    
    • Matlab实现
    clc,clear all
    a=zeros(6);
    a(1,2)=50;a(1,4)=40;a(1,5)=25;a(1,6)=10;
    a(2,3)=15;a(2,4)=20;a(2,6)=25;
    a(3,4)=10;a(3,5)=20;
    a(4,5)=10;a(4,6)=25;
    a(5,6)=55;
    
    a=a+a'
    
    a(find(a==0))=inf %将a=0的数全部替换为无强大
    pb(1:length(a))=0;pb(1)=1;  %当一个点已经求出到原点的最短距离时,其下标i对应的pb(i)赋1
    index1=1; %存放存入S集合的顺序
    index2=ones(1,length(a)); %存放始点到第i点最短通路中第i顶点前一顶点的序号
    d(1:length(a))=inf;d(1)=0;  %存放由始点到第i点最短通路的值
    temp=1;  %temp表示c1,算c1到其它点的最短路。
    
    while sum(pb)<length(a)  %看是否所有的点都标记为P标号
    tb=find(pb==0); %找到标号为0的所有点,即找到还没有存入S的点
    d(tb)=min(d(tb),d(temp)+a(temp,tb));%计算标号为0的点的最短路,或者是从原点直接到这个点,又或者是原点经过r1,间接到达这个点
    tmpb=find(d(tb)==min(d(tb)));  %求d[tb]序列最小值的下标
    temp=tb(tmpb(1));%可能有多条路径同时到达最小值,却其中一个,temp也从原点变为下一个点
    pb(temp)=1;%找到最小路径的表对应的pb(i)=1
    index1=[index1,temp];  %存放存入S集合的顺序
    temp2=find(d(index1)==d(temp)-a(temp,index1));
    index2(temp)=index1(temp2(1)); %记录标号索引
    end
    d, index1, index2
    

    测试数据

    0 5 100
    0 4 30
    1 2 5
    0 2 10
    2 3 50
    3 5 10
    4 3 20
    4 5 60

  • 相关阅读:
    Chapter 2 JavaScript Basic
    第一感觉:依赖注入读书笔记之一(草稿版)
    JQuery IN ACTION读书笔记之一: JQuery选择器
    使用Razor
    非侵入式Ajax
    QT定制有标题的扁平化下拉框控件
    JavaScript之this,new,delete,call,apply
    实例解析C++虚表
    Python解析生成XML-ElementTree VS minidom
    从Python传递JSON到JavaScript
  • 原文地址:https://www.cnblogs.com/pprp/p/8406136.html
Copyright © 2020-2023  润新知