最優二叉查找樹的一道思考習題
同最優二叉查找樹一樣,矩陣連乘問題也是一個卡特蘭數問題(其動态規劃的構造過程都很像)
分析解答:
a,鋪墊的數學知識首先要搞清楚矩陣相乘是怎麼乘的:
1)對于連續的n個矩陣相乘 A1 * A2 *A3.........An,其乘法順序可以是任意的,可以在上面加括号,改變做乘法的順序,例如 A*B*C三個矩陣相乘可以A*(B*C)
也可以直接按從左到右的順序。連續的兩個矩陣的位數必須滿足m*p,p*n才能相乘,且相乘後的結果是個m*n的矩陣。(線性代數的知識)
2)對于2個m*p,p*n的矩陣相乘,共做乘法次數為 m*n*p 次。這是預備知識,知道矩陣連續的乘法的運算次數跟運算順序有關後,就很容易舉出例子了,略。
b,卡特蘭數個,證明很麻煩,有時間看了組合數學再來看
c,重點是要解決這個問題。
設M[i , j]表示從第 i 個矩陣到第 j 個矩陣連乘的最少乘法次數,(i 從 0 編号),我們最終的目标是求 M[0 , n-1]。
Ai *.......Ak * Ak+1.....Aj
假設要得到這個式子的值(即從矩陣 i 連乘到矩陣 j),所作的最後一個矩陣乘法是在矩陣 k 後(注意準确的描述位置)斷開的(即左右都已乘運算好),那麼容易得到
其遞推式:
M[i , j] = min{ M[i , k] + M[k+1 , j] + p[i - 1] * p[ k ] * p[ j ] } i <= k <= j-1
其中 di 是矩陣 Ai 的第一維,dk+1是斷開處矩陣 Ak 的第二維(即Ak+1的第一維,是一樣的),dj+1是最後一個矩陣 Aj 的第二維。
得到這個式子也是一個逆向思維的過程。
可以用矩陣連乘的動态規劃構造過程與最優二叉查找樹比較下,發現其構造非常相似(在前面一篇dp之什麼叫做professional中提到過,不再詳述)
實作:
初始條件:M[i , i] = 0
填表順序:鑒于其遞推式與最優二叉查找樹相似,填表順序也是按對角線的,自己畫畫就知道了。
代碼也跟最優二叉查找樹的控制邏輯相似:
package Section8;
/*第八章 動态規劃 課後習題:矩陣連乘*/
public class MatEven {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] Dim = {30,35,35,15,15,5,5,10,10,20,20,25};
int result = MatEven(Dim);
System.out.println("\n動态規劃求的的最優政策相乘順序導緻的最少乘法數為:" + result);
}
public static int MatEven(int[] Dim){
//接受n個矩陣的次元數組Dim大小為2n
int n = Dim.length / 2; //有n個矩陣,編号0...n-1,編号為k的矩陣的維數是Dim[2k] * Dim[2k+1]
int[][] Result = new int[n][n]; //最小代價矩陣
//初始化
for(int i = 0;i < n;i++)
Result[i][i] = 0;
//沿對角線填矩陣
for(int d = 1;d <= n-1;d++) //共n-1條對角線需要填
{
for(int i = 0;i <= n-d-1;i++) //第d條對角線的第一個點橫坐标為d
{
//int j = i - d;
int j = i + d; //在第d條對角線上的點,橫縱坐标的關系是j = i + d
//這樣就确定了一個位置(i,j)的坐标,然後來填(i,j)
int Min = 1000000000;
for(int k = i;k <= j-1;k++) //從第k個矩陣後面斷開
{
//動态規劃狀态轉移方程
int temp = Result[i][k] + Result[k+1][j] + (Dim[2*i] * Dim[2*k + 1] * Dim[2*j+1]);
if( temp < Min)
Min = temp;
}
Result[i][j] = Min;
}
}
return Result[0][n-1];
}
上面用一個數組接受一個連乘的矩陣的維數,
例如連乘的矩陣維數是:30*35 35*15 15*5 5*10 10*20 20*25
用動态規劃求解得到的最佳乘法次數是:
動态規劃求的的最優政策相乘順序導緻的最少乘法數為:15125
直接傳回矩陣的話就可以得到整個M[i , j]的值
如果按照從左到右的順序做乘法,是遠遠不止這個次數的。
-------------------------------------------------------------------------
當然,再做一些處理,就還可以得到具體的次序,類似于最優二叉查找樹,就是要記錄動态規劃産生的過程,略
----------------------------------------------------------------------------------------------
總結:
矩陣連乘問題是個卡特蘭數問題
其動态規劃的構造過程非常類似于最優二叉查找樹
矩陣連乘的最有子結構是什麼?
本文轉自農夫山泉别墅部落格園部落格,原文連結:http://www.cnblogs.com/yaowen/p/4466268.html,如需轉載請自行聯系原作者