您的位置:首页 > 其它

算法导论学习笔记(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;

};
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: