C++作業9.|Matrix chain multiplication

Exercise 9.6

Matrix chain multiplication

矩陣鏈相乘,求最小的乘法次數

Given a sequence of matrices, we want to find the most efficient way to multiply these matrices together. The problem is not actually to perform the multiplications, but merely to decide in which order to perform the multiplications.
We have many options because matrix multiplication is associative. In other words, no matter how we parenthesize the product, the result will be the same. For example, if we had four matrices A, B, C, and D, we would have:
(ABC)D = (AB)(CD) = A(BCD) = A(BC)D = ....

However, the order in which we parenthesize the product affects the number of simple arithmetic operations needed to compute the product, or the efficiency. For example, suppose A is a 10 × 30 matrix, B is a 30 × 5 matrix, and C is a 5 × 60 matrix. Then,
(AB)C = (10×30×5) + (10×5×60) = 1500 + 3000 = 4500 operations
A(BC) = (30×5×60) + (10×30×60) = 9000 + 18000 = 27000 operations.

Clearly the first method is the more efficient. Now that we have identified the problem, how do we determine the optimal parenthesization of a product of n matrices? We could go through each possible parenthesization (brute force), but this would require time exponential in the number of matrices, which is very slow and impractical for large n. The solution, as we will see, is to break up the problem into a set of related subproblems. By solving subproblems one time and reusing these solutions many times, we can drastically reduce the time required. This is known as dynamic programming.

先形式化一下我們的input,矩陣鏈{A1,A2,...,An},其中對於矩陣Ai,它是一個Pi-1 * Pi的矩陣。m[i,j] 表示{Ai,Ai+1,..., Aj}相乘的最小的乘法次數

這個遞歸的思路其實和第一個問題有點類似,先看怎麼遞歸。

首先我們要找出一個點來分隔這個鏈,相當於這個點把這個問題轉換爲了 該點前一部分的矩陣鏈的最小的乘法次數問題和該點後一部分的矩陣鏈的最小的乘法次數問題。

但是這個點怎麼找呢?和第一個例子一樣,我們直接遍歷的來找。

所以我們的遞歸應該是這樣的:
m[i,j] = mini<=k<=j (m[i,k] + m[k+1,j] + Pi-1*Pk*Pj)

當然,這是對於i!=j的情況,當i==j的時候呢?顯然 是0了,因爲我們的矩陣鏈就一個矩陣。

EXAMPLE INPUT
9     6    10    11     8     4     5     7    12    13
EXAMPLE OUTPUT
2816



#include <iostream> 
using namespace std; 
 
int min(int x, int y) {
	return x < y ? x : y;
}

int getMultiplications(int num, int dim[]) {
	int ary[233][233];
	
	// m[i,i] = 0
	for (int i = 1; i <= num; ++ i) {
		ary[i][i] = 0;
	}
	
	// let m[i,j] = maxInt (or a very huge int)
	for (int i = 1; i <= num; ++ i) {
		for (int j = i + 1; j <= num; ++ j) {
			ary[i][j] = 233333333;
		}
	}
	
	for (int p = 1; p < num; ++ p) {
		for (int i = 1; i < num + 1; ++ i) {
			for (int k = i; k < i + p; ++ k) {
				ary[i][i+p] = min(ary[i][k] + ary[k+1][i+p]
				 + dim[i-1] * dim[k] * dim[i+p], ary[i][i+p]);
			}
		}
	}
	// m[1,num] is the result
	return ary[1][num];
}

int main() { 
    int dimensions[10]; 
    for (int i = 0; i < 10; ++ i) { 
        cin >> dimensions[i]; 
    } 
    cout << getMultiplications(9, dimensions); 
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章