码迷,mamicode.com
首页 > 其他好文 > 详细

图-最短路径

时间:2016-07-13 10:26:21      阅读:179      评论:0      收藏:0      [点我收藏+]

标签:

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

    技术分享 寻找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的寻找过程。

   

图-最短路径

标签:

原文地址:http://www.cnblogs.com/zhanjxcom/p/5665879.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!