国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
五大常用算法

一、基本概念

    動態(tài)規(guī)劃是運(yùn)籌學(xué)中用于求解決策過程中的最優(yōu)化數(shù)學(xué)方法。當(dāng)然,我們在這里關(guān)注的是作為一種算法設(shè)計技術(shù),作為一種使用多階段決策過程最優(yōu)的通用方法。

    動態(tài)規(guī)劃過程是:每次決策依賴于當(dāng)前狀態(tài),又隨即引起狀態(tài)的轉(zhuǎn)移。一個決策序列就是在變化的狀態(tài)中產(chǎn)生出來的,所以,這種多階段最優(yōu)化決策解決問題的過程就稱為動態(tài)規(guī)劃。

    假設(shè)問題是由交疊的子問題所構(gòu)成,我們就能夠用動態(tài)規(guī)劃技術(shù)來解決它。一般來說,這種子問題出自對給定問題求解的遞推關(guān)系中,這個遞推關(guān)系包括了同樣問題的更小子問題的解。動態(tài)規(guī)劃法建議,與其對交疊子問題一次重新的求解,不如把每一個較小子問題僅僅求解一次并把結(jié)果記錄在表中(動態(tài)規(guī)劃也是空間換時間的)。這樣就能夠從表中得到原始問題的解。

    動態(tài)規(guī)劃經(jīng)常常使用于解決最優(yōu)化問題,這些問題多表現(xiàn)為多階段決策。

    關(guān)于多階段決策:在實(shí)際中,人們經(jīng)常遇到這樣一類決策問題,即因?yàn)檫^程的特殊性,能夠?qū)Q策的全過程根據(jù)時間或空間劃分若干個聯(lián)系的階段。而在各階段中。人們都須要作出方案的選擇。我們稱之為決策。而且當(dāng)一個階段的決策之后,經(jīng)常影響到下一個階段的決策,從而影響整個過程的活動。這樣,各個階段所確定的決策就構(gòu)成一個決策序列,常稱之為策略。因?yàn)楦鱾€階段可供選擇的決策往往不止一個。因而就可能有很多決策以供選擇,這些可供選擇的策略構(gòu)成一個集合,我們稱之為同意策略集合(簡稱策略集合)。每一個策略都對應(yīng)地確定一種活動的效果。我們假定這個效果能夠用數(shù)量來衡量。

    因?yàn)椴煌牟呗越?jīng)常導(dǎo)致不同的效果,因此,怎樣在同意策略集合中選擇一個策略,使其在預(yù)定的標(biāo)準(zhǔn)下達(dá)到最好的效果。經(jīng)常是人們所關(guān)心的問題。我們稱這種策略為最優(yōu)策略,這類問題就稱為多階段決策問題。

多階段決策問題舉例:機(jī)器負(fù)荷分配問題

    某種機(jī)器能夠在高低兩種不同的負(fù)荷下進(jìn)行生產(chǎn)。在高負(fù)荷下生產(chǎn)時。產(chǎn)品的年產(chǎn)量g和投入生產(chǎn)的機(jī)器數(shù)量x的關(guān)系為g=g(x),這時的年完善率為a,即假設(shè)年初完善機(jī)器數(shù)為x,到年終時完善的機(jī)器數(shù)為a*x(0<a<1);在低負(fù)荷下生產(chǎn)時,產(chǎn)品的年產(chǎn)量h和投入生產(chǎn)的機(jī)器數(shù)量y的關(guān)系為h=h(y)。對應(yīng)的完善率為b(0<b<0)。且a<b。

    假定開始生產(chǎn)時完善的機(jī)器熟練度為s1。

    要制定一個五年計劃,確定每年投入高、低兩種負(fù)荷生產(chǎn)的完善機(jī)器數(shù)量,使5年內(nèi)產(chǎn)品的總產(chǎn)量達(dá)到最大。

    這是一個多階段決策問題。

    顯然能夠?qū)⑷^程劃分為5個階段(一年一個階段),每一個階段開始時要確定投入高、低兩種負(fù)荷下生產(chǎn)的完善機(jī)器數(shù),并且上一個階段的決策必定影響到下一個階段的生產(chǎn)狀態(tài)。決策的目標(biāo)是使產(chǎn)品的總產(chǎn)量達(dá)到最大。這個問題常常使用數(shù)學(xué)方法建模,結(jié)合線性規(guī)劃等知識來進(jìn)行解決。

