圖-最短路徑

    最短路徑:對於網圖來講,最短路徑是指兩個頂點之間通過的邊上權值之和最少的路徑,而且咱們稱路徑上的第一個頂點式源點,最後一個頂點是終點。如下圖爲例,html

     尋找v0到v8的最短距離。算法

 

   對應解決思路:如今比較成熟的有Dijkstra(迪傑斯特拉)算法Flord算法算法。
post

  Dijkstra(迪傑斯特拉)算法url

     Dijkstra求源節點S到終結點D的最短距離的過程當中,循環過程當中每次肯定一個源節點到其它節點T的最短距離。該距離肯定後,遍歷判斷該節點T到其它節點的距離是否比如今S到其它節點距離短,更短的話則修改成相應長度,並將對應的路徑記錄。。這種求最短路徑的方式與圖最小生成樹算法之Kruskal(克魯斯卡爾)算法有殊途同歸之妙。該算法的時間複雜度度是O(N^2),N是節點的個數。spa

   代碼以下:.net

 
 
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算法code

    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)。htm

  代碼以下blog

   

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的尋找過程。v8

相關文章
相關標籤/搜索