算法导论学习笔记(8)——动态规划之矩阵链乘法
2012-05-01 22:17
405 查看
【问题描述】
给定有n个连乘矩阵的维数,要求计算其采用最优计算次序时所用的乘法次数,即所要求计算的乘法次数最少。例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10*100,100*5和5*50,采用(A1A2)A3,乘法次数为10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次数为100*5*50+10*100*50=75000次乘法,显然,最好的次序是(A1A2)A3,乘法次数为7500次。
c++代码:
#define MAX_SIZE 50
using namespace std;
int m[MAX_SIZE][MAX_SIZE];
int s[MAX_SIZE][MAX_SIZE];
//m表示计算矩阵需要的标量乘法运算次数的最小值
//s记录计算m时取得的最优代价处k的值
//p表示的是矩阵的维数数组,例如第i个矩阵的维数是p[i-1] x p[i]
//num表示矩阵数
void matrix_chain_order(int p[],int num)
{
int n=num;
int i,j,k,w,q;
for(i=1;i<=n;i++)
m[i][i]=0;
for(w=1;w<=n-1;w++)//j-i=w
{
for(i=1;i<=n-w;i++)
{
j=w+i;
m[i][j]=100000000;//对于不同的矩阵数可以自行设置大小
for(k=i;k<=j-1;k++)
{
q=s[i][k]+s[k+1][j]+p[i-1]*p[k]*p[j];
if(q<m[i][j])
{
m[i][j]=q;
s[i][j]=k;//记录k的值
}
}
}
}
}
void display(int k,int i,int j)//k代表最优的中间值
{
if(i==j)
{
printf("M%d",i);
}
else
{
printf("(");
display(s[i][k],i,k);
printf("*");
display(s[k+1][j],k+1,j);
printf(")");
}
}
int main()
{
int i;
int num,size[MAX_SIZE];
printf("请输入相乘矩阵的个数:");
cin>>num;
printf("请输入矩阵的行数与列数:\n");
for(i=0;i<=num;i++)
cin>>size[i];
matrix_chain_order(size,num);
printf("实现矩阵相乘最少的标量积为: %d",s[1][num]);
printf("\n矩阵相乘顺序为:");
display(s[1][num],1,num);
printf("\n");
return 1;
};
给定有n个连乘矩阵的维数,要求计算其采用最优计算次序时所用的乘法次数,即所要求计算的乘法次数最少。例如,给定三个连乘矩阵{A1,A2,A3}的维数分别是10*100,100*5和5*50,采用(A1A2)A3,乘法次数为10*100*5+10*5*50=7500次,而采用A1(A2A3),乘法次数为100*5*50+10*100*50=75000次乘法,显然,最好的次序是(A1A2)A3,乘法次数为7500次。
c++代码:
#define MAX_SIZE 50
using namespace std;
int m[MAX_SIZE][MAX_SIZE];
int s[MAX_SIZE][MAX_SIZE];
//m表示计算矩阵需要的标量乘法运算次数的最小值
//s记录计算m时取得的最优代价处k的值
//p表示的是矩阵的维数数组,例如第i个矩阵的维数是p[i-1] x p[i]
//num表示矩阵数
void matrix_chain_order(int p[],int num)
{
int n=num;
int i,j,k,w,q;
for(i=1;i<=n;i++)
m[i][i]=0;
for(w=1;w<=n-1;w++)//j-i=w
{
for(i=1;i<=n-w;i++)
{
j=w+i;
m[i][j]=100000000;//对于不同的矩阵数可以自行设置大小
for(k=i;k<=j-1;k++)
{
q=s[i][k]+s[k+1][j]+p[i-1]*p[k]*p[j];
if(q<m[i][j])
{
m[i][j]=q;
s[i][j]=k;//记录k的值
}
}
}
}
}
void display(int k,int i,int j)//k代表最优的中间值
{
if(i==j)
{
printf("M%d",i);
}
else
{
printf("(");
display(s[i][k],i,k);
printf("*");
display(s[k+1][j],k+1,j);
printf(")");
}
}
int main()
{
int i;
int num,size[MAX_SIZE];
printf("请输入相乘矩阵的个数:");
cin>>num;
printf("请输入矩阵的行数与列数:\n");
for(i=0;i<=num;i++)
cin>>size[i];
matrix_chain_order(size,num);
printf("实现矩阵相乘最少的标量积为: %d",s[1][num]);
printf("\n矩阵相乘顺序为:");
display(s[1][num],1,num);
printf("\n");
return 1;
};
相关文章推荐
- 算法导论学习笔记—Strassen算法的Java实现
- 算法导论学习笔记 第2章 算法基础
- 算法导论学习笔记---第三章
- 算法导论学习笔记-1
- 【算法导论学习笔记】第3章:函数的增长
- 算法导论学习笔记之摊还分析
- 算法导论学习笔记(16)——图的基本算法
- 【算法导论】学习笔记第一章:算法在计算中的作用
- 算法导论--学习笔记01
- 算法导论学习笔记-第十六章-贪心算法
- 算法导论--学习笔记02
- 【算法导论学习笔记】第2章:算法基础
- 【算法导论学习笔记】---选择算法
- 【算法导论】学习笔记——第12章 二叉搜索树
- 算法导论学习笔记——第13章 红黑树
- [算法导论] 单源最短路径 - Dijkstra 学习笔记
- 算法导论学习笔记-第十八章-B树
- 算法导论学习笔记(六):计数排序与基数排序
- 算法导论 学习笔记 第四章 递归
- Introduction to Algorithms 算法导论 第3章 函数的增长 学习笔记及习题解答