二、基本思想與策略

          基本思想與分治法類似,也是將待求解的問題分解為若干個子問題(階段),按順序求解子階段,前一子問題的解,為后一子問題的求解提供了實(shí)用的信息。

    在求解任一子問題時,列出各種可能的局部解,通過決策保留那些有可能達(dá)到最優(yōu)的局部解,丟棄其它局部解。依次解決各子問題,最后一個子問題就是初始問題的解。

    因?yàn)閯討B(tài)規(guī)劃解決的問題多數(shù)有重疊子問題這個特點(diǎn)。為降低反復(fù)計算。對每個子問題僅僅解一次,將其不同階段的不同狀態(tài)保存在一個二維數(shù)組中。

    與分治法最大的區(qū)別是:適合于用動態(tài)規(guī)劃法求解的問題,經(jīng)分解后得到的子問題往往不是互相獨(dú)立的(即下一個子階段的求解是建立在上一個子階段的解的基礎(chǔ)上,進(jìn)行進(jìn)一步的求解)。

三、適用的情況

能采用動態(tài)規(guī)劃求解的問題的一般要具有3個性質(zhì):

(1)最優(yōu)化原理:假設(shè)問題的最優(yōu)解所包括的子問題的解也是最優(yōu)的,就稱該問題具有最優(yōu)子結(jié)構(gòu),即滿足最優(yōu)化原理。

(2)無后效性:即某階段狀態(tài)一旦確定。就不受這個狀態(tài)以后決策的影響。也就是說,某狀態(tài)以后的過程不會影響曾經(jīng)的狀態(tài)。僅僅與當(dāng)前狀態(tài)有關(guān);

(3)有重疊子問題:即子問題之間是不獨(dú)立的,一個子問題在下一階段決策中可能被多次使用到(該性質(zhì)并非動態(tài)規(guī)劃適用的必要條件,可是假設(shè)沒有這條性質(zhì)。動態(tài)規(guī)劃算法同其它算法相比就不具備優(yōu)勢)。

四、求解的基本步驟

     動態(tài)規(guī)劃所處理的問題是一個多階段決策問題,一般由初始狀態(tài)開始,通過對中間階段決策的選擇,達(dá)到結(jié)束狀態(tài)。這些決策形成了一個決策序列,同時確定了完成整個過程的一條活動路線(通常是求最優(yōu)的活動路線)。如圖所示。動態(tài)規(guī)劃的設(shè)計都有著一定的模式,一般要經(jīng)歷以下幾個步驟。

    初始狀態(tài)→│決策1│→│決策2│→…→│決策n│→結(jié)束狀態(tài)

                      圖1 動態(tài)規(guī)劃決策過程示意圖

    (1)劃分階段:按照問題的時間或空間特征,把問題分為若干個階段。在劃分階段時,注意劃分后的階段一定要是有序的或者是可排序的,否則問題就無法求解。

    (2)確定狀態(tài)和狀態(tài)變量:將問題發(fā)展到各個階段時所處于的各種客觀情況用不同的狀態(tài)表示出來。當(dāng)然,狀態(tài)的選擇要滿足無后效性。

    (3)確定決策并寫出狀態(tài)轉(zhuǎn)移方程:因?yàn)闆Q策和狀態(tài)轉(zhuǎn)移有著天然的聯(lián)系,狀態(tài)轉(zhuǎn)移就是根據(jù)上一階段的狀態(tài)和決策來導(dǎo)出本階段的狀態(tài)。所以如果確定了決策,狀態(tài)轉(zhuǎn)移方程也就可寫出。但事實(shí)上常常是反過來做,根據(jù)相鄰兩個階段的狀態(tài)之間的關(guān)系來確定決策方法和狀態(tài)轉(zhuǎn)移方程

    (4)尋找邊界條件:給出的狀態(tài)轉(zhuǎn)移方程是一個遞推式,需要一個遞推的終止條件或邊界條件。

    一般,只要解決問題的階段、狀態(tài)狀態(tài)轉(zhuǎn)移決策確定了,就可以寫出狀態(tài)轉(zhuǎn)移方程(包括邊界條件)。

