Java實現幾種最短路徑問題

前言

最短路徑問題在現實處處可見,而且針對不同的情形都需要具體分析纔會找到最好解法。

最短路徑Floyd算法

一支部隊急行軍,要經過A,B,C,D據點,這四個據點之間有些之間有路到達,有些沒有。爲了最大的節約時間,部隊指揮部需要知道任意兩個據點之間的最短時間。以下是兩兩之間所花的時間(如下圖所示):
圖一
那麼如何才能讓兩個據點之間花的時間變短?加入第三個據點即可。因此判斷條件就出來了:
兩個據點之間花費的時間如果比加入第三個據點的時間長,那麼兩個據點之間的最短時間即是加入第三個據點的時間之和。
這樣Floyd算法的Java實現如下(核心代碼就是上面的判斷,邊的權值全部提前賦值):

public class Floyd {

      /**
     * @param graph 圖的鄰接矩陣
     * @param n 代表頂點的個數
     * @return
     */
    public int[][] floyd(int[][] graph,int n){
          int[][] edge = new int[n][n];
          for(int i=0;i<n;i++){
              for(int j=0;j<n;j++){
                  edge[i][j]=graph[i][j];
              }
          }
          for(int k=0;k<n;k++){
              for(int i=0;i<n;i++){
                  for(int j=0;j<n;j++){
                      if(edge[i][j]>edge[i][k]+edge[k][j])
                          edge[i][j]=edge[i][k]+edge[k][j];
                  }
              }
          }
          return edge;
      }
}

Floyd算法容易理解,並且可以算出任意兩個點之間的最短距離。不難得出,Floyd算法的時間複雜度爲O(n3),空間複雜度爲O(n2),n爲頂點的個數。

單源最短路徑Dijkstra

還有一種常見的問題,也就是單源最短路徑。求出1號頂點到其它頂點的最短距離:
這裏寫圖片描述

類似Floyd算法,我們在覈心代碼裏面直接就給出圖的鄰接矩陣,避免不必要的代碼。
public class Dijiskra {

      public int[] dijsktra(int[][] edge){
      //得到頂點個數
          int vartex = edge.length;
         //標記
          int flag = 0;
        //記錄某個頂點有沒有訪問到
          int[] mark = new int[vartex];
    //這裏求的是從第一個頂點到其它頂點的最短距離
          mark[0]=1;
          int[] distance = new int[vartex];
    //最開始默認的都是邊的值,這裏傳進來就得事先做好處理,比如兩個頂點之間不可達,那麼久應該賦值爲一個很大的數
          for(int i=0;i<vartex;i++){
              distance[i]=edge[0][i];
          }
    //核心代碼
          for(int i=1;i<vartex;i++){
              int min = Integer.MAX_VALUE;
              for(int j=0;j<vartex;j++){
                    if(mark[j]==0&&distance[j]<min){
                        min=distance[j];
                        flag=j;
                    }
               }
              mark[flag]=1;
              for(int k=0;k<vartex;k++){
                  if(distance[k]>distance[flag]+edge[flag][k]){
                      distance[k]=distance[flag]+edge[flag][k];
                  }
              }

          }
          return distance;
      }
}

該算法同樣和頂點關係密切,其時間複雜度爲O(n2),空間複雜度也只需要存儲圖的鄰接矩陣或者鄰接鏈表即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章