算法——動態規劃

迎來了新的課題,動態規劃,聽這個名字就很高大上,因爲會動啊。

 

概念&基本思想

多階段決策過程的最優化問題。是一種途徑,而不是一種特殊算法,沒有準確的數學表達式,所以叫動態的嘛。

多階段決策問題

如果一類活動可以分解爲若干相互聯繫的階段,在每個階段都做出決策,一個階段的決策做出以後影響下一個階段的決策,從而完全確定了一條決策路線,這成爲多階段決策問題。

各個階段的決策構成一個序列,構成一個策略。每個階段的決策不同就構成了不同的策略,多階段決策問題就是要確定一個最優策略。

術語

階段:把所給求解問題的過程恰當地分成若干個相互聯繫的階段,以便於求解,過程不同,階段數就可能不同.描述階段的變量稱爲階段變量。在多數情況下,階段變量是離散的,用k表示。此外,也有階段變量是連續的情形。如果過程可以在任何時刻作出決策,且在任意兩個不同的時刻之間允許有無窮多個決策時,階段變量就是連續的。

狀態:狀態表示每個階段開始面臨的自然狀況或客觀條件。過程的狀態通常可以用一個或一組數來描述,稱爲狀態變量。一般,狀態是離散的,但有時爲了方便也將狀態取成連續的。

無後效性:如果給定某一階段的狀態,則在這一階段以後過程的發展不受這階段以前各段狀態的影響,所有各階段都確定時,整個過程也就確定了。

決策:一個階段的狀態給定以後,從該狀態演變到下一階段某個狀態的一種選擇(行動)稱爲決策。描述決策的變量稱決策變量,因狀態滿足無後效性,故在每個階段選擇決策時只需考慮當前的狀態而無須考慮過程的歷史。決策變量的範圍稱爲允許決策集合。

策略:由每個階段的決策組成的序列稱爲策略。對於每一個實際的多階段決策過程,可供選取的策略有一定的範圍限制,這個範圍稱爲允許策略集合。允許策略集合中達到最優效果的策略稱爲最優策略

基本思想

動態規劃算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每一個解都對應於一個值,我們希望找到具有最優值的解。動態規劃算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。與分治法不同的是,適合於用動態規劃求解的問題,經分解得到子問題往往不是互相獨立的。若用分治法來解這類問題,則分解得到的子問題數目太多,有些子問題被重複計算了很多次。如果我們能夠保存已解決的子問題的答案,而在需要時再找出已求得的答案,這樣就可以避免大量的重複計算,節省時間。我們可以用一個表來記錄所有已解的子問題的答案。不管該子問題以後是否被用到,只要它被計算過,就將其結果填入表中。這就是動態規劃法的基本思路。

(百度百科)

把求解的問題分成許多階段或多個子問題,然後按順序求解各個子問題。前一個子問題的解爲後一個子問題的求解提供了有用的信息。在求解任何一子問題時,列出各種可能的局部解,通過決策保留那些有可能達到最優的局部解,丟棄其他局部解,依次解決各子問題,最後一個子問題就是問題的解。

基本要素 || 適用條件

  • 最優子結構:原問題最優解包含子問題的最優解。或者說,一個最優化策略的子策略總是最優的。
  • 子問題重疊:每次產生的子問題並不總是新的,有些子問題被重複計算。動態規劃將原來具有指數級時間複雜度的搜索算法改進成了具有多項式時間複雜度的算法。其中的關鍵在於解決冗餘,這是動態規劃算法的根本目的。動態規劃實質上是一種以空間換時間的技術。
  • 無後效性

基本模型 || 基本步驟

  1. 確定問題的決策對象
  2. 對決策過程進行階段劃分
  3. 確定各個階段的狀態變量
  4. 根據狀態變量確定目標函數和費用函數
  5. 建立各個階段狀態變量的轉移過程,確定狀態轉移方程。

(百度百科)

  • 找出最優解性質
  • 遞歸地定義最優值
  • 自底向上的方式計算最優值(自底向上可以將重複的計算保存起來)
  • 根據計算最優值得到的信息,構造最優解。

例子

矩陣連乘