實(shí)際應(yīng)用中可以按以下幾個簡化的步驟進(jìn)行設(shè)計:

    (1)分析最優(yōu)解的性質(zhì),并刻畫其結(jié)構(gòu)特征。

    (2)遞歸的定義最優(yōu)解。

    (3)以自底向上或自頂向下的記憶化方式(備忘錄法)計算出最優(yōu)值。

    (4)根據(jù)計算優(yōu)值時得到的信息,構(gòu)造問題的最優(yōu)解。

五、常見動態(tài)規(guī)劃問題

 1、找零錢問題

     有數(shù)組penny,penny中所有的值都為正數(shù)且不重復(fù)。每個值代表一種面值的貨幣,每種面值的貨幣可以使用任意張,再給定一個整數(shù)aim(小于等于1000)代表要找的錢數(shù),求換錢有多少種方法。
給定數(shù)組penny及它的大小(小于等于50),同時給定一個整數(shù)aim,請返回有多少種方法可以湊成aim。
測試樣例:
[1,2,4],3,3
返回:2

解析:設(shè)dp[n][m]為使用前n中貨幣湊成的m的種數(shù),那么就會有兩種情況:

             使用第n種貨幣:dp[n-1][m]+dp[n-1][m-peney[n]]

              不用第n種貨幣:dp[n-1][m],為什么不使用第n種貨幣呢,因?yàn)閜enney[n]>m。

        這樣就可以求出當(dāng)m>=penney[n]時 dp[n][m] = dp[n-1][m]+dp[n][m-peney[n]],否則,dp[n][m] = dp[n-1][m]

代碼如下:

[java] view plain copy
  1. import java.util.*;  
  2. public class Exchange {  
  3.     public int countWays(int[] penny, int n, int aim) {  
  4.         // write code here  
  5.         if(n==0||penny==null||aim<0){  
  6.          return 0;     
  7.         }  
  8.         int[][] pd = new int[n][aim+1];  
  9.         for(int i=0;i<n;i++){  
  10.          pd[i][0] = 1;     
  11.         }  
  12.         for(int i=1;penny[0]*i<=aim;i++){  
  13.          pd[0][penny[0]*i] = 1;     
  14.         }  
  15.         for(int i=1;i<n;i++){  
  16.             for(int j=0;j<=aim;j++){  
  17.                 if(j>=penny[i]){  
  18.                     pd[i][j] = pd[i-1][j]+pd[i][j-penny[i]];  
  19.                 }else{  
  20.                     pd[i][j] = pd[i-1][j];  
  21.                 }  
  22.             }  
  23.         }  
  24.         return pd[n-1][aim];  
  25.     }   

2、走方格問題

      有一個矩陣map,它每個格子有一個權(quán)值。從左上角的格子開始每次只能向右或者向下走,最后到達(dá)右下角的位置,路徑上所有的數(shù)字累加起來就是路徑和,返回所有的路徑中最小的路徑和。
給定一個矩陣map及它的行數(shù)n和列數(shù)m,請返回最小路徑和。保證行列數(shù)均小于等于100.
測試樣例:
[[1,2,3],[1,1,1]],2,3
返回:4

解析:設(shè)dp[n][m]為走到n*m位置的路徑長度,那么顯而易見dp[n][m] = min(dp[n-1][m],dp[n][m-1]);

 代碼如下:

[java] view plain copy
  1. import java.util.*;    
  2. public class MinimumPath {  
  3.     public int getMin(int[][] map, int n, int m) {  
  4.         // write code here  
  5.        int[][] dp = new int[n][m];  
  6.         for(int i=0;i<n;i++){  
  7.             for(int j=0;j<=i;j++){  
  8.              dp[i][0]+=map[j][0];      
  9.             }  
  10.         }  
  11.         for(int i=0;i<m;i++){  
  12.             for(int j=0;j<=i;j++){  
  13.              dp[0][i]+=map[0][j];      
  14.             }  
  15.         }  
  16.         for(int i=1;i<n;i++){  
  17.             for(int j=1;j<m;j++){  
  18.              dp[i][j] = min(dp[i][j-1]+map[i][j],dp[i-1][j]+map[i][j]);     
  19.             }  
  20.         }  
  21.         return dp[n-1][m-1];  
  22.     }  
  23.     public int min(int a,int b){  
  24.         if(a>b){  
  25.          return b;     
  26.         }else{  
  27.          return a;     
  28.         }  
  29.     }  

3、走臺階問題

    有n級臺階,一個人每次上一級或者兩級,問有多少種走完n級臺階的方法。為了防止溢出,請將結(jié)果Mod 1000000007
給定一個正整數(shù)int n,請返回一個數(shù),代表上樓的方式數(shù)。保證n小于等于100000。
測試樣例:
1
返回:1

解析:這是一個非常經(jīng)典的為題,設(shè)f(n)為上n級臺階的方法,要上到n級臺階的最后一步有兩種方式:從n-1級臺階走一步;從n-1級臺階走兩步,于是就有了這個公式f(n) = f(n-1)+f(n-2);

代碼如下:

[java] view plain copy
  1. import java.util.*;  
  2. public class GoUpstairs {  
  3.     public int countWays(int n) {  
  4.         // write code here  
  5.         if(n<=2)  
  6.             return n;  
  7.         int f = 1%1000000007;  
  8.         int s = 2%1000000007;  
  9.         int t = 0;  
  10.         for(int i=3;i<=n;i++){  
  11.          t = (f+s)%1000000007;  
  12.          f = s;  
  13.          s = t;  
  14.         }  
  15.        return t;   
  16.     }  
  17. }

4、最長公共序列數(shù)

     給定兩個字符串A和B,返回兩個字符串的最長公共子序列的長度。例如,A="1A2C3D4B56”,B="B1D23CA45B6A”,”123456"或者"12C4B6"都是最長公共子序列。
給定兩個字符串A和B,同時給定兩個串的長度n和m,請返回最長公共子序列的長度。保證兩串長度均小于等于300。
測試樣例:
"1A2C3D4B56",10,"B1D23CA45B6A",12
返回:6

解析:設(shè)dp[n][m] ,為A的前n個字符與B的前m個字符的公共序列長度,則當(dāng)A[n]==B[m]的時候,dp[i][j] = max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]),否則,dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);

