算法分析实验报告3.docx
- 文档编号:25407860
- 上传时间:2023-06-08
- 格式:DOCX
- 页数:16
- 大小:52.59KB
算法分析实验报告3.docx
《算法分析实验报告3.docx》由会员分享,可在线阅读,更多相关《算法分析实验报告3.docx(16页珍藏版)》请在冰豆网上搜索。
算法分析实验报告3
兰州交通大学
《算法设计与分析》
实验报告3
题目
03-动态规划
专业
计算机科学与技术
班级
计算机科学与技术2016-02班
学号
201610333
姓名
石博洋
第3章动态规划
1.实验题目与环境
1.1实验题目及要求
(1)用代码实现矩阵连乘问题。
给定n个矩阵{A1,A2,…,An},其中Ai与Ai+1是可乘的,i=1,2,…,n-1。
考察这n个矩阵的连乘积A1A2…An。
由于矩阵乘法满足结合律,故计算矩阵的连乘积可以有许多不同的计算次序,这种计算次序可以用加括号的方式来确定。
若一个矩阵连乘积的计算次序完全确定,则可以依此次序反复调用2个矩阵相乘的标准算法(有改进的方法,这里不考虑)计算出矩阵连乘积。
确定一个计算顺序,使得需要的乘的次数最少。
(2)用代码实现最长公共子序列问题。
一个给定序列的子序列是在该序列中删去若干元素后得到的序列。
确切地说,若给定序列X=
例如,序列Z=是序列X=的子序列,相应的递增下标序列为<2,3,5,7>。
给定两个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。
例如,若X=和Y=,则序列是X和Y的一个公共子序列,序列也是X和Y的一个公共子序列。
而且,后者是X和Y的一个最长公共子序列,因为X和Y没有长度大于4的公共子序列。
(3)0-1背包问题。
现有n种物品,对1<=i<=n,已知第i种物品的重量为正整数Wi,价值为正整数Vi,背包能承受的最大载重量为正整数W,现要求找出这n种物品的一个子集,使得子集中物品的总重量不超过W且总价值尽量大。
(注意:
这里对每种物品或者全取或者一点都不取,不允许只取一部分)
使用动态规划使得装入背包的物品价值之和最大。
1.2实验环境:
CPU:
Intel(R)Core(TM)i3-21203.3GHZ
内存:
12GB
操作系统:
Windows7.1X64
编译环境:
MircosoftVisualC++6
2.问题分析
(1)分析。
由于矩阵乘法满足结合律,所以计算矩阵连乘的连乘积可以与许多不同的计算计算次序,这种计算次序可以用加括号的方式来确定。
若一个矩阵连乘积的计算次序完全确定,也就是说连乘积已完全加括号,那么可以依此次序反复调用2个矩阵相乘的标准算法计算出矩阵连乘积。
完全加括号的矩阵连乘积可递归地定义为:
(1).单个矩阵是完全加括号的;
(2).矩阵连乘积A是完全加括号的,则A可以表示为2个完全加括号的矩阵连乘积B和C的乘积并加括号,及A=(BC);
举个例子,矩阵连乘积A1A2A3A4A5,可以有5种不同的完全加括号方式:
(A1(A2(A3A4))),(A1((A2A3)A4)),((A1A2)(A3A4)),((A1(A2A3))A4),(((A1A2)A3)A4)
每一种完全加括号的方式对应一种矩阵连乘积的计算次序,而矩阵连乘积的计算次序与其计算量有密切的关系,即与矩阵的行和列有关。
补充一下数学知识,矩阵A与矩阵B可乘的条件为矩阵A的列数等于矩阵B的行数,例如,若A是一个p*q的矩阵,B是一个q*r的矩阵,则其乘积C=AB是一个p*r的矩阵。
(2)分析。
设X={A,B,C,B,D,A,B},Y={B,D,C,A,B,A}。
求X,Y的最长公共子序列最容易想到的方法是穷举法。
对X的多有子序列,检查它是否也是Y的子序列,从而确定它是否为X和Y的公共子序列。
由集合的性质知,元素为m的集合共有2^m个不同子序列,因此,穷举法需要指数级别的运算时间。
进一步分解问题特性,最长公共子序列问题实际上具有最优子结构性质。
设序列X={x1,x2,……xm}和Y={y1,y2,……yn}的最长公共子序列为Z={z1,z2,……zk}。
则有:
(1)若xm=yn,则zk=xm=yn,且zk-1是Xm-1和Yn-1的最长公共子序列。
(2)若xm!
=yn且zk!
=xm,则Z是Xm-1和Y的最长公共子序列。
(3)若xm!
=yn且zk!
=yn,则Z是X和Yn-1的最长公共子序列。
其中,Xm-1={x1,x2……xm-1},Yn-1={y1,y2……yn-1},Zk-1={z1,z2……zk-1}。
(3)分析。
动态规划算法的基本思想是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。
但是经分解得到的子问题往往不是互相独立的。
不同子问题的数目常常只有多项式量级。
如果能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,就可以避免大量重复计算,从而得到多项式时间算法。
它把已知问题分为很多子问题,按顺序求解子问题,在每一种情况下,列出各种情况的局部解,按条件从中选取那些最有可能产生最佳的结果舍弃其余。
前一子问题为后面子问题提供信息,而减少计算量,最后一个子问题的解即为问题解。
采用此方法求解0-1背包问题的主要步骤如下:
①分析最优解的结构:
最有子结构性质;
②建立递归方程;
③计算最优值;
④构造最优解。
3.设计过程
(1)代码
#include"pch.h"
#include
#include
usingnamespacestd;
structSIGN{
intnum;//加括号的个数
}l[100+5],r[100+5];//l为左括号,r为右括号
//矩阵的个数
intn;
//矩阵的维数第i个矩形的维数为p[i*2]和p[i*2+1]
intp[200+5];
//m[i][j]表示当前i到j最少的计算次数
intm[100+5][100+5];
//s[i][j]表示当前i到j最少计算次数需要断开的位置s[i][j]
ints[100+5][100+5];
//x[i]表示第i个矩阵要加括号的个数
voidMatrixChain()
{
memset(m,0,sizeof(m));
//当前矩阵的长度
for(intr=2;r<=n;r++)
{
//矩阵的起始位置
for(inti=1;i<=n-r+1;i++)
{
//矩阵的结束位置(矩阵开始+矩阵长度-1)
intj=i+r-1;
if(i>n||j>n)continue;
//m[i][j]初值
m[i][j]=m[i+1][j]+p[2*i]*p[2*i+1]*p[2*j+1];
//记录当前s[i][j]的最优断开位置
s[i][j]=i;
//循环找i,j之间的最优断点k
for(intk=i+1;k { intt=m[i][k]+m[k+1][j]+p[i*2]*p[k*2+1]*p[j*2+1]; if(t { //更新i到j的最优解 m[i][j]=t; //更新当前s[i][j]的最优断开位置 s[i][j]=k; } } //cout< } } } //加括号 voidTraceback(inti,intj) { if(i==j)return; Traceback(i,s[i][j]); Traceback(s[i][j]+1,j); cout<<"MultiplyA("< cout<<")andA("<<(s[i][j]+1)<<","< l[i].num++; r[j].num++; } //输出括号 voiddealSign() { cout<<"计算次序: "; //加括号 for(inti=1;i<=n;i++) { intleftCount=l[i].num; intrightCount=r[i].num; //先输出左括号再输出当前矩阵最后输出右括号 for(intj=0;j { cout<<"("; } cout< for(intk=0;k { cout<<")"; } } cout<<"\n"; } intmain() { cout<<"请输入矩阵的个数: "; cin>>n; cout<<"请输入各矩阵的维数,空格分开"< for(inti=1;i<=n;i++) { cin>>p[i*2]; cin>>p[i*2+1]; } MatrixChain(); //输出1到n的最优结果 cout<<"最小计算次数为: "< memset(l,0,sizeof(l)); memset(r,0,sizeof(r)); Traceback(1,n); dealSign(); return0; } (2)代码 #include"pch.h" #include usingnamespacestd; constintM=7; constintN=6; voidoutput(char*s,intn); voidLCSLength(intm,intn,char*x,char*y,int**c); voidLCS(inti,intj,char*x,int**c); intmain() { //X={A,B,C,E,F,B,A} //Y={B,D,E,F,B,A} charx[]={'','A','B','C','E','F','B','A',}; chary[]={'','B','D','E','F','B','A'}; int**c=newint*[M+1]; for(inti=0;i<=M;i++) { c[i]=newint[N+1]; } cout<<"序列X: "< output(x,M); cout<<"序列Y: "< output(y,N); LCSLength(M,N,x,y,c); cout<<"序列X、Y最长公共子序列长度为: "< cout<<"序列X、Y最长公共子序列为: "< LCS(M,N,x,c); cout< } voidoutput(char*s,intn) { for(inti=1;i<=n;i++) { cout< } cout< } voidLCSLength(intm,intn,char*x,char*y,int**c) { inti,j; for(i=1;i<=m;i++) c[i][0]=0; for(i=1;i<=n;i++) c[0][i]=0; for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { if(x[i]==y[j]) { c[i][j]=c[i-1][j-1]+1; } elseif(c[i-1][j]>=c[i][j-1]) { c[i][j]=c[i-1][j]; } else { c[i][j]=c[i][j-1]; } } } } voidLCS(inti,intj,char*x,int**c) { if(i==0||j==0) { return; } if(c[i][j]==c[i-1][j-1]+1) { LCS(i-1,j-1,x,c); cout< } elseif(c[i-1][j]>=c[i][j-1]) { LCS(i-1,j,x,c); } else { LCS(i,j-1,x,c); } } (3)代码。 #include"pch.h" #include #include #include #include usingnamespacestd; constintMAX=1000; intw[MAX],v[MAX],best[MAX]; intV[MAX][MAX];//最大价值矩阵 intW,n;//W为背包的最大载重量,n为物品的数量 //求最大值函数 intmax1(intx,inty) { returnx>=y? x: y; } //求最小值函数 intmin1(intx,inty) { returnx>=y? y: x; } voidKnaspack() { intMax=min(w[n]-1,W); for(intj=1;j<=Max;j++) V[n][j]=0; for(intj=w[n];j<=W;j++) V[n][j]=v[n]; for(inti=n-1;i>1;i--) { Max=min(w[i]-1,W); for(intj=1;j<=Max;j++) V[i][j]=V[i+1][j]; for(intj=w[i];j<=W;j++) V[i][j]=max(V[i+1][j],V[i+1][j-w[i]]+v[i]); } V[1][W]=V[2][W];//先假设第一个物品不放入 if(W>w[1]) V[1][W]=max(V[1][W],V[2][W-w[1]]+v[1]); } //生成向量数组,决定某一个物品是否应该放入背包 voidTraceback() { for(inti=1;i { if(V[i][W]==V[i+1][W])//如果当前行的最优值与下一行的最优值相等,则表明该物品不能放入。 best[i]=0; else//否则可以放入 { best[i]=1; W-=w[i]; } } best[n]=(V[n][W])? 1: 0; } voidmain() { LARGE_INTEGERbegin,end,frequency; QueryPerformanceFrequency(&frequency); srand(time(0)); cout<<"输入商品数量n和背包容量W: "; cin>>n>>W; for(inti=1;i<=n;i++) { w[i]=rand()%1000; v[i]=rand()%1000; } cout<<"商品的重量和价值如下: "< for(inti=1;i<=n;i++) { cout< cout< } QueryPerformanceCounter(&begin); Knaspack();//构造矩阵 Traceback();//求出解的向量数组 QueryPerformanceCounter(&end); inttotalW=0; inttotalV=0; //显示可以放入的物品 cout<<"所选择的商品如下: "< cout<<"序号i: \t重量w: \t价格v: \t"< for(inti=1;i<=n;i++) { if(best[i]==1) { totalW+=w[i]; totalV+=v[i]; cout< : left)< } } cout<<"放入背包的物品总重量为: "< "<<""< cout<<"时间: " <<(double)(end.QuadPart-begin.QuadPart)/frequency.QuadPart <<"s"< } 4.结果展示 (1) (2) (3)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 分析 实验 报告