已阅读5页,还剩5页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
基于贪心法的装箱问题【问题】装箱问题问题描述:有一个箱子容量为V(正整数,0V20000),同时有n个物品(0n30),每个物品有一个体积(正整数)。要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。 【算法设计的思想】贪心法是求解关于独立系统组合优化问题的一种简单算法,求最小生成树的Kruskal算法就是一种贪心算法。贪心法的基本思路是:从问题的某一个初始解出发逐步逼近给定的目标,以尽可能快的地求得更好的解。当达到某算法中的某一步不能再继续前进时,算法停止。 该算法存在问题: 1. 不能保证求得的最后解是最佳的; 2. 不能用来求最大或最小解问题; 3. 只能求满足某些约束条件的可行解的范围。贪婪法是一种不追求最优解,只希望得到较为满意解的方法。贪婪法一般可以快速得到满意的解,因为它省去了为找最优解要穷尽所有可能而必须耗费的大量时间。贪婪法常以当前情况为基础作最优选择,而不考虑各种可能的整体情况,所以贪婪法不要回溯。 例如平时购物找钱时,为使找回的零钱的硬币数最少,不考虑找零钱的所有各种发表方案,而是从最大面值的币种开始,按递减的顺序考虑各币种,先尽量用大面值的币种,当不足大面值币种的金额时才去考虑下一种较小面值的币种。这就是在使用贪婪法。这种方法在这里总是最优,是因为银行对其发行的硬币种类和硬币面值的巧妙安排。如只有面值分别为1、5和11单位的硬币,而希望找回总额为15单位的硬币。按贪婪算法,应找1个11单位面值的硬币和4个1单位面值的硬币,共找回5个硬币。但最优的解应是3个5单位面值的硬币。若考察将n种物品的集合分划成n个或小于n个物品的所有子集,最优解就可以找到。但所有可能划分的总数太大。对适当大的n,找出所有可能的划分要花费的时间是无法承受的。为此,对装箱问题采用非常简单的近似算法,即贪婪法。该算法依次将物品放到它第一个能放进去的箱子中,该算法虽不能保证找到最优解,但还是能找到非常好的解。不失一般性,设n件物品的体积是按从大到小排好序的,即有v0v1vn-1。如不满足上述要求,只要先对这n件物品按它们的体积从大到小排序,然后按排序结果对物品重新编号即可。【算法的流程图】输入箱子的容积输入物品总数N输入各物品体积预置已用箱子链为空预置已用箱子计数器box_count为0开始i=0;in;i+。从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j已用箱子能不能再放物品i已用箱子都不能再放物品i,另用一个箱子j,并将物品i放入该箱子,box_count+否则,将物品i放入箱子j【算法设计的思想】装箱算法简单描述如下: 输入箱子的容积; 输入物品种数n; 按体积从大到小顺序,输入各物品的体积; 预置已用箱子链为空; 预置已用箱子计数器box_count为0; for (i=0;in;i+) 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j; if (已用箱子都不能再放物品i) 另用一个箱子j,并将物品i放入该箱子; box_count+; else 将物品i放入箱子j; 上述算法能求出需要的箱子数box_count,并能求出各箱子所装物品。 若每只箱子所装物品用链表来表示,链表首结点指针存于一个结构中,结构记录尚剩余的空间量和该箱子所装物品链表的首指针。另将全部箱子的信息也构成链表。以下是按以上算法编写的程序。【程序】#include#includeusing namespace std;int v,n;int volume31;/存储n件物品的体积 int h20001;/hi=1,表示n件物品通过某种组合,所构成的体积和正和等于i; /hi=0,表示n件物品无论如何组合,体积和都无法等于i int main() freopen(in.txt,r,stdin); freopen(out.txt,w,stdout); int v,n,i,j,k; while(cinvn) for(i=1;ivolumei; memset(h,0,sizeof(h); h0=1; for(i=1;i=volumei;k-) hk=hk|hk-volumei; j=v; while(j0&hj=0) j-; coutv-jendl; return 0; 【运行结果分析】输入 24 一个整数,表示箱子容量 6 一个整数,表示有n个物品接下来n行,分别表示这n个物品的各自体积。 129 8 7 7 3输出:0 一个整数,表示箱子剩余空间 【算法设计分析】本题是经典问题:0-1背包的特殊例子(加强了已知条件)。用整形数组volume存储各件物品的体积,用布尔型函数h(i,k)表示前i个物品通过组合能否恰好装满容量k的空间,则考虑第i件物品,如果没有被选中,则问题转化为h(i-1,k);如果第i件物品被选中了,则问题转化为h(i-1,k-volumei),因此有如下的表达式:h(i,k)=h(i-1,k-volumei) | h(i-1,k); k从V开始递减,判断h(n,k)是否为真,第一个符号要求的k即为剩余空间最小时消耗的体积。 如果此时直接编写程序,就要定义一个二维数组,空间复杂度时n*v,注意到了n,v的取值范围很大,所以用二维数组存储就会有问题。 我们注意到,h(i,k)的取值仅与h(i-1,0)h(i-1,k)有关,且如果h(i-1,k)=true,必然有h(i,k)=true,h(i,k)的值存在继承性,而程序结束时,我们也只关心h(n,k),因此,我们可以用一维数组h(k)来存储中间信息。为了避免重复计算,可以让k从大到小变化,为了避免出现负数,k的变化范围为vvolumei.【收获体会】这个实验让我深刻理解了贪心法,贪心法顾名思义就是说要贪,要一点一点的贪,歇斯底里地贪,嚼字一点的讲,就是说求一个问题的最优解时,将这个问题肢解为一系列的局部性的问题,然后通过在每个局部得到最优以使得在全局得到最优.其实这点挺有意思的,整个计算机界每天都在叫着虚拟现实,为此做了很多的算法,大部分算法都比较贪,结果现实给我们虚拟出来了.当然,即使在现实世界里面贪也就不见得全是坏事,所以这么想来也只能说是现实世界是比较残酷的吧。 最后还要感谢一些同学对自己极大的帮助,还有老师课堂上对自己的授学。动态规划装箱问题(2012-05-06 09:16:33)转载标签:动态规划杂谈分类:算法设计装箱问题(pack.cpp)【问题描述】有一个箱子容量为V(正整数,0=V=20000),同时有n个物品(0n=30),每个物品有一个体积(正整数)。要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。【输入样例】2468312797【输出样例】0样例说明:24表示箱子容量6表示n个物品8n行,分别表示n个物品的体积312797方法一、使用二维数组fij,表示前i个物品装入容量为j的箱子能获得的最大体积,动态转移方程:fij=max(fi-1j,fi-1j-ai+ai);#include using namespace std;int f3120001;int main()freopen(pack.in,r,stdin);freopen(pack.out,w,stdout);int V,n,i,j;cinVn;int an+1;for(i=1;iai;for(i=1;i=n;i+)for(j=1;j=V;j+)if(jai)fij=fi-1j;elsefij=max(fi-1j,fi-1j-ai+ai);coutV-fnV;while(1);return 0;方法二、方法一虽好,但占用内存空间较大,改用一维数组fj:仍表示前i个物品装箱能获得的最大体积。#include using namespace std;int f20001;/fj表示前i个物品装入获得的最大体积int main()freopen(pack.in,r,stdin);freopen(pack.out,w,stdout);int V,n,i,j;cinVn;int an+1;for(i=1;iai;for(i=1;i=1;j-)if(jai) fj=max(fj-1,fj);/虽然fj总是大于fj-1,但这一句为什么不能少?else fj=max(fj,fj-ai+ai);coutV-fV;/while(1);return 0;方法三、#include using namespace std;ifstream fin(pack.in);ofstream fout(pack.out);int f20001;int main()int v,n,a31,i,j,d;finvn;for(i=1;iai;for(i=1;i0;j-)/j为剩余空间if(fj=1&j+ai0&fd!=1)d-;foutv-dendl;fin.close();fout.close();return 0;试问方法三中fj的含义是什么?装箱问题分类:算法与数据结构2006-06-20 14:451618人阅读评论(0)收藏举报存储算法 装箱问题问题描述有一个箱子容量为V(正整数,0V20000),同时有n个物品(0n30),每个物品有一个体积(正整数)。要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。样例输入: 24 一个整数,表示箱子容量 6 一个整数,表示有n个物品 8 接下来n行,分别表示这n个物品的各自体积。 3 12 7 9 7输出: 0 一个整数,表示箱子剩余空间算法分析:本题是经典问题:0-1背包的特殊例子(加强了已知条件)。用整形数组volume存储各件物品的体积,用布尔型函数h(i,k)表示前i个物品通过组合能否恰好装满容量k的空间,则考虑第i件物品,如果没有被选中,则问题转化为h(i-1,k);如果第i件物品被选中了,则问题转化为h(i-1,k-volumei),因此有如下的表达式:h(i,k)=h(i-1,k-volumei) | h(i-1,k); k从V开始递减,判断h(n,k)是否为真,第一个符号要求的k即为剩余空间最小时消耗的体积。 如果此时直接编写程序,就要定义一个二维数组,空间复杂度时n*v,注意到了n,v的取值范围很大,所以用二维数组存储就会有问题。 我们注意到,h(i,k)的取值仅与h(i-1,0)h(i-1,k)有关,且如果h(i-1,k)=true,必然有h(i,k)=true,h(i,k)的值存在继承性,而程序结束时,我们也只关心h(n,k),因此,我们可以用一维数组h(k)来存储中间信息。为了避免重复计算,可以让k从大到小变化,为了避免出现负数,k的变化范围为vvolumei.示例程序:#include#includeusing namespace std;int v,n;int volume31;/存储n件物品的体积int h20001;/hi=1,表示n件物品通过某种组合,所构成的体积和正和等于i; /hi=0,表示n件物品无
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026贵州贵阳观山湖人力资源服务有限公司教育教学人员招聘考试备考题库及答案解析
- 2026年镇江市丹徒区卫生健康系统人员招聘笔试备考试题及答案解析
- 宁波富甬集团有限公司2026年度第一期公开招聘工作人员10人笔试参考题库及答案详解
- 2026江西吉安市青原区睿才人力资源有限公司面向社会招聘项目制人员1人考试参考题库及答案解析
- 冒险力敢为人先-冒险精神教育培训
- 2026及未来5-10年快速凝结复合水泥项目投资价值市场数据分析报告
- 2025年矿山救援队员《矿山救援知识》真题及答案解析
- 产品推广策略市场测试报告模板
- 2026年注册土木工程师(水利水电)之专业知识通关练习题库包(黄金题型)附答案详解
- 2026年数据结构与算法智慧树网课章节题库【培优A卷】附答案详解
- 2024-2025学年安徽省“江南十校”高一下学期5月份阶段联考数学试卷(含答案)
- 智慧工厂工控系统网络安全等级保护建设方案
- 大型活动安全员职责
- 机械工程材料课件 学习情境八 有色金属及其合金
- 食品安全事故处理制度
- 2024年西藏自治区中考物理试题卷(含答案)
- 《底层逻辑》刘润
- 第五节绿色施工管理体系与措施
- 破伤风急诊预防及诊疗专家共识
- 产教融合实训基地建设
- 2024年大型国有集团公司“两优一先”评选表彰工作方案
评论
0/150
提交评论