矩阵链乘法
#include<iostream>
using namespace std;
struct Matrix
{
int rows;
int cols;
Matrix(int row=0,int col=0):rows(row),cols(col){}
};
void PrintOptimalParens(int** record, int i, int j)
{
if (i == j)
{
printf("A[%d]", i);
return;
}
else
{
printf("(");
PrintOptimalParens(record, i, record[i][j]);
PrintOptimalParens(record, record[i][j] + 1, j);
printf(")");
}
}
int MatrixChainOrder(const Matrix* matrix, int len)
{
int** result = new int*[len];
int** record = new int*[len];
for (int i = 0; i < len; i++)
{
result[i] = new int[len];
record[i] = new int[len];
}
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
result[i][j] = 0;
record[i][j] = -1;
}
}
for (int step = 2; step<= len; step++) //步距
{
for (int begin = 0; begin < len - step+1; begin++) //起始
{
int min = 0x7fffffff;
int cur = step + begin - 1;
for (int k = begin ; k < cur; k++) //分割点
{
int min1 = result[begin][k] + result[k+1][cur] + matrix[begin].rows*matrix[k].cols*matrix[cur].cols;
//printf("result[%d][%d] = %d\t", begin, k, result[begin][k]);
//printf("result[%d][%d] = %d\t", k+1, cur, result[k+1][cur]);
//printf("matrix[%d-%d]*matrix[%d-%d] = %d\n", begin, k,k+1, cur, matrix[begin].rows*matrix[k].cols*matrix[cur].cols);
if (min1 < min)
{
min = min1;
record[begin][cur] = k;
}
}
result[begin][cur] = min;
//printf("result[%d][%d] = %d\n\n", begin, cur, result[begin][cur]);
}
}
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
cout<<result[i][j]<<" ";
}
cout << endl;
}
cout << endl;
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
cout << record[i][j] << " ";
}
cout << endl;
}
cout << endl;
PrintOptimalParens(record, 0, len - 1);
cout << endl;
int temp = result[0][len - 1];
for (int i = 0; i < len; i++)
{
delete[] result[i];
delete[] record[i];
}
delete[] result;
delete[] record;
return temp;
}
int main()
{
Matrix matrix[6] = { Matrix(30,35),Matrix(35,15),Matrix(15,5),Matrix(5,10),Matrix(10,20),Matrix(20,25) };
int result = MatrixChainOrder(matrix, 6);
cout << result << endl;
return 0;
}
运行结果
自顶向下备忘录方法
int MatrixChainOrder(Matrix* matrix, int** result, int begin, int end)
{
if (result[begin][end] > 0x8fffffff)
{
return result[begin][end];
}
if (begin == end)
{
result[begin][end] = 0;
return 0;
}
int min = 0x7fffffff;
for (int i = begin; i < end; i++)
{
int temp = MatrixChainOrder(matrix, result, begin, i)
+ MatrixChainOrder(matrix, result, i + 1, end)
+ matrix[begin].rows*matrix[i].cols*matrix[end].cols;
if (min > temp)
{
min = temp;
}
}
result[begin][end] = min;
return min;
}
int MatrixChainOrder(Matrix* matrix, int len)
{
int** result = new int*[len];
for (int i = 0; i < len; i++)
{
result[i] = new int[len];
}
for (int i = 0; i < len; i++)
{
for (int j = 0; j < len; j++)
{
result[i][j] = 0x80000000;
}
}
return MatrixChainOrder(matrix, result, 0, len-1);
}
int main()
{
Matrix matrix[6] = { Matrix(30,35),Matrix(35,15),Matrix(15,5),Matrix(5,10),Matrix(10,20),Matrix(20,25) };
int result = MatrixChainOrder(matrix, 6);
cout << result << endl;
return 0;
}
运行结果