算法分析与设计实验报告.docx
- 文档编号:8786378
- 上传时间:2023-02-01
- 格式:DOCX
- 页数:27
- 大小:47.17KB
算法分析与设计实验报告.docx
《算法分析与设计实验报告.docx》由会员分享,可在线阅读,更多相关《算法分析与设计实验报告.docx(27页珍藏版)》请在冰豆网上搜索。
算法分析与设计实验报告
算法分析与设计
实验报告
班级:
学号:
姓名:
实验一算法实现一
一、实验目的与要求
熟悉C/C++语言的集成开发环境;
通过本实验加深对分治法、贪心算法的理解。
二、实验内容:
掌握分治法、贪心算法的概念和基本思想,并结合具体的问题学习如何用相应策略进行求解的方法。
三、实验题
1.【伪造硬币问题】给你一个装有n个硬币的袋子。
n个硬币中有一个是伪造的。
你的任务是找出这个伪造的硬币。
为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。
试用分治法的思想写出解决问题的算法,并计算其时间复杂度。
(1)源程序:
#include
#include
#include
intfindTheCoin(intq[],inta,intb);
intquantity(intq[],inta,intb);
voidmain()
{
time_tts;
srand((unsigned)time(&ts));
constintMax=70;
intn,k;
while(true)
{
cout<<"请输入硬币的个数"< cin>>n; intq[Max]; inti; for(i=1;i<=n;i++) { q[i]=2; } k=rand()%n; if(k==0) k=n; q[k]=1; cout<<"随机产生的硬币排列顺序"< for(i=1;i<=n;i++) { cout< if(i%5==0) cout< } cout< intp=findTheCoin(q,1,n); cout<<"伪造硬币的位置: "< cout<<"======================="< } } intquantity(intq[],inta,intb) { inttotal=0; inti; for(i=a;i<=b;i++) total+=q[i]; returntotal; } intfindTheCoin(intq[],inta,intb) { if(a==b) returna; intn=b-a+1; intc=n%3; intm=a+n/3-1; intd; switch(c) { case0: if(quantity(q,a,m)==quantity(q,m+1,m+n/3)) { d=findTheCoin(q,m+n/3+1,m+2*(n/3)); returnd; } elseif(quantity(q,a,m)==quantity(q,m+n/3+1,m+2*(n/3))) { d=findTheCoin(q,m+1,m+n/3); returnd; } else { d=findTheCoin(q,a,m); returnd; } //break; case1: if((quantity(q,a,m)==quantity(q,m+1,m+n/3))&&(quantity(q,m+n/3+1,m+2*(n/3))==quantity(q,m+1,m+n/3))) returnm+2*(n/3)+1; else { if(quantity(q,a,m)==quantity(q,m+1,m+n/3)) { d=findTheCoin(q,m+n/3+1,m+2*(n/3)); returnd; } elseif(quantity(q,a,m)==quantity(q,m+n/3+1,m+2*(n/3))) { d=findTheCoin(q,m+1,m+n/3); returnd; } else { d=findTheCoin(q,a,m); returnd; } } //break; case2: if(q[m+2*(n/3)+1]==q[m+2*(n/3)+2]) { if(quantity(q,a,m)==quantity(q,m+1,m+n/3)) { d=findTheCoin(q,m+n/3+1,m+2*(n/3)); returnd; } elseif(quantity(q,a,m)==quantity(q,m+n/3+1,m+2*(n/3))) { d=findTheCoin(q,m+1,m+n/3); returnd; } else { d=findTheCoin(q,a,m); returnd; } } else { if(q[m+2*(n/3)+2]==q[1]) returnm+2*(n/3)+1; //cout<<"伪造硬币的号码是"<<3*m+1< else returnm+2*(n/3)+2; //cout<<"伪造硬币的号码是"<<3*m+2< } } //returntrue; } (2)运行结果 2.【找零钱问题】一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。 售货员希望用数目最少的硬币找给小孩。 假设提供了数目有限的面值为25美分、10美分、5美分、及1美分的硬币。 给出一种找零钱的贪心算法。 (1)源程序: #include #include intmakeChange(intmoney,intcoin25,intcoin10,intcoin5,intcoin1) { inti=0,j=0; while(money) { if(money>=25) { i=money/25; if(i<=coin25) { money=money-25*i; j+=i; cout<<"需要25美分"< "< } else { money=money-25*coin25; j+=coin25; cout<<"需要25美分"< "< } } if(money>=10) { i=money/10; if(i<=coin10) { money=money-10*i; j+=i; cout<<"需要10美分"< "< } else { money=money-10*coin10; j+=coin10; cout<<"需要10美分"< "< } } if(money>=5) { i=money/5; if(i<=coin5) { money=money-5*i; j+=i; cout<<"需要5美分"< "< } else { money=money-5*coin5; j+=coin5; cout<<"需要5美分"< "< } } if(money>=1) { i=money/1; if(i<=coin1) { money=money-1*i; j+=i; cout<<"需要1美分"< "< } else { cout<<"! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! "< cout<<"! 零钱不够,无法找零! ! "< cout<<"! 请退出后重新操作! ! "< cout<<"! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! "< return0; } } } cout<<"共需要"< "< return1; } voidmain() { intmoney,smoney,ymoney; intcoin25,coin10,coin5,coin1; cout<<"欢迎使用,按0可退出! "< cout<<"请输入各面值硬币的个数: "< cout<<"25美分个数: "; cin>>coin25; cout<<"10美分个数: "; cin>>coin10; cout<<"5美分个数: "; cin>>coin5; cout<<"1美分个数: "; cin>>coin1; while(true) { cout<<"应收: "; cin>>ymoney; if(ymoney==0) break; cout<<"实收: "; cin>>smoney; money=smoney-ymoney; cout<<"您要找"< "< if(money==0) continue; makeChange(money,coin25,coin10,coin5,coin1); cout<<"==========================="< } } (2)运行结果 四、实验步骤 理解算法思想和问题要求; 编程实现题目要求; 上机输入和调试自己所编的程序; 验证分析实验结果; 整理出实验报告。 五、实验感想 找零钱问题生活中也很常见,问题也很简单,所以变成没有费很大力气。 伪造硬币问题因为涉及到函数的递归调用,所以在编程时在递归调用函数时结果的返回出了许多错误,先检查了自己的算法,弄清思路是没有问题的,可能在写程序时犯了一些逻辑错误,后来经过一组测试数据,自己在纸上模拟程序单步执行,终于找到了自己犯得错误,问题迎刃而解。 实验二算法实现二 一、实验目的与要求 熟悉C/C++语言的集成开发环境; 通过本实验加深对贪心算法、动态规划和回溯算法的理解。 二、实验内容: 掌握贪心算法、动态规划和回溯算法的概念和基本思想,分析并掌握"0-1"背包问题的三种算法,并分析其优缺点。 三、实验题 1."0-1"背包问题的贪心算法 (1)源程序 #include #definemax100 voidsort(intn,floata[max],floatb[max]) { intj,h,k; floatt1,t2,t3,c[max]; for(k=1;k<=n;k++) c[k]=a[k]/b[k]; for(h=1;h for(j=1;j<=n-h;j++) if(c[j] { t1=a[j];a[j]=a[j+1];a[j+1]=t1; t2=b[j];b[j]=b[j+1];b[j+1]=t2; t3=c[j];c[j]=c[j+1];c[j+1]=t3; } } voidknapsack(intn,floatlimitw,floatv[max],floatw[max],intx[max]) { floatc1; inti; sort(n,v,w); cout<<"货物按价值密度排序后为: "< cout<<"价值: "; for(i=1;i<=n;i++) { cout< } cout< "; for(i=1;i<=n;i++) { cout< } c1=limitw; for(i=1;i<=n;i++) { if(w[i]>c1) continue; x[i]=1; c1=c1-w[i]; } } voidmain() { intn,i,x[max]; floatv[max],w[max],totalv=0,totalw=0,limitw; while(true) { cout<<"请输入货物数量: "< cin>>n; cout<<"背包最大载重: "< cin>>limitw; for(i=1;i<=n;i++) x[i]=0; cout<<"请依次输入物品的价值: "< for(i=1;i<=n;i++) cin>>v[i]; cout<<"请依次输入物品的重量: "< for(i=1;i<=n;i++) cin>>w[i]; knapsack(n,limitw,v,w,x); cout< "; for(i=1;i<=n;i++) { cout< if(x[i]==1) { totalw=totalw+w[i]; totalv=totalv+v[i]; } } cout< cout<<"背包的总重量为: "< cout<<"背包的总价值为: "< cout<<"============================="< } } (2)运行结果 2."0-1"背包问题的动态规划算法 (1)源程序 #include intc[10][100]; intknapsack(intwmax,intn) { inti,j,w[10],p[10]; cout<<"请输入每个物品的重量: "< for(i=1;i<=n;i++) cin>>w[i]; cout<<"请输入每个物品的价值: "< for(i=1;i<=n;i++) cin>>p[i]; for(i=0;i<10;i++) { for(j=0;j<100;j++) c[i][j]=0; } for(i=1;i<=n;i++) { for(j=1;j<=wmax;j++) { if(w[i]<=j) { if(p[i]+c[i-1][j-w[i]]>c[i-1][j]) c[i][j]=p[i]+c[i-1][j-w[i]]; else c[i][j]=c[i-1][j]; } else c[i][j]=c[i-1][j]; } } return(c[n][wmax]); } intmain() { intwmax,n,i,j; cout<<"请输入背包的载重: "< cin>>wmax; cout<<"请输入货物数量: "< cin>>n; cout<<"装载的最大价值为: "< return0; } (2)运行结果 3."0-1"背包问题的回溯算法 (1)源程序 #include usingnamespacestd; classKnap { friendintKnapsack(intp[],intw[],intc,intn); public: voidprint() { for(intm=1;m<=n;m++) cout< cout< }; private: intBound(inti); voidBacktrack(inti); intc;//背包容量 intn;//物品数 int*w;//物品重量数组 int*p;//物品价值数组 intcw;//当前重量 intcp;//当前价值 intbestp;//当前最优值 int*bestx;//当前最优解 int*x;//当前解 }; intKnap: : Bound(inti) {//计算上界 intcleft=c-cw;//剩余容量 intb=cp;//以物品单位重量价值递减序装入物品 while(i<=n&&w[i]<=cleft) { cleft-=w[i]; b+=p[i]; i++; }//装满背包 if(i<=n) b+=p[i]/w[i]*cleft; returnb; } voidKnap: : Backtrack(inti) { if(i>n) { if(bestp { for(intj=1;j<=n;j++) bestx[j]=x[j]; bestp=cp; } return; } if(cw+w[i]<=c)//搜索左子树 { x[i]=1; cw+=w[i]; cp+=p[i]; Backtrack(i+1); cw-=w[i]; cp-=p[i]; } if(Bound(i+1)>bestp)//搜索右子树 { x[i]=0; Backtrack(i+1); } } classObject { friendintKnapsack(intp[],intw[],intc,intn); public: intoperator<=(Objecta)const { return(d>=a.d); } private: intID; floatd; }; intKnapsack(intp[],intw[],intc,intn) {//为Knap: : Backtrack初始化 intW=0; intP=0; inti=1; Object*Q=newObject[n]; for(i=1;i<=n;i++) { Q[i-1].ID=i; Q[i-1].d=1.0*p[i]/w[i]; P+=p[i]; W+=w[i]; } if(W<=c) returnP;//装入所有物品 //依物品单位重量排序 floatf; for(i=0;i for(intj=i;j { if(Q[i].d { f=Q[i].d; Q[i].d=Q[j].d; Q[j].d=f; } } KnapK; K.p=newint[n+1]; K.w=newint[n+1]; K.x=newint[n+1]; K.bestx=newint[n+1]; K.x[0]=0; K.bestx[0]=0; for(i=1;i<=n;i++) { K.p[i]=p[Q[i-1].ID]; K.w[i]=w[Q[i-1].ID]; } K.cp=0; K.cw=0; K.c=c; K.n=n; K.bestp=0;//回溯搜索 K.Backtrack (1); K.print(); delete[]Q; delete[]K.w; delete[]K.p; returnK.bestp; } voidmain() { int*p; int*w; intc=0; intn=0; inti=0; //chark; while(true) { cout<<"请输入背包容量: "< cin>>c; cout<<"请输入物品的个数: "< cin>>n; p=newint[n+1]; w=newint[n+1]; p[0]=0; w[0]=0; cout<<"请输入物品的价值: "< for(i=1;i<=n;i++) cin>>p[i]; cout<<"请输入物品的重量: "< for(i=1;i<=n;i++) cin>>w[i]; cout<<"最优解为: "< //cout<<"最优值为(bestp): "< cout< cout<<"=========================="< //cout<<"[s]重新开始"< //cout<<"[q]退出"< //cin>>k; } } (2)运行结果 四、实验步骤 理解算法思想和问题要求; 编程实现题目要求; 上机输入和调试自己所编的程序; 验证分析实验结果; 整理出实验报告。 五、实验感想 贪心算法只考虑眼前的利益而不考虑长远利益,得到的可能不是最优解,所以编程时一步
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 分析 设计 实验 报告