代碼如下:

[java] view plain copy
  1. import java.util.*;  
  2. public class LCS {  
  3.     public int findLCS(String A, int n, String B, int m) {  
  4.         // write code here  
  5.         int[][] dp = new int[n][m];  
  6.         char[] a = A.toCharArray();  
  7.         char[] b = B.toCharArray();  
  8.        for(int i=0;i<n;i++){  
  9.            if(a[i]==b[0]){  
  10.                dp[i][0] = 1;  
  11.                for(int j=i+1;j<n;j++){  
  12.                    dp[j][0] = 1;  
  13.                }  
  14.                break;  
  15.            }       
  16.        }  
  17.          for(int i=0;i<m;i++){  
  18.            if(a[0]==b[i]){  
  19.                dp[0][i] = 1;  
  20.                for(int j=i+1;j<m;j++){  
  21.                    dp[0][j] = 1;  
  22.                }  
  23.                break;  
  24.            }       
  25.        }  
  26.        for(int i=1;i<n;i++){  
  27.            for(int j=1;j<m;j++){  
  28.                if(a[i]==b[j]){  
  29.                   dp[i][j] = max(dp[i-1][j-1]+1,dp[i-1][j],dp[i][j-1]);  
  30.                }else{  
  31.                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);  
  32.                }               
  33.            }  
  34.        }       
  35.         return dp[n-1][m-1];  
  36.     }  
  37.     public int max(int a,int b,int c){  
  38.         int max = a;  
  39.         if(b>max)  
  40.             max=b;  
  41.         if(c>max)  
  42.             max = c;  
  43.         return max;  
  44.     }  


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
動態(tài)規(guī)劃之狀態(tài)轉(zhuǎn)移方程-NOIP提高組歷年高頻考點(diǎn)(4)
Python|動態(tài)規(guī)劃經(jīng)典案例
動態(tài)規(guī)劃詳解 第一章
常用算法二(動態(tài)規(guī)劃)
Dynamic Programming
談?wù)剟討B(tài)規(guī)劃的思想
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服