C语言实现矩阵连乘算法

由于矩阵乘法满足结合律,所以矩阵连乘可以有不同的计算次序。所以矩阵连乘次序可以通过”()“来确定。不同的加括号方式有不同的计算次序和计算量。我们可以用动态规划求矩阵连乘最优计算次序和最少计算量。

其中,P存放矩阵行列数。

s[i][j]中的数组为矩阵链A[i:j]的最佳断开方式应在矩阵Ak和A(k+1)之间断开。

//矩阵为:A:30*35  B:35*15 C:15*5 D:5*10 E:10*20 F:20*25
//p[]={30,35,15,5,10,20,25}
void MatrixChain(int p[1024],int n,int m[1024][1024],int s[8][8])
//m为最少乘法次数,s断开位置,p下标,n个矩阵
{
for(int i = 1;i <= n;i++)
{
m[i][i] = 0;//单一矩阵无法计算
}
for(int r = 2;r <= n;r++)//矩阵子链为r
{
for(int i = 1;i <= n-r+1;i++)//n-r+1为矩阵子链长度为r时,矩阵子链个数
{
int j = i+r-1;//i:长度为r的子链是子链数的第i个,
//j:长度为r的子链是子链数的第i个时,子链末端在P数组的位置
m[i][j] = m[i+1][j] + p[i-1]*p[i]*p[j];//子链是i到j的之间链,乘法次数
s[i][j] = i;//表明计算矩阵链A[i,j]的最佳方式应在矩阵Ak和A(k+1)之间断开
for(int k = i+1;k<j;k++)//在子链i到j之间断开有没有更优的断开位置
{
int t = m[i][k] + m[k+1][j] + p[i-1]*p[k]*p[j];
if(t < m[i][j])//最优位置断开处
{
m[i][j] = t;
s[i][j] = k;//P数组i到j的断开位置为k
}
}
}
}
}




void Traceback(int i,int j,int s[8][8])//显示最优断开位置
{
if(i == j)
return;
Traceback(i,s[i][j],s);
Traceback(s[i][j]+1,j,s);
cout<<"Multiply A"<<i<<","<<s[i][j];
cout<<"and A"<<(s[i][j]+1)<<","<<j<<endl;
}


//显示断开位置方式
void shows(int s[8][8])//其中,s[i][j]为矩阵链A[i:j]的最佳断开位置为:在Ak和A(k+1)之间断开。
{
for(int ii = 1;ii<=6;ii++)
{
for(int ij = 1;ij<=6;ij++)
printf("%5d",s[ii][ij]);
printf("\n");
}
}

有什么不对的问题请大家指正。

你可能感兴趣的:(算法,动态规划,C语言,矩阵连乘)