給定n個矩陣, 其中ai
與ai+
1 是可乘的, i = 1, 2,
⋯ , n-1.考察這n個矩陣的連乘積a1
a2,⋯
,an .由於矩陣乘法滿足結合律,所以計算矩陣的連乘積可有多種不同的計算次序,而不同的計算次序有不同的計算量。設計演算法求得多個矩陣連乘時的最小計算量。
分析最優解的性質 (thinking top-dwon)
為方便起見,將矩陣連乘積ai
ai+1
⋯aj 簡記為a[i:j]。考察計算a[1:n]的最優計算次序。設這個計算次序在矩陣ak
和ak+1
之間將矩陣鏈斷開, 1 <= k < n, 則其相應的完全加括號方式為((a1
⋯ak )(ak
+1⋯a
n ))。依此次序,先計算a[1:k]和a[k+1:n],然後將計算結果相乘得到a[1:n],依此計算順序總計算量為a[1:k]的計算量加上a[k+1:n]的計算量,再加上a[1:k]和a[k+1:n]相乘的計算量。
關鍵特徵:計算a[1:n]的最優次序所包含的計算矩陣子鏈a[1:k]和a[k+1:n]的次序也是最優的。即滿足最優子結構性質。
建立遞迴關係
對於矩陣連乘積的最優計算次序問題,設計算a[i:j],1<=i<=j<=n,所需的最少數乘次數為m[i][j],則原問題的最優值為m[1][n]。可以將m[i][j]遞迴的定義為 m[
i][j
]=i = j
i < j且i<=k
m[i][j]給出了最優值,即計算a[i:j]所需最少數乘次數。同時還確定了計算a[i:j]的最優次序中的斷開位置k,也就是說,對於這個k有 m[
i][j
]=m[
i][k
]+m[
k+1]
[j]+
pi−1
pkpj
若將對應於m[i][j]的斷開位置k記為s[i][j],在計算出最優值m[i][j]後,可遞迴地由s[i][j]構造出相應的最優解。
計算最優值(solving bottom-up)
由於該問題滿足子問題重疊的性質,如果採用遞迴方式求解,將大量重複計算,因此需要自底向上進行求解。在計算過程中,儲存已解決的子問題答案。每個子問題只計算一次,而在後面需要時只要簡單查一下,從而避免大量重複計算,最終得到多項式時間的演算法。用陣列p表示矩陣的維數,用二維陣列m來儲存最優解,用二維陣列s記錄最優斷開位置k。
構造最優解
上面給出了計算最優解的遞推式,可以通過查表m[1][n]即可得到最優值。如果需要構造最優解,需要利用二維陣列s中儲存的資訊,即矩陣鏈斷開的位置。具體演算法在下面的traceback函式中給出。
/*
**動態規劃——矩陣連乘
*/#include
#include
#define n 7
void martixchain(int p, int m[n], int s[n]);
void traceback(int i, int j, int s[n]);
int main()
; int m[n][n];
int s[n][n];
martixchain(p, m, s);
traceback(1, 6, s);
return0;}
void martixchain(int p, int m[n], int s[n])}}
}}void traceback(int i, int j, int s[n])
矩陣連乘 動態規劃 動態規劃解矩陣連乘問題
一.矩陣鏈事例 矩陣鏈問題主要涉及的時在多個矩陣相乘,如何通過相乘的順序來減少程式執行。二.例題分析 這次分析過程按照動態規劃的三個基本條件來逐步解答 1 尋找最優子結構 假設我們已經找到父矩陣鏈最優解,當我們劃分到最後一步時都是兩個子矩陣鏈 分別被括號包圍 相乘,如 a1a2a3a4 a5a6a7...
python矩陣連乘 動態規劃 矩陣連乘問題
一 問題描述 給定n個數字矩陣a1,a2,an,其中ai與ai 1是可乘的,設ai是pi 1 pi矩陣,i 1,2,n。求矩陣連乘a1a2.an的加括號方法,使得所用的乘次數最少。例子三個矩陣連乘,可以有 a1a2 a3和a1 a2a3 兩種方法求積 乘法次數分別為 p0p1p2 p0p2p3和p0...
動態規劃 矩陣連乘問題
給定n 1個矩陣 a0,a1,a2,an 1 其中ai與ai 1是可乘的,i 0,1,2,n 2。矩陣乘法滿足結合律。考察這n個矩陣的連乘積,得出運算次數最少的結合。首先,考慮兩個矩陣相乘。如果a b兩個矩陣可以相乘,那麼a b的形式必定滿足 a p q b q r 設c a b,那麼c滿足c p ...