zoukankan      html  css  js  c++  java
  • 图-最短路径

        最短路径:对于网图来说,最短路径是指两个顶点之间经过的边上权值之和最少的路径,并且我们称路径上的第一个顶点式源点,最后一个顶点是终点。以下图为例,

         寻找v0到v8的最短距离。

       对应解决思路:现在比较成熟的有Dijkstra(迪杰斯特拉)算法Flord算法算法。

      Dijkstra(迪杰斯特拉)算法

         Dijkstra求源节点S到终结点D的最短距离的过程中,循环过程中每次确定一个源节点到其它节点T的最短距离。该距离确定后,遍历判断该节点T到其它节点的距离是否比现在S到其它节点距离短,更短的话则修改为相应长度,并将对应的路径记录。。这种求最短路径的方式与图最小生成树算法之Kruskal(克鲁斯卡尔)算法有异曲同工之妙。该算法的时间复杂度度是O(N^2),N是节点的个数。

       代码如下:

    
    
    int dist[MAXNUM];
    
    
    int prevT[MAXNUM];
    
    
    int final[MAXNUM];
    
    
    int MIN;

    int G[9][9]={0,1, 5, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT, MAXINT,//对应的权值矩阵
    
    
                 1, 0, 3, 7, 5, MAXINT ,MAXINT, MAXINT ,MAXINT,
    
    
                 5 ,3, 0, MAXINT ,1 ,7, MAXINT ,MAXINT ,MAXINT,
    
    
                MAXINT, 7, MAXINT ,0, 2, MAXINT, 3 ,MAXINT, MAXINT,
    
    
                MAXINT ,5, 1, 2, 0, 3 ,6, 9, MAXINT,
    
    
                MAXINT, MAXINT ,7, MAXINT, 3, 0, MAXINT, 5, MAXINT,
    
    
                MAXINT ,MAXINT ,MAXINT,  3, 6, MAXINT, 0 ,2 ,7,
    
    
                MAXINT, MAXINT ,MAXINT, MAXINT, 9 ,5 ,2, 0, 4,
    
    
                MAXINT, MAXINT ,MAXINT, MAXINT, MAXINT, MAXINT ,7, 4, 0};
    void Short_Dijkstra()
    {
        //初始化dist和prevT
        int min_num;
        for(int i=0;i<MAXNUM;i++)
        {
          final[i]=0;//标记是否是最短路径
          dist[i]=G[0][i];//对应权值
          prevT[i]=0;
        }
        final[0]=1;//对v0本身就是最短的
        dist[0]=G[0][0];
        for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离
        {
            MIN=MAXINT;//最小值
            min_num=0;
            for(int j=1;j<MAXNUM;j++)
            {
                if(!final[j] &&  dist[j]<MIN)
                {
                    min_num=j;
                    MIN=dist[j];//最小值
                }
            }
            final[min_num]=1;//找到最小值
           for(int k=0;k<MAXNUM;k++)
           {
              if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离
               {
                   prevT[k]=min_num;//记录经过的前驱点
                   dist[k]=G[min_num][k]+dist[min_num];//更新距离
              }
           }
        }
    }

    Flord算法

        Floyd算法是一个经典的动态规划算法,它适用于寻找各个顶点之间的最短距离。从任意节点i到任意节点j的最短路径不外乎2种可能,1是直接从点i到点j,这种方法最直接,但是距离比一定最短。2是从i经过若干个节点k到j。所以,我们假设Dis(i,j)为节点i到节点j的最短路径的距离,对于每一个节点k,我们检查Dis(i,k) + Dis(k,j) < Dis(i,j)是否成立,如果成立,证明从i到k再到j的路径比i直接到j的路径短,我们便设置Dis(i,j) = Dis(i,k) + Dis(k,j),同时记录我们走过的路径。这样一来,当我们遍历完所有节点k,Dis(i,j)中记录的便是i到j的最短路径的距离。算法时间复杂度:O(n3)。

      代码如下

       

    void Short_Dijkstra()
    {
        //初始化dist和prevTT
        int min_num;
        for(int i=0;i<MAXNUM;i++)
        {
          final[i]=0;
          dist[i]=G[0][i];
          prevT[i]=0;
        }
        final[0]=1;//对v0本身就是最短的
        dist[0]=G[0][0];
        for(int i=1;i<MAXNUM;i++)//每次遍历v0到某个顶点最短距离
        {
            MIN=MAXINT;//最小值
            min_num=0;
            for(int j=1;j<MAXNUM;j++)
            {
                if(!final[j] &&  dist[j]<MIN)
                {
                    min_num=j;
                    MIN=dist[j];//最小值
                }
            }
            final[min_num]=1;//找到最小值
           for(int k=0;k<MAXNUM;k++)
           {
              if(!final[k] && (G[min_num][k]+dist[min_num]<dist[k])) //在已有的点上找到距离V0更短的距离
               {
                   prevT[k]=min_num;//记录经过的前驱点
                   dist[k]=G[min_num][k]+dist[min_num];//更新距离
              }
           }
        }
    }

      图这两种算法最核心的思想就是:利用已有的最短的距离路径,通过这路径来不断扩充,最终实现从原点S到终点D的寻找过程。

       

  • 相关阅读:
    [AWS DA
    [CSS] Grid: X: justify-content, Y: align-items, X & Y: place-content
    [AWS] Lab: Network Load Balancer
    [Netlify serverless] Dependencies are not automatically install in functions
    python pandas
    pytorch suds numpy pandas
    unistd.h sleep() stdlib.h exit()
    万字报告详解:数字人民币产业图景
    33个Kubernetes安全工具
    人工智能时代都需要哪些数学知识?这些经典教材给你划重点
  • 原文地址:https://www.cnblogs.com/zhanjxcom/p/5665879.html
Copyright © 2011-2022 走看看