陣鏈乘法問題:
給定乙個n個矩陣的序列(矩陣鏈),矩陣ai的規模為pi-1 * pi, 求完全括號話方案,使得計算成績a1*a2*......*an所需標量乘法次數最少。
注意:求解矩陣鏈乘法問題並不是要真正進行矩陣相乘運算,只是確定代價最低的計算順序,確定最優計算書序所花費的時間通常要比隨後真正進行矩陣相乘所節省的時間要少。
兩個矩陣a、b相容,即a的列數等於b的行數時, 才能相乘。n個矩陣相乘有很多種計算方案,例如
完全括號化的矩陣相乘鏈有
(a1(a2(a3 a4))
(a1((a2* a3)a4))
((a1 * a2)(a3* a4))
((a1(a2*a3)a4))
(((a1*a2)a3)a4)
但是每種相乘辦法進行的乘法次數都不一樣,這個問題即是是進行的乘法次數最少,求出分割點,並且給出最優化乘法鏈,運用的是自底向上的動態規劃方法求解的
下面的兩個m、s二維矩陣多用了一些空間,跟課本上的i, j標號保持了同步,便於理解,免去處理陣列下標的很多問題。。。嘿嘿,有點偷懶....
#include #include #include #include using namespace std;
pair>, vector>>
matrixchainorder(vectorp)
}} }
cout << "vector m:" << endl;
for (int i = 0; i < n; i++)
cout << "vector s:" << endl;
for (int i = 0; i < n; i++)
return make_pair(m, s);
}//列印→_→(最優括號化方案)
void printoptimalparens(vector> s, int i, int j)
}const int n = 7;
//一般遞迴方法
int recursivematrixchain(int (*m)[n], int *p, int i, int j)
return m[i][j];
}//帶備忘的自頂向下的遞迴方法實現
int lookupchain(int (*m)[n], int *p, int i, int j)
return m[i][j];
}//列印二維陣列的右上半部分
void displaytwoarray(int (*twoarray)[n])
cout << endl; }}
int main()
; vectorivp(p, p+sizeof(p)/sizeof(int));
cout << "自底向下的動態規劃方法求解: " << endl;
printoptimalparens(matrixchainorder(ivp).second, 1, 6);
cout << endl;
cout << "普通遞迴方法求解:";
int m[n][n];
cout << recursivematrixchain(m, p, 1, 6) << endl;
cout << "帶備忘的遞迴方法求解:";
cout << lookupchain(m, p, 1, 6) << endl;
system("pause");
return 0;
}
執行結果為:(我把求出的兩個二維陣列也列印出來了...)
演算法導論 第15章 動態規劃之鋼條切割
python coding utf 8import numpy import copyimport timea 0,1,5,8,9,10,17,17,20,24,30 不同長度鋼條的 表,a k 對應於長度為k的剛條的 assert len a 11 cost numpy.zeros shape 1...
《演算法導論》讀書筆記之第15章 動態規劃 總結
前言 書中列舉四個常見問題,分析如何採用動態規劃方法進行解決。今天把動態規劃演算法總結一下。關於四個問題的動態規範分析過程可以參考前面的幾篇日誌,鏈結如下 裝配線排程問題 矩陣鏈乘問題 最長公共子串行問題 最優二叉查詢樹問題 1 基本概念 動態規劃是通過組合子問題的解而解決整個問題的,通過將問題分解...
演算法導論 動態規劃之矩陣鏈乘法
原題見pdf204頁 a0a1a2a3a4a5 定義 a i 的維數為p i p i 1 m i j 為重a i 乘到a j 標量乘法運算的最小次數。m i j 0,當i j時 加入要求解的是m 0 2 則m 0 2 為m 0 0 m 1 2 p 0 p 1 p 3 m 0 1 m 2 2 p 0 ...