采用動(dòng)態(tài)規(guī)劃發(fā)求解的問題必須具有兩個(gè)性質(zhì):最優(yōu)子結(jié)構(gòu)和子問題重疊。
動(dòng)態(tài)規(guī)劃算法的基本要素
(1)最優(yōu)子結(jié)構(gòu):當(dāng)問題的最優(yōu)解包含了其子問題的最優(yōu)解時(shí),稱該問題具有最優(yōu)子結(jié)構(gòu)性質(zhì)。
(2)重疊子問題:在用遞歸算法自頂向下解問題時(shí),每次產(chǎn)生的子問題并不總是新問題,有些子問題被反復(fù)計(jì)算多次。這種性質(zhì)稱為子問題的重疊性質(zhì)
與分治法相同,動(dòng)態(tài)規(guī)劃法具有最優(yōu)子結(jié)構(gòu)性質(zhì)。動(dòng)態(tài)規(guī)劃法的解決辦法,也是將一個(gè)大問題分解為若干個(gè)規(guī)模較小的子問題,通過合并求解的子問題而得到原問題的解。
與分治法不同,動(dòng)態(tài)規(guī)劃法的子問題重疊,指分解出的子問題不是相互獨(dú)立的,有重疊部分。如果采用分治法求解,重疊的子問題將被重復(fù)計(jì)算多次。
動(dòng)態(tài)規(guī)劃法采用備忘錄做法解決子問題重疊。對每個(gè)子問題只求解一次,保存每個(gè)子問題的計(jì)算結(jié)果,就像一個(gè)備忘錄,當(dāng)需要再次求解某個(gè)子問題是,只要查找備忘錄中的結(jié)果即可,要求備忘錄的查找時(shí)間為常數(shù)。
動(dòng)態(tài)規(guī)劃求解步驟:
(1)找出最優(yōu)解的性質(zhì),并刻畫其結(jié)構(gòu)特征。
(2)遞歸地定義最優(yōu)值(寫出狀態(tài)轉(zhuǎn)移方程,或稱動(dòng)態(tài)規(guī)劃方程)。
(3)以自底向上(或自頂向下)的方式計(jì)算出最優(yōu)值。
(4)根據(jù)計(jì)算最優(yōu)值時(shí)得到的信息,構(gòu)造一個(gè)最優(yōu)解。
f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+P(n,m)}
動(dòng)態(tài)規(guī)劃算法基本框架代碼
for(j=1; j<=m; j=j+1) // 第一個(gè)階段
xn[j] = 初始值;
for(i=n-1; i>=1; i=i-1)// 其他n-1個(gè)階段
for(j=1; j>=f(i); j=j+1)//f(i)與i有關(guān)的表達(dá)式
xi[j]=j=max(或min){g(xi-1[j1:j2]), ......, g(xi-1[jk:jk+1])};
t = g(x1[j1:j2]); // 由子問題的最優(yōu)解求解整個(gè)問題的最優(yōu)解的方案
print(x1[j1]);
for(i=2; i<=n-1; i=i+1)
{
t = t-xi-1[ji];
for(j=1; j>=f(i); j=j+1)
if(t=xi[ji])
break;
}