实验4 贪心算法解决背包问题.docx
- 文档编号:5640291
- 上传时间:2022-12-29
- 格式:DOCX
- 页数:32
- 大小:1.36MB
实验4 贪心算法解决背包问题.docx
《实验4 贪心算法解决背包问题.docx》由会员分享,可在线阅读,更多相关《实验4 贪心算法解决背包问题.docx(32页珍藏版)》请在冰豆网上搜索。
实验4贪心算法解决背包问题
算法分析与设计实验报告
第4次实验
姓名
学号
班级
时间
11.15上午
地点
工训楼309
实验名称
利用贪心算法解决背包问题
实验目的
通过上机实验,要求掌握贪心算法解决问题,以及背包问题的解决。
实验原理
使用动态规划法,根据不同的随机数规模和数量,能准确的输出背包问题得到的结果,并计算出程序运行所需要的时间。
加最少的重量得到更大的价值,也就是说,尽量让单位重量价值更大的物品尽可能多的装入背包中。
实验步骤
①先输入背包容量和物品数量;
②输入每个背包重量和背包价值的随机数组范围;
③产生2个随机数组;
④计时开始,调用主要算法函数;
⑤输出背包问题最优解,输出算法花费的时间。
关键代码
voidsort(goodinfogoods[],intn)
{
inti,j;
for(j=2;j<=n;j++)
{
goods[0]=goods[j];
i=j-1;
while(goods[0].p/goods[0].w>goods[i].p/goods[i].w)
{
goods[i+1]=goods[i];
i--;
}
goods[i+1]=goods[0];
}
}//按物品效益,重量比值做升序排列
voidKnapsack(goodinfogoods[],floatM,intn)
{
floatcu;
inti,j;
floatvalue=0;
for(i=1;i<=n;i++)
goods[i].X=0;
cu=M;//背包剩余容量
for(i=1;i<=n;i++)
{
if(goods[i].w>cu)//当该物品重量大与剩余容量跳出
break;
goods[i].X=1;
cu-=goods[i].w;//确定背包新的剩余容量
}
if(i<=n)
goods[i].X=cu/goods[i].w;//剩下部分可以放的东西
//按物品编号做降序排列
for(j=2;j<=n;j++)
{
goods[0]=goods[j];
i=j-1;
while(goods[0].flag { goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } cout<<"最优解为: (下面括号外为物品的编号,括号内为物品放入背包的百分比)"< cout<<"第"; for(i=1;i<=n;i++) { if(goods[i].X! =0) { cout< if(goods[i].X==1)value+=goods[i].p; elsevalue+=goods[i].p*goods[i].X; } } cout<<"件物品要放"< cout<<"最优值为: "< } 测试结果 只改变背包的最大容量: 加入了计算最优值的过程: 只改变可选物品的总重量: 仅改变物品价值范围: 仅改变物品的质量范围: 中型数据的测试: 大型数据的测试: 超大型数据: (由于数据太多无法一一截屏,只截了最优解的,开始编程的时候没有考虑到大型数据的格式问题,所以显示不是很工整) 加了计算最优值的过程: 实验心得 1、其他数据不变,只改变背包的最大容量的时候,随着背包的容量增长运行的时间也在部分上涨 2、只改变可选物品的总数的时候,发现算法并没有按照预期的那样随着物品数量的增长运行时间也在线性增长,有时候物品数量多的那个算法运行的时间反而还短一点,得出结论是在大体范围内算法耗时是随着物品数量的增长而增长,局部数据会有波动; 3、只改变物品的价值的时候,发现这个数据对算法的运行时间基本没有影响,当物品价值变化很大的时候,算法运行时间也没有太大的波动或者根本不变甚至还有运行时间变回0的; 4、同样在改变物品的重量范围的时候,发现重量范围对算法运行的时间也是没有影响的,基本上都维持在0.016的这个范围内 5、上面的测试都是在小型范围的数据内测试得到的结果,现在我们测试中型数据和大型数据: 中型数据好大型数据的测试中发现,增加了背包的容量和物品的数量以后,算法的运行时间明显增加, 6、以上5点得到一个结论,物品的数量和背包容量是影响算法运行时间的主要因素,小型数据范围内不会波动很大,当数据量达到中型,大型,更大型上万的数量级的时候,发现算法运行的时间就越来越长。 7、刚开始测试数据的时候发现了一个问题,就是程序里面取了两次随机数,可是只要物品价值和重量的取值一样时,每次运行得到的随机数就是完全一样的,就算不一样,两次的随机数之间也是有魔种规律或者给我的感觉就是可能是程序的随机数种子是一样的,经过一晚上的猜测,终于找到问题所在,原来是 srand((unsigned)time(NULL));这句语句我输入了两次,分别在输出物品价值和物品重量的前面取了两次随机数种子,但是随机数的种子可能是一个线性存储空间,所有的种子顺序存储同样的随机数种子,所以如果取了两次随机数种子就会得到同样的种子,导致得到两次随机数完全一样,把其中的一个取随机数种子的语句去掉以后就得到了不一样的随机数了。 通过这次实验,我理解了动态规划法的实现。 明白了背包问题的解法,更理解了程序,同时也知道了一些背包问题在实际生活中的运用。 可以比较在同样数据规模的情况下,不加入随机化过程和加入随机化过程的运行时间。 加入随机化过程应该能大大提高速度,同时也方便了使用者,减少了手工输入的麻烦。 同时解决这个问题的过程中我用了很长时间去看书和理解,觉得比第一次的实验难很多,需要自己动脑。 第二天想起来没有加入最优值的计算过程,于是写完报告以后才加的,在以上截图中提供了加了计算最优值的算法和没有加之前的时间对比,发现运行时间会有一点点增加,小型数据的改变也就是两位数或者一位数以内的改变对算法的运行时间不会有太大的变化: 补充截图如下: 改变物品总数量: 改变背包的最大容量: 同时改变两个变量: 超大型数据: …………… 十倍的数据算法运行的时间远远大于十倍的时间。 实验得分 助教签名 附录: 完整代码 #include #include #include #include usingnamespacestd; structgoodinfo { floatp;//物品价值 floatw;//物品重量 floatX;//物品该放的数量 intflag;//物品编号 };//物品信息结构体 voidsort(goodinfogoods[],intn) { inti,j; for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while(goods[0].p/goods[0].w>goods[i].p/goods[i].w) { goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } }//按物品效益,重量比值做升序排列 voidKnapsack(goodinfogoods[],floatM,intn) { floatcu; inti,j; floatvalue=0; for(i=1;i<=n;i++) goods[i].X=0; cu=M;//背包剩余容量 for(i=1;i<=n;i++) { if(goods[i].w>cu)//当该物品重量大与剩余容量跳出 break; goods[i].X=1; cu-=goods[i].w;//确定背包新的剩余容量 } if(i<=n) goods[i].X=cu/goods[i].w;//剩下部分可以放的东西 //按物品编号做降序排列 for(j=2;j<=n;j++) { goods[0]=goods[j]; i=j-1; while(goods[0].flag { goods[i+1]=goods[i]; i--; } goods[i+1]=goods[0]; } cout<<"最优解为: (下面括号外为物品的编号,括号内为物品放入背包的百分比)"< cout<<"第"; for(i=1;i<=n;i++) { if(goods[i].X! =0) { cout< if(goods[i].X==1)value+=goods[i].p; elsevalue+=goods[i].p*goods[i].X; } } cout<<"件物品要放"< cout<<"最优值为: "< } intmain(void) { inti,j,n; floatM; goodinfo*goods;//定义一个指针 cout<<"请输入是否进入算法(0表示退出,其他数字表示进入): "< cin>>j; while(j) { cout<<"请输入物品的总数量&背包的最大容量: "; cin>>n>>M; goods=newstructgoodinfo[n+1]; inta,b;//a是物品价值的范围,b是物品质量的范围 cout<<"请输入物品价值的范围和物品质量的范围: "; cin>>a>>b; for(i=1;i<=n;i++) { goods[i].flag=i; } srand((unsigned)time(NULL)); cout<<"随机物品的价值分别为: "; for(i=1;i<=n;i++) { goods[i].p=(rand()%(a)+1); cout< } cout< cout<<"随机物品的重量分别为: "; for(j=1;j<=n;j++) { goods[j].w=(rand()%(b)+1); cout< } cout< //开始计时 clock_tstart,end,over; start=clock(); end=clock(); over=end-start; start=clock();//开启时钟 sort(goods,n); Knapsack(goods,M,n); end=clock();//关闭时钟 printf("Thetimeis%6.3f",(double)(end-start-over)/CLK_TCK); cout< cout< } system("pause"); return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验4 贪心算法解决背包问题 实验 贪心 算法 解决 背包 问题