福州大学数学与计算机科学学院《计算机算法设计与分析》上机实验报告(2)专业和班级数学02班姓名詹小青成绩学号031201206实验名称矩阵连乘算法实验目的利用动态规划、公共子序列或贪心算法其中一种实现矩阵连乘实验任务给定n个矩阵:A1,A2,...,An,其中Ai与Ai+1是可乘的,i=1,2...,n-1。确定计算矩阵连乘积的计算次序,使得依此次序计算矩阵连乘积需要的数乘次数最少。输入数据为矩阵个数和每个矩阵规模,输出结果为计算矩阵连乘积的计算次序和最少数乘次数。实验步骤1、算法设计思想(动态规划算法实现矩阵连乘):由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序。这种计算次序可以用加括号的方式来确定。若一个矩阵连乘积的计算次序完全确定,也就是说该连乘积已完全加括号,则可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。完全加括号的矩阵连乘积可递归地定义为:(1)单个矩阵是完全加括号的;(2)矩阵连乘积A是完全加括号的,则A可表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,即A=(BC)2、算法基本步骤:设计算A[i:j],1≤i≤j≤n,所需要的最少数乘次数m[i,j],则原问题的最优值为m[1,n]。当i=j时,A[i:j]=Ai,因此,m[i][i]=0,i=1,2,…,n;当ij时,若A[i:j]的最优次序在Ak和Ak+1之间断开,i=kj,则:m[i][j]=m[i][k]+m[k+1][j]+pi-1pkpj。由于在计算是并不知道断开点k的位置,所以k还未定。不过k的位置只有j-i个可能。因此,k是这j-i个位置使计算量达到最小的那个位置。综上,有递推关系如下:若将对应m[i][j]的断开位置k记为s[i][j],在计算出最优值m[i][j]后,可递归地由s[i][j]构造出相应的最优解。s[i][j]中的数表明,计算矩阵链A[i:j]的最佳方式应在矩阵Ak和Ak+1之间断开,即最优的加括号方式应为(A[i:k])(A[k+1:j)。从s[1][n]记录的信息可知计算A[1:n]的最优加括号方式为(A[1:s[1][n]])(A[s[1][n]+1:n]),进一步递推,A[1:s[1][n]]的最优加括号方式为(A[1:s[1][s[1][n]]])(A[s[1][s[1][n]]+1:s[1][s[1][n]]])。同理可以确定A[s[1][n]+1:n]的最优加括号方式在s[s[1][n]+1][n]处断开...照此递推下去,最终可以确定A[1:n]的最优完全加括号方式,及构造出问题的一个最优解。3、动态规划迭代算法设计:用动态规划迭代方式解决此问题,可依据其递归式自底向上的方式进行计算。在计算过程中,保存已解决的子问题的答案。每个子问题只计算一次,而在后面需要时只需简单检查一下,从而避免了大量的重复计算,最终得到多项式时间的算法。4、算法代码:1.//3d1-2矩阵连乘动态规划迭代实现2.//A130*35A235*15A315*5A45*10A510*20A620*253.//p[0-6]={30,35,15,5,10,20,25}4.#includestdafx.h5.#includeiostream6.usingnamespacestd;7.8.constintL=7;9.10.intMatrixChain(intn,int**m,int**s,int*p);11.voidTraceback(inti,intj,int**s);//构造最优解12.13.intmain()14.{15.intp[L]={30,35,15,5,10,20,25};16.17.int**s=newint*[L];18.int**m=newint*[L];19.for(inti=0;iL;i++)20.{21.s[i]=newint[L];22.m[i]=newint[L];23.}24.25.cout矩阵的最少计算次数为:MatrixChain(6,m,s,p)endl;26.cout矩阵最优计算次序为:endl;27.Traceback(1,6,s);28.return0;29.}30.31.intMatrixChain(intn,int**m,int**s,int*p)32.{33.for(inti=1;i=n;i++)34.{35.m[i][i]=0;36.}37.for(intr=2;r=n;r++)//r为当前计算的链长(子问题规模)38.{39.for(inti=1;i=n-r+1;i++)//n-r+1为最后一个r链的前边界40.{41.intj=i+r-1;//计算前边界为r,链长为r的链的后边界42.43.m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j];//将链ij划分为A(i)*(A[i+1:j])44.45.s[i][j]=i;46.47.for(intk=i+1;kj;k++)48.{49.//将链ij划分为(A[i:k])*(A[k+1:j])50.intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j];51.if(tm[i][j])52.{53.m[i][j]=t;54.s[i][j]=k;55.}56.}57.}58.}59.returnm[1][L-1];60.}61.62.voidTraceback(inti,intj,int**s)63.{64.if(i==j)return;65.Traceback(i,s[i][j],s);66.Traceback(s[i][j]+1,j,s);67.coutMultiplyAi,s[i][j];68.coutandA(s[i][j]+1),jendl;69.}上述迭代算法的运行过程如下图所示:当R=2时,先迭代计算出:m[1:2]=m[1:1]+m[2:2}+p[0]*p[1]*p[2];m[2:3]=m[2:2]+m[3:3]+p[1]*p[2]*p[3];m[3:4]=m[3:3]+m[4][4]+p[2]*p[3]*p[4];m[4:5]=m[4:4]+m[5][5]+p[3]*p[4]*p[5];m[5:6]=m[5][5]+m[6][6]+p[4]*p[5]*p[6]的值;当R=3时,迭代计算出:m[1:3]=min(m[1:1]+m[2:3]+p[0]*p[1]*p[3],m[1:2]+m[3:3]+p[0]*p[2]*p[3]);m[2:4]=min(m[2:2]+m[3:4]+p[1]*p[2]*p[4],m[2:3]+m[4:4]+p[1]*p[3]*p[4])......m[4:6]=min(m[4:4]+m[5:6]+p[3]*p[4]*p[6],m[4:5]+m[6:6]+p[3]*p[5]*p[6]);......依次类推,根据之前计算的m值,迭代计算最优解。实验结果实验结果截图: