1.问题
设A1,A2,……An为n个矩阵的序列给定一个n个矩阵的序列,其中Ai为Pi=1*P阶矩阵,这个矩阵链的输入用向量P=<P0,P1,P2,…,Pn>给出,确定一种乘法次序,使得基本运算的总次数达到最小。
2.解析
Ai…j:表示矩阵链相乘的子问题Ai,Ai+1…Aj;
M[i…j]:表示得到乘积Ai…j所用的最少基本运算次数;
假定最后一次相乘发生在矩阵链Ai…kAk+1…j之间,m[i,j]=min{m[i,k]+m[k+1,j]+Pi=1PkPj}满足优化原则。也就是说,m[i,j]最小值时,m[i,k],m[k+1,j]也是最小的。
3.设计
int recurMatrixChain(int* data,int i, int j) {
if (i == j) { // 递归到最小单元
m[i][j] = 0;
s[i][j] = i;
return m[i][j];
}
m[i][j] = 1 << 30; //无穷大
s[i][j] = i; //在i分割
for (int k=i; k<=j-1;k++) { // 从i到j-1开始递归,求最小值,然后加上整体数据
int q = recurMatrixChain(data, i, k) + recurMatrixChain(data, k+1, j) + data[i-1]*data[k]*data[j]; //data[0]*data[k]*data[j]
if (q < m[i][j]) {
m[i][j] = q;
s[i][j] = k;
}
}
return m[i][j];
}
void matrixChain(int* data,int n) { //迭代
int i,j,k,t;
for (int i = 0; i < n+1; i++){
for (int j = 0; j < n+1; j++) {
s[i][j] = i;
}
}
printR(); //按照 r 来打印数据
for(int r = 2; r <= n; r++) { //r为当前问题规模,进行子问题划分
for(i = 1; i <= (n-r+1); i++) { //i的起点不断变化,各种r长
j = i + r -1; //不同终点
m[i][j] = m[i+1][j] + data[i-1]*data[i]*data[j]; //划分为Ai(Ai+1....Aj)
s[i][j] = i; //标记元素 = 坐标 记录分割位置
for(k = i + 1; k <= j - 1; k++) { //不同的划分位置
t = m[i][k] + m[k+1][j] + data[i-1]*data[k]*data[j]; //前面的+后面的+相乘数据
if (t < m[i][j]) {
m[i][j] = t;
s[i][j] = k;
}
}
}
}
}
4.分析
递归算法复杂度:
迭代算法复杂度:
T(n)=O(n3)