1. 程式人生 > 實用技巧 >python之(25)中級總結(3)關係型資料庫(mysql和oracle使用)

python之(25)中級總結(3)關係型資料庫(mysql和oracle使用)

技術標籤:ACM演算法資料結構動態規劃

一文詳解動態規劃

1 .動態規劃的基本思想

  • 求解具有某種最優性質的問題
  • 動態規劃演算法和分治法類似,將求解問題分解成若干個子問題,得到子問題的解,然後根據這些子問題的解得到原問題的解
  • 儲存已經解決的子問題的答案,當需要時間再找出子問題的答案,從而避免了大量的重複計算,節省了大量的時間,用一張表來記錄得到的所有子問題的答案,我們不管在以後的計算中當中是否會用到都把結果存放到表中

2 .動態規劃設計步驟

1.找出最優解的性質,刻畫其結構特徵
2.遞迴定義最優質並且寫出動態規劃方程
3.自底向上方式計算最優值
4.根據計算最優值的過程,構造最優解

3.矩陣連乘問題

m * n矩陣A與 n * p 矩陣B相乘需要耗費O(mnp)的時間,假設我們需要計算ABC三個矩陣的乘積,有兩種方式來計算,第一種A(BC),第二種(AB)C;儘管結果相同,但是從時間消耗的角度來考慮,兩者卻大不相同。 由於矩陣乘法滿足結合律,故計算矩陣的連乘積可以有多種不同的計算次序,可以用加括號的方式來確定。若一個矩陣連乘積的計算次序完全確定,則可以按照此次序反覆呼叫兩個矩陣乘法的標準演算法來計算出矩陣連乘積,完全加括號的矩陣連乘積可以遞迴地定義為:(1)單個矩陣是完全加括號的(2)矩陣連乘積A是完全加括號的,則A可以表示為兩個完全加括號的矩陣連乘積B和C的乘積加括號,即A=BC,例如,矩陣連乘積A1A2A3A4會有5種不同的完全加括號的方式,通過比較乘法運算計算工作量可以發現在計算矩陣連乘積時,加括號方式對計算量有很大影響。

(1)分解最優解的結構

我們利用所得到的最優子結構,就可以根據子問題的最優解來構造原問題的一個最優解,我們已經看到一個矩陣連乘積問題的非平凡例項的任何解法都需要分割乘積,而且任何最優解都包含子問題例項的最優解,所以,可以把問題分割為兩個子問題(最優完全加括號方式),尋找子問題例項的最優解,然後合併這些子問題的最優解,進而構造出一個矩陣連乘積問題例項的一個最優解,也就是必須保證在尋找一個正確的位置來分割乘積時,我們已經考慮過了所有的可能的位置,從而確保了已經檢查過的是最優的一個。

(2)建立遞迴關係

m[i][j]給出子問題的最優解,計算A[i.j]所需要的最少數乘積數,同時還確定了計算A[i,j]的最有次序中斷開位置k,在該處分裂乘積後可以得到最優完全加括號方式,定義陣列s[i][j]儲存k值,在計算出最優值m[i][j]之後,可以遞迴由s[i][j]構造出相應的最優解。

(3)計算矩陣連乘積動態規劃演算法

#define NUM 41
int p[NUM];
int m[NUM][NUM];
int s[NUM][NUM];
void Chain(int n)
{
  for(int i = 1;i <= n;i++)
      m[i][i] = 0;
  for(int r = 2;r <= n;r++)
      for(int i = 1;i <= n-r+1;i++)
      {
        int j = i+r-1;
        m[i][j]=m[i+1][j] + p[i-1] * p[i] *p[j];
        s[i][j] = i;
        for(int k = i+1;k < j;k++)
        {
          int t = m[i][k] + m[k+1][j] + p[i-1] * p[k] * p[j];
          if(t < m[i][j]){m[i][j] = t;s[i][j] = k;}
        }
      }
}

以上演算法主要計算量取決於程式中對r,i,k的三重迴圈,三重迴圈的總體計算次數為O(n3)算法佔用的空間為O(n2),由此可見,動態規劃演算法比窮舉搜尋法有效得多。