任意兩點最短路徑問題


問題描述

       輸入:圖G = (V,E)

       輸出:圖中任意兩點的最短路徑

算法描述(Floyd算法)

     1. 分析優化子結構

       定理1,Vi,Vj的最短路徑包含兩點Vm,Vn,那么Vi,Vj的最短路徑中對應Vm,Vn的部分一定是Vm,Vn在該圖中的一條最短路徑。

       證明1,可以通過反證法進行證明,如果不是,那么可以構造出比當前Vi,Vj的最短路徑更短的路徑。

     2. 分析子問題重疊性。

       首先,需要了解Vi,Vj的遞歸代價方程。

       定義:D(i,j)為Vi,Vj的最短路徑長度。

  • D(i,j) = 0,if i = j.
  • D(i,j) = min ( D(i,j) , D(i,k) + D(k,j)),其中,i ≤ k ≤ j,if i ≠ j.

       那么此問題的計算形式基本上於矩陣鏈乘問題的計算形式,這就是一個划分動態規划,那么同理自然就有子問題重疊性。

     3.遞歸地定義最優解的代價 

  • D(i,j) = 0,if i = j.
  • D(i,j) = min ( D(i,j) , D(i,k) + D(k,j)),其中,i ≤ k ≤ j,if i ≠ j.

     4.自底向上地計算優化解的代價保存之,並獲取構造最優解的信息

       對於該算法而言,計算順序是值得思考的。如果直接進行遍歷計算,可能當計算D(i,j)時,所使用的D(i,k)以及D(k,j)都並非是最小代價,可以說,每個D(i,j)都相互影響。

       解決辦法為:構建頂點集合S以及表示任意兩點之間最小路徑代價的二維矩陣M,

  • 初始時,S為空,M中僅僅將邊錄入,無邊記為無窮。
  • 依次向S中加入頂點,並僅僅將該頂點作為遞歸方程中的頂點Vk,更新M。
  • 當S = V時,M中記為最短路徑代價。

      故而可以設計算法為:

Floyd算法
D <-- W
P <-- 0
For k = 1 to n Do /*k控制填入元素*/
     For i = 1 to n Do /*i,j控制矩陣的遍歷*/
        for j = 1 to n
           if (D[ i, j ] > D[ i, k ] + D[ k, j ] )
           then D[ i, j ] = D[ i, k ] + D[ k, j ]
                   P[ i, j ] = k; 

     5.根據構造最優解的信息構造優化解

        注意,下列算法只打印中間節點,而不會答應起止節點,所以,P中無邊或者直接有邊的值均為0.

path(index q, r)
     if (P[ q, r ]!=0)
         path(q, P[q, r])
         println( “v”+ P[q, r])
         path(P[q, r], r)
         return;
     //no intermediate nodes
     else return 

  6.算法復雜性分析:

       時間復雜性:

           計算代價的時間復雜性:O(n^3)。

           構造最優解時間復雜性:O(n)。最多只會遍歷n個頂點

           空間復雜性:O(n^2)。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM