问题描述:
在矩阵链乘的过程中,不同的相乘次序对于运算代价产生巨大的影响。本算法主要是采用动态规划的方法求解举证链乘的顺序,使得计算乘积所需要的标量乘法次数数量最少。 例如:对于A1:10*100,A2:100*5, A3:5*50规模的三个矩阵, 如果按((A1A2)A3)顺序计算,代价为10*100*5+10*5*50=7500;如果按照(A1(A2A3))顺序,计算代价为100*5*50+10*100*50=75000.
本方法最主要的目标是对矩阵链进行完全括号化,使其计算代价最小。
/*矩阵练乘法
int p[N + 1] = { 30, 35, 15, 5, 10, 20, 25 }; 测试用例
输入:p为矩阵规模序列,例如A1:30*35 , A2:35*15 ,A3:15*5 等
m[i][j]表示Ai...Aj的最小代价值
s[i][j]表示Ai...Aj之间在什么地方加括号
*/
#include<iostream>
#include<algorithm>
using namespace std;
#define N 6 //举证个数
void matrix_chain_order(int p[N+1], int m[N + 1][N + 1],int s[N+1][N+1]){
int q = 0;
for (int i = 1; i <= N; i++) m[i][i] = 0;
for (int l = 2; l <= N; l++){
for (int i = 1; i <= N - l + 1; i++)
{
int j = i + l - 1;
m[i][j] = 999999999;
for (int k = i; k < j; k++){
q = m[i][k] + m[k + 1][j] + p[i - 1] * p[k] * p[j];
if (q < m[i][j]){
m[i][j] = q;
s[i][j] = k;
}
}
}
}
}
//打印括号化的矩阵链
void print(int s[N + 1][N + 1],int i,int j){
if (i == j) cout << "A" << i;
else{
cout << "(";
print(s, i, s[i][j]);
print(s, s[i][j]+1, j);
cout << ")";
}
}
int main(){
int m[N + 1][N + 1], s[N + 1][N + 1];
int p[N + 1] = { 30, 35, 15, 5, 10, 20, 25 };
matrix_chain_order(p,m,s);
print(s, 1, 6);
return 0;
}
运行结果截图: