例:
P=<30,35,15,5,10,20> 它对应5个矩阵
A1:30×35 A2:35×15 A3:15×5 A4:5×10 A5:10×20
先计算:
m[1,1]=0 m[2,2]=0 m[3,3]=0 m[4,4]=0 m[5,5]=0
当r=2表示两个矩阵相乘的运算量:
m[1,2]=30×35×15=15750
m[2,3]=35×15×5=2625
m[3,4]=15×5×10=750
m[4,5]=5×10×20=1000
r=3表示3个矩阵相乘的运算量:
m[1,3]=min{m[1,2]+30×15×5,m[2,3]+30×35×5}=min{15750+2625,2625+5250}=7875 A1(A2A3) s[1,3]=1
m[2,4]=min{m[2,3]+35×5×10,m[3,4]+35×15×10}={2625+1750,750+5250}=4375 (A2A3)A4 s[2,4]=3
m[3,5]=min{m[3,4]+15×10×20,m[4,5]+15×5×20}=2500 A3(A4A5) s[3,5]=3
r=4表示4个矩阵相乘的运算量:
m[1,4]=min{m[2,4]+30×35×10,m[1,2]+m[3,4]+30×15×10,m[1,3]+30×5×10}
=min{4375+10500,15750+750+4500,7875+1500}
=9375 [A1A2A3]A4---->(A1(A2A3))A4 s[1,4]=3
m[2,5]=min{m[3,5]+35×15×20,m[2,3]+m[4,5]+35×5×20,m[2,4]+35×10×20}
=min{2500+10500,2625+1000+3500,4375+7000}
=7125 (A2A3)(A4A5) s[2,5]=3
r=5表示5个矩阵相乘的运算量:
m[1,5]=min{m[2,5]+30×35×20,m[1,2]+m[3,5]+30×15×20,m[1,3]+m[4,5]+30×5×20,m[1,4]+30×10×20}
=min{7125+21000,15750+2500+9000,7875+1000+3000,9375+9000}
=11875 (A1A2A3)(A4A5)---->(A1(A2A3))(A4A5) s[1,5]=3
优化函数备忘录:
r=1 m[1,1]=0 m[2,2]=0 m[3,3]=0 m[4,4]=0 m[5,5]=0
r=2 m[1,2]=15750 m[2,3]=2625 m[3,4]=750 m[4,5]=1000
r=3 m[1,3]=7875 m[2,4]=4375 m[3,5]=2500
r=4 m[1,4]=9375 m[2,5]=7125
r=5 m[1,5]=11875
标记函数:
r=2 s[1,2]=1 s[2,3]=2 s[3,4]=3 s[4,5]=4
r=3 s[1,3]=1 s[2,4]=3 s[3,5]=3
r=4 s[1,4]=3 s[2,5]=3
r=5 s[1,5]=3
根据 s[1,5]=3 推出最后一次划分的位置为3 [A1A2A3][A4A5] 然后再由[A1A2A3]找s[1,3]=1 推出最后一次划分位置为1 A1(A2A3)
所以最终答案为:(A1(A2A3))(A4A5) 运算次数为:11875次
#include<iostream>
#include<iomanip>
using namespace std;
int s[50][50],m[50][50];
int a[100];
void juzhen(int n)//通过迭代实现动态规划
{
int i,r,j,t,k;
for(i=1;i<=n;i++)
for(j=i;j<=n;j++) //将m[i,i]与s[i,j]赋初值
{
m[i][i]=0;
s[i][j]=i;
}
for(r=2;r<=n;r++) //r为当前计算的链长
for(i=1;i<=n-r+1;i++) //n-r+1为当前最后一个r链的前边界
{
j=i+r-1; //计算前边界为i,后边界为j的链r
m[i][j]=m[i+1][j]+a[i-1]*a[i]*a[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]+a[i-1]*a[k]*a[j]; //划分位置为(Ai ... Ak)(Ak+1 ... Aj)
if(t<m[i][j]) //用更好的值替换
{
m[i][j]=t;
s[i][j]=k;
}
}
}
}
void youhua(int n) //表格输出优化函数值备忘录
{
int r,i,j;
cout<<"r=1"<<" ";
for(i=1;i<=n;i++)
cout<<"m["<<i<<","<<i<<"]"<<"="<<left<<setw(6)<<m[i][i]<<" ";
cout<<endl;
for(r=2;r<=n;r++)
{
cout<<"r="<<r<<" ";
for(i=1;i<=n-r+1;i++)
{
j=i+r-1; //记录位置
cout<<"m["<<i<<","<<j<<"]"<<"="<<left<<setw(6)<<m[i][j]<<" ";
}
cout<<endl;
}
}
void biaoji(int n) //表格输出标记函数
{
int r,i,j;
for(r=2;r<=n;r++)
{
cout<<"r="<<r<<" ";
for(i=1;i<=n-r+1;i++)
{
j=i+r-1; //记录位置
cout<<"s["<<i<<","<<j<<"]"<<"="<<left<<setw(6)<<s[i][j]<<" ";
}
cout<<endl;
}
}
void kuohao1(int i,int j)// 递归输出括号表示法
{
if(i==j)
cout<<"A"<<i;
else if(i+1==j)
cout<<"(A"<<i<<"A"<<j<<")";
else
{
cout<<"(";
kuohao1(i,s[i][j]); //取s[i,j]做分割位置进行递归
kuohao1(s[i][j]+1,j);
cout<<")";
}
}
void kuohao2(int n) //表格输出
{
int i,j,r;
for(r=2;r<=n;r++)
{
cout<<"r="<<r<<" ";
for(i=1;i<=n-r+1;i++)
{
j=i+r-1;
kuohao1(i,j);
cout<<" ";
}
cout<<endl;
}
}
//主函数
void main()
{
int n,i;
cout<<"请输入矩阵个数:";cin>>n;
cout<<"请输入对应矩阵:";
for (i=0;i<=n;i++)
cin>>a[i];
for (i=0;i<n;i++)
cout<<"A"<<i+1<<":"<<a[i]<<"*"<<a[i+1]<<" ";
cout<<endl;
juzhen(n);
cout<<"优化函数值的备忘录:"<<endl;youhua(n);
cout<<"标记函数:"<<endl;biaoji(n);
cout<<"括号表示法:"<<endl;kuohao2(n);
}