矩阵连乘 动态规划 详解
矩陣連乘問(wèn)題----動(dòng)態(tài)規(guī)劃(轉(zhuǎn)載):
給定n個(gè)矩陣{A1,A2,…,An},其中Ai與Ai+1是可乘的,i=1,2…,n-1。如何確定計(jì)算矩陣連乘積的計(jì)算次序,使得依此次序計(jì)算矩陣連乘積需要的數(shù)乘次數(shù)最少。
解答:我們按照動(dòng)態(tài)規(guī)劃的幾個(gè)步驟來(lái)分析:
(1)找出最優(yōu)解的性質(zhì),刻畫其特征結(jié)構(gòu)
對(duì)于矩陣連乘問(wèn)題,最優(yōu)解就是找到一種計(jì)算順序,使得計(jì)算次數(shù)最少。
令m[i][j]表示第i個(gè)矩陣至第j個(gè)矩陣這段的最優(yōu)解。
將矩陣連乘積?簡(jiǎn)記為A[i:j]?,這里i<=j.假設(shè)這個(gè)最優(yōu)解在第k處斷開(kāi),i<=k<j,則A[i:j]是最優(yōu)的,那么A[i,k]和A[k+1:j]也是相應(yīng)矩陣連乘的最優(yōu)解。可以用反證法證明之。?這就是最優(yōu)子結(jié)構(gòu),也是用動(dòng)態(tài)規(guī)劃法解題的重要特征之一。
(2)建立遞歸關(guān)系
設(shè)計(jì)算A[i:j],1≤i≤j≤n,所需要的最少數(shù)乘次數(shù)m[i,j],則原問(wèn)題的最優(yōu)值為m[1,n]?。
當(dāng)i=j時(shí),A[i,j]=Ai, m[i,j]=0;(表示只有一個(gè)矩陣,如A1,沒(méi)有和其他矩陣相乘,故乘的次數(shù)為0)
當(dāng)i<j時(shí),m[i,j]=min{m[i,k]+m[k+1,j] +pi-1*pk*pj} ,其中 i<=k<j
(相當(dāng)于對(duì)i~j這段,把它分成2段,看哪種分法乘的次數(shù)最少,如A1,A2,A3,A4,則有3種分法:{A1}{A2A3A4 }、{A1A2}{A3A4 }、{A1A2A3}{A4 },其中{}表示其內(nèi)部是最優(yōu)解,如{A1A2A3}表示是A1A2A3的最優(yōu)解),
也即:
(3)計(jì)算最優(yōu)值
對(duì)于1≤i≤j≤n不同的有序?qū)?i,j) 對(duì)于不同的子問(wèn)題,因此不同子問(wèn)題的個(gè)數(shù)最多只有o(n*n).但是若采用遞歸求解的話,許多子問(wèn)題將被重復(fù)求解,所以子問(wèn)題被重復(fù)求解,這也是適合用動(dòng)態(tài)規(guī)劃法解題的主要特征之一。?
用動(dòng)態(tài)規(guī)劃算法解此問(wèn)題,可依據(jù)其遞歸式以自底向上的方式進(jìn)行計(jì)算。在計(jì)算過(guò)程中,保存已解決的子問(wèn)題答案。每個(gè)子問(wèn)題只計(jì)算一次,而在后面需要時(shí)只要簡(jiǎn)單查一下,從而避免大量的重復(fù)計(jì)算,最終得到多項(xiàng)式時(shí)間的算法。
下面給出動(dòng)態(tài)規(guī)劃求解最優(yōu)值的代碼:
//也是要枚舉求到的,但是如果我們之前先記錄下這些小規(guī)模的情況,當(dāng)求大規(guī)模的時(shí)候,直接提取就行了,因此體現(xiàn)了記憶搜索的說(shuō)法
void MatrixChain(int *p,int n,int **m,int **s)
{??? //m是最優(yōu)值,s是最優(yōu)值的斷開(kāi)點(diǎn)的索引,n為題目所給的矩陣的個(gè)數(shù)(下面例子中)
//矩陣段長(zhǎng)度為1,則m[][]中對(duì)角線的值為0,表示只有一個(gè)矩陣,沒(méi)有相乘的.
for(int i = 1;i<=n;i++) m[i][i] = 0;
for(int r = 2;r<=n;r++){//r表示矩陣的長(zhǎng)度(2,3…逐漸變長(zhǎng))
?? for(int i = 1;i<=n-r+1;i++){???
//從第i個(gè)矩陣Ai開(kāi)始,長(zhǎng)度為r,則矩陣段為(Ai~Aj)
int j = i+r-1;//當(dāng)前矩陣段(Ai~Aj)的起始為Ai,尾為Aj
//求(Ai~Aj)中最小的,其實(shí)k應(yīng)該從i開(kāi)始,但些處先記錄第一個(gè)值,k從i+1開(kāi)始,這樣也可以。
//例如對(duì)(A2~A4),則i=2,j=4,下面一行的m[2][4]=m[3][4]+p[1]*p[2]*p[4],即A2(A3A4)
??? ?m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];
??? ?s[i][j] = i;//記錄斷開(kāi)點(diǎn)的索引
//循環(huán)求出(Ai~Aj)中的最小數(shù)乘次數(shù)
??? ?for(int k = i+1 ; k<j;k++){
//將矩陣段(Ai~Aj)分成左右2部分(左m[i][k],右m[k+1][j]), //再加上左右2部分最后相乘的次數(shù)(p[i-1] *p[k]*p[j])
???? ??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;? //保存最小的,即最優(yōu)的結(jié)果
}//if
??? ?}//k
?? ?}//i
}//r
}//MatrixChain
上面代碼中后面的k也相當(dāng)于是從i到j(luò)-1遞增的,只是單獨(dú)把第一個(gè)(k=i)提了出來(lái).
對(duì)于?p={30?35 ?15?5? 10? 20????? 25}:
?
計(jì)算順序?yàn)?#xff1a;
對(duì)上例,共6個(gè)矩陣(A1~A6),n=6,當(dāng)r=3時(shí),r循環(huán)里面的是3個(gè)矩陣的最優(yōu)解,i從1->4,即求的是
(A1A2A3),(A2A3A4),(A3A4A5),(A4A5A6)這4個(gè)矩陣段(長(zhǎng)度為3)的最優(yōu)解.當(dāng)i=2時(shí)(A2A3A4)的最優(yōu)解為{A2(A3A4) ,(A2A3)A4}的較小值。
?
?矩陣連乘計(jì)算次序問(wèn)題的最優(yōu)解包含著其子問(wèn)題的最優(yōu)解。這種性質(zhì)稱為最優(yōu)子結(jié)構(gòu)性質(zhì)。?
?在分析問(wèn)題的最優(yōu)子結(jié)構(gòu)性質(zhì)時(shí),所用的方法具有普遍性:首先假設(shè)由問(wèn)題的最優(yōu)解導(dǎo)出的子問(wèn)題的解不是最優(yōu)的,然后再設(shè)法說(shuō)明在這個(gè)假設(shè)下可構(gòu)造出比原問(wèn)題最優(yōu)解更好的解,從而導(dǎo)致矛盾。?
?利用問(wèn)題的最優(yōu)子結(jié)構(gòu)性質(zhì),以自底向上的方式遞歸地從子問(wèn)題的最優(yōu)解逐步構(gòu)造出整個(gè)問(wèn)題的最優(yōu)解。最優(yōu)子結(jié)構(gòu)是問(wèn)題能用動(dòng)態(tài)規(guī)劃算法求解的前提。
?遞歸算法求解問(wèn)題時(shí),每次產(chǎn)生的子問(wèn)題并不總是新問(wèn)題,有些子問(wèn)題被反復(fù)計(jì)算多次。這種性質(zhì)稱為子問(wèn)題的重疊性質(zhì)。?
?動(dòng)態(tài)規(guī)劃算法,對(duì)每一個(gè)子問(wèn)題只解一次,而后將其解保存在一個(gè)表格中,當(dāng)再次需要解此子問(wèn)題時(shí),只是簡(jiǎn)單地用常數(shù)時(shí)間查看一下結(jié)果。?
?通常不同的子問(wèn)題個(gè)數(shù)隨問(wèn)題的大小呈多項(xiàng)式增長(zhǎng)。因此用動(dòng)態(tài)規(guī)劃算法只需要多項(xiàng)式時(shí)間,從而獲得較高的解題效率。
?
總結(jié)
以上是生活随笔為你收集整理的矩阵连乘 动态规划 详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: LeetCode题库整理【Java】——
- 下一篇: 认识和选购极致画质的显示器