动态规划算法实验报告材料.docx
- 文档编号:23181279
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:26
- 大小:164.20KB
动态规划算法实验报告材料.docx
《动态规划算法实验报告材料.docx》由会员分享,可在线阅读,更多相关《动态规划算法实验报告材料.docx(26页珍藏版)》请在冰豆网上搜索。
动态规划算法实验报告材料
实验标题
1、矩阵连乘2、最长公共子序列3、最大子段和
4、凸多边形最优三角剖分5、流水作业调度
6、0-1背包问题7、最优二叉搜索树
实验目的
掌握动态规划法的基本思想和算法设计的基本步骤。
实验内容与源码
1、矩阵连乘
#include
#include
usingnamespacestd;
constintsize=4;
//ra,ca和rb,cb分别表示矩阵A和B的行数和列数
voidmatriMultiply(inta[][4],intb[][4],intc[][4],intra,intca,intrb,intcb)
{
if(ca!
=rb)cerr<<"矩阵不可乘";
for(inti=0;i for(intj=0;j { intsum=a[i][0]*b[0][j]; for(intk=1;k sum+=a[i][k]*b[k][j]; c[i][j]=sum; } } voidMatrixChain(int*p,intn,intm[][4],ints[][4]) { for(inti=1;i<=n;i++)m[i][i]=0;//对角线 for(intr=2;r<=n;r++)//外维 for(inti=1;i<=n-r+1;i++)//上三角 { intj=i+r-1; m[i][j]=m[i+1][j]+p[i-1]*p[i]*p[j]; s[i][j]=i; for(intk=i+1;k { intt=m[i][k]+m[k+1][j]+p[i-1]*p[k]*p[j]; if(t { m[i][j]=t; s[i][j]=k; } } } } voidTraceback(inti,intj,ints[][4]) { if(i==j) { cout<<"A"< } elseif(i+1==j) { cout<<"(A"< } else { cout<<"("; Traceback(i,s[i][j],s); Traceback(s[i][j]+1,j,s); cout<<")"; } } intmain() { intw; cout<<"矩阵个数: "; cin>>w; intp[w],s[w][w]; cout<<"输入矩阵A1维数: "; cin>>p[0]>>p[1]; for(inti=2;i<=w;i++) { intm=p[i-1]; cout<<"输入矩阵A"< "; cin>>p[i-1]>>p[i]; if(p[i-1]! =m) { cout< "< exit (1); } } Traceback(1,w,s); return0; } 运行结果 2、最长公共子序列 #include #include #defineN100 usingnamespacestd; //str1存储字符串x,str2存储字符串y charstr1[N],str2[N]; //lcs存储最长公共子序列 charlcs[N]; //c[i][j]存储str1[1...i]与str2[1...j]的最长公共子序列的长度 intc[N][N]; //flag[i][j]==0为str1[i]==str2[j] //flag[i][j]==1为c[i-1][j]>=s[i][j-1] //flag[i][j]==-1为c[i-1][j] intflag[N][N]; //求长度 intLCSLength(char*x,char*y) { inti,j; //分别取得x,y的长度 intm=strlen(x); intn=strlen(y); for(i=1;i<=m;i++) c[i][0]=0; for(i=0;i<=n;i++) c[0][i]=0; for(i=1;i<=m;i++) for(j=1;j<=n;j++) { if(x[i-1]==y[j-1]) { c[i][j]=c[i-1][j-1]+1; flag[i][j]=0; } elseif(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; flag[i][j]=1; } else { c[i][j]=c[i][j-1]; flag[i][j]=-1; } } returnc[m][n]; } //求出最长公共子序列 char*getLCS(char*x,char*y,intlen,char*lcs) { inti=strlen(x); intj=strlen(y); while(i&&j) { if(flag[i][j]==0) { lcs[--len]=x[i-1]; i--; j--; } elseif(flag[i][j]==1) i--; else j--; } returnlcs; } intmain() { inti; cout<<"请输入字符串x: "< cin>>str1; cout<<"请输入字符串y: "< cin>>str2; intlcsLen=LCSLength(str1,str2); cout<<"最长公共子序列长度: "< char*p=getLCS(str1,str2,lcsLen,lcs); cout<<"最长公共子序列为: "; for(i=0;i cout< return0; } 运行结果 3、最大子段和 //分治法求最大子段和 #include usingnamespacestd; intMaxSubSum(int*a,intleft,intright) { intsum=0; if(left==right)sum=a[left]>0? a[left]: 0; else { intcenter=(left+right)/2; //最大子段和在左边 intleftsum=MaxSubSum(a,left,center); //最大子段和在右边 intrightsum=MaxSubSum(a,center+1,right); //最大子段和在中间 ints1=0; intlefts=0; for(inti=center;i>=left;i--) { lefts+=a[i]; if(lefts>s1)s1=lefts; } ints2=0; intrights=0; for(inti=center+1;i<=right;i++) { rights+=a[i]; if(rights>s2)s2=rights; } sum=s1+s2;//前后子段和相加 //判断最大子段和 if(sum>leftsum)sum=leftsum; if(sum>rightsum)sum=rightsum; } returnsum; } intMaxSum(int*a,intn) { returnMaxSubSum(a,1,n-1); } intmain() { inta[8]={2,-3,-5,4,1,7,1,-5}; cout<<"最大子段和为: "< return0; } //动态规划法 #include usingnamespacestd; intMaxSum(int*a,intn) { intsum=0,b=0; for(inti=1;i { if(b>0)b+=a[i]; elseb=a[i]; if(b>sum)sum=b; } returnsum; } intmain() { inta[8]={2,-3,-5,4,1,7,1,-5}; cout<<"最大子段和为: "< return0; } 运行结果 4、凸多边形最优三角剖分 #include #include #include #defineN50 usingnamespacestd; structpoint { intx; inty; }; intdistance(pointX,pointY)//两点距离 { intdis=(Y.x-X.x)*(Y.x-X.x)+(Y.y-X.y)*(Y.y-X.y); return(int)sqrt(dis); } intw(pointa,pointb,pointc)//权值 { returndistance(a,b)+distance(b,c)+distance(a,c); } boolJudgeInput()//判断是否能构成凸多边形 { point*v;//记录凸多边形各顶点坐标 int*total;//记录坐标在直线方程中的值 intm,a,b,c; cout<<"请输入凸多边形顶点个数: "; cin>>m; intM=m-1; for(inti=0;i { cout<<"输入顶点v"< "; cin>>v[i].x>>v[i].y; } //根据顶点坐标判断是否能构成一个凸多边形 for(intj=0;j { intp=0; intq=0; if(m-1==j) { a=v[m-1].y-v[0].y; b=v[m-1].x-v[0].y; c=b*v[m-1].y-a*v[m-1].x; } else { a=v[j].y-v[j+1].y; b=v[j].x-v[j+1].x; c=b*v[j].y-a*v[j].x; } for(intk=0;k { total[k]=a*v[k].x-b*v[k].y+c; if(total[k]>0) { p=p+1; } elseif(total[k]<0) { q=q+1; } } if((p>0&&q>0)||(p==0&&q==0)) { cout<<"无法构成凸多边形! "< exit (1); } } } boolminWeightTriangulation()//计算最优值算法 { intM; int**t,**s; point*v; for(inti=1;i<=M;i++) t[i][i]=0; for(intr=2;r<=M;r++) for(inti=1;i<=M-r+1;i++) { intj=i+r-1; t[i][j]=t[i+1][j]+w(v[i-1],v[i],v[j]); s[i][j]=i; for(intk=i+1;k { intu=t[i][k]+t[k+1][j]+w(v[i-1],v[k],v[j]); if(u { t[i][j]=u; s[i][j]=k; } } } returntrue; } voidTraceback(inti,intj,int**s) { if(i==j) return; Traceback(i,s[i][j],s); Traceback(s[i][j]+1,j,s); cout<<"三角形: v"< } intmain() { int**s;//记录最优三角剖分中所有三角形信息 int**t;//记录最优三角剖分所对应的权函数值 point*v;//记录凸多边形各顶点坐标 int*total;//记录坐标在直线方程中的值 intM=0; t=newint*[N]; s=newint*[N]; for(inti=0;i { t[i]=newint[N]; s[i]=newint[N]; } v=newpoint[N]; total=newint[N]; if(JudgeInput()) { if(minWeightTriangulation()) { Traceback(1,M,s); cout< cout<<"最优权值之和为: "< } } return0; } 运行结果: 5、流水作业调度 #include #defineN100 usingnamespacestd; classJobtype { public: /*intoperator<=(Jobtypea)const { return(key<=a.key); }*/ intkey; intindex; booljob; }; voidsort(Jobtype*d,intn) { inti,j; Jobtypetemp; boolexchange;//交换标志 for(i=0;i exchange=false;//本趟排序开始前,交换标志应为假 for(j=n-1;j>=i;j--) if(d[j+1].key temp=d[j+1]; d[j+1]=d[j]; d[j]=temp; exchange=true;//发生了交换,故将交换标志置为真 } if(! exchange)//本趟排序未发生交换,提前终止算法 return; } } intFlowShop(intn,int*a,int*b,int*c) { Jobtype*d=newJobtype[n]; for(inti=0;i { d[i].key=a[i]>b[i]? b[i]: a[i];//执行时间 d[i].job=a[i]<=b[i];//作业组 d[i].index=i;//作业序号 } sort(d,n);; intj=0; intk=n-1; for(inti=0;i { if(d[i].job) { c[j++]=d[i].index; } else { c[k--]=d[i].index; } } j=a[c[0]]; k=j+b[c[0]]; for(inti=1;i { j+=a[c[i]]; k=j k+b[c[i]]: j+b[c[i]]; } deleted;//回收空间 returnk;//返回调度时间 } intmain() { intn,*a,*b,*c; cout<<"作业数: "; cin>>n; Jobtype*d=newJobtype[N]; a=newint[N]; b=newint[N]; c=newint[N]; cout<<"请输入作业号和时间: "; for(inti=0;i { cin>>d[i].index>>d[i].key; } cout< intk=FlowShop(n,a,b,c); cout<<"\n调度时间: "< cout<<"最优调度序列: "; for(inti=0;i { cout< } return0; } 运行结果: 6、0-1背包问题 #include #include usingnamespacestd; constintC=10;//容量 constintN=5;//个数 intmax(constinta,constintb) { returna>b? a: b; } intmin(constinta,constintb) { returna a: b; } /* m为记录数组m[i][j]代表在剩有j容量的条件下,从i开始往后的物品中可以取得的最大价值 w为重量数组,v为价值数组 n为物品个数,c为开始容量 则m[1][c]即此背包能剩下的最大价值 */ voidknapsack(int**m,intn,intc,int*w,int*v) { intjMax=min(w[n]-1,c);//前n-1个物品 for(intj=0;j<=jMax;j++) m[n][j]=0; for(intj=w[n];j<=c;j++) m[n][j]=v[n]; for(inti=n-1;i>1;i--) { jMax=min(w[i]-1,c); for(intj=0;j<=jMax;j++) m[i][j]=m[i+1][j]; for(intj=w[i];j<=c;j++) m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]); } m[1][c]=m[2][c]; if(c>=w[1]) m[1][c]=max(m[1][c],m[2][c-w[1]]+v[1]); } //找出最优解,0表示不能装,1表示能装 voidtraceback(int**m,intn,intc,int*x,int*w) { for(inti=1;i { if(m[i][c]==m[i+1][c])x[i]=0; else { x[i]=1; c-=w[i]; } } x[n]=(m[n][c]==0)? 0: 1; } intmain() { int*v=newint[N+1]; int*w=newint[N+1]; int**m=newint*[N+1]; int*x=newint[N+1]; for(inti=0;i { m[i]=newint[C+1]; } cout<<"输入重量序列,"< for(inti=1;i<=N;i++) cin>>w[i]; cout<<"输入价值序列,"< for(inti=1;i<=N;i++) cin>>v[i]; knapsack(m,N,C,w,v); traceback(m,N,C,x,w); cout<<"最优值: "< cout<<"是否装入背包的情况: "; for(inti=1;i<=N;i++) { cout< } for(inti=0;i { deletem[i]; } delete[]m; return0; } 运行结果 7、最优二叉搜索树 #include #include #include #defineN100 usingnamespacestd; constdoubleMAX=numeric_limits : max();//double的最大值 //a[i]为结点i被访问的概率 //b[i]为“虚结点”i被访问的概率 //m[i][j]用来存放子树(i,j)的期望代价 //w[i][j]用来存放子树(i,j)的所有结点(包括虚结点)的a,b概率之和 //s[i][j]用来跟踪root的 voidOptimalBinarySearchTree(double*a,double*b,intn) { ints[N][N]; doublem[N][N]; doublew[N][N]; inti,j,l,r; for(i=1;i<=n+1;i++) { m[i][i-1]=b[i-1]; w[i][i-1]=b[i-1]; } for(l=1;l<=n;l++) { for(i=1;i<=n-l+1;i++) { j=l+i-1; m[i][j]=MAX; w[i][j]=w[i][j-1]+a[j]+b[j]; for(r=i;r<=j;r++) { doublek=m[i][r-1]+w[i][j]+m[r+1][j]; if(k { m[i][j]=k; s[i][j]=k; } } } } cout< } intmain() { doublea[N],b[N]; intn; doublesum=0; inti,j,l;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态 规划 算法 实验 报告 材料
![提示](https://static.bdocx.com/images/bang_tan.gif)