問題描述:給定n個矩陣{A1,A2,…,An},其中,Ai與Ai+1是可乘的,(i=1,2 ,…,n-1)。用加括號的方法表示矩陣連乘的次序,不同的計算次序計算量(乘法次數)是不同的,找出一種加括號的方法,使得矩陣連乘的次數最小。輸入數據爲矩陣個數和每個矩陣規模,輸出結果爲計算矩陣連乘積的計算次序和最少乘法次數。

參考:https://blog.csdn.net/liufeng_king/article/details/8497607https://blog.csdn.net/x_xhuashui/article/details/81903558

問題解析:

這道題需要找到一個矩陣相乘的順序,使得乘法運算的次數最小。每次兩個相乘的矩陣構成一個階段,每一次決定哪兩個矩陣相乘,即爲一個決策,每次相乘之後的現狀即爲狀態。

 設計算A[i:j],1≤i≤j≤n,所需要的最少數乘次數m[i,j],則原問題的最優值爲m[1,n]。

      當i=j時,A[i:j]=Ai,因此,m[i][i]=0,i=1,2,…,n
      當i<j時,若A[i:j]的最優次序在Ak和Ak+1之間斷開,i<=k<j,則:m[i][j]=m[i][k]+m[k+1][j]+pi-1pkpj。由於在計算是並不知道斷開點k的位置,所以k還未定。不過k的位置只有j-i個可能。因此,k是這j-i個位置使計算量達到最小的那個位置。

遞推關係:

m[i:j] = \left\{\begin{matrix} 0 & i=j\\ min_{i\leqslant k\leqslant j}({m[i,k]+m[k+1,j]+p_{i-1}p_{k}p_{j}}) & i<j \end{matrix}\right.

感覺有點兒難。。稍後再看看

 

 

公共最長子序列(LCS)

問題描述:

給定兩個字符串,求解這兩個字符串的最長公共子序列(Longest Common Sequence)。注,子序列不一定連續。比如字符串1:BDCABA;字符串2:ABCBDAB,則這兩個字符串的最長公共子序列長度爲4,最長公共子序列是:BCBA

參考:https://www.cnblogs.com/hapjin/p/5572483.html

分析:動態規劃問題的基本要素:重疊子問題、最優子結構

遞推關係:

C[i,j]=\left\{\begin{matrix} 0 & i=0 or j=0\\ C[i-1,j-1]+1 & i,j>0,x_{i}==y_{j}\\ max[C[i,j-1],C[i-1,j]] & i,j>0,x_{i}!=y_{j} \end{matrix}\right.

c[i,j]表示:(x1,x2....xi) 和 (y1,y2...yj) 的最長公共子序列的長度

代碼實現:

     public static int LCS(String str1, String str2){
         int[][] c = new int[str1.length() + 1][str2.length() + 1]; //這個表用來存儲計算的值
         for(int row = 0; row <= str1.length(); row++)
             c[row][0] = 0;
         for(int column = 0; column <= str2.length(); column++)
             c[0][column] = 0;
         
         for(int i = 1; i <= str1.length(); i++)
             for(int j = 1; j <= str2.length(); j++)
             {
                 if(str1.charAt(i-1) == str2.charAt(j-1))
                     c[i][j] = c[i-1][j-1] + 1;
                 else if(c[i][j-1] > c[i-1][j])
                     c[i][j] = c[i][j-1];
                 else
                     c[i][j] = c[i-1][j];
             }
         return c[str1.length()][str2.length()];
     }

很明顯,使用空間換時間。雖然遞推關係式是從後往前,但是計算還是從前往後計算。

0-1揹包問題

問題描述:

0-1 揹包問題:給定 n 種物品和一個容量爲 C 的揹包,物品 i 的重量是 wi,其價值爲 vi 。

問:應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?

參考:https://blog.csdn.net/mu399/article/details/7722810

分析:重疊子問題、最優子結構

遞推關係式:Vi表示第 i 個物品的價值,Wi表示第 i 個物品的體積,定義V(i,j):當前揹包容量 j,前 i 個物品最佳組合對應的價值

V(i,j)=\left\{\begin{matrix} V(i-1,j) & j<w_{i}\\ max[V(i-1,j),V(i-1,j-w_{i})+v_{i}] & j\geqslant w_{i} \end{matrix}\right.

代碼實現:

待完善

 

 

 

 

 

 

 

 

 

 

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