ImageVerifierCode 换一换
格式:DOCX , 页数:31 ,大小:136.54KB ,
资源ID:13002155      下载积分:1 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-13002155.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(蛮力法动归贪心分支限界法解01背包问题剖析.docx)为本站会员(b****6)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

蛮力法动归贪心分支限界法解01背包问题剖析.docx

1、蛮力法动归贪心分支限界法解01背包问题剖析算法综合实验报告学 号: 1004121206 姓 名: 林 一、实验内容:分别用蛮力、动态规划、贪心及分支限界法实现对0-1背包问题的求解,并至少用两个测试用例对所完成的代码进行正确性及效率关系上的验证。二、程序设计的基本思想、原理和算法描述:1、 蛮力法 1.1数据结构注:结构体obj用来存放单个物品的价值和重量 typedef struct obj int w;/物品的重量 int v;/物品的价值 ; 1.2 函数组成 void subset(int s10,int n):用来生成子集的函数 void judge(int s10, obj ob

2、j,int mark,int n,int c):判断子集的可行性 int getmax(int mark,int n,int &flag):求解问题的最优解 void outputObj(int flag,int s10,int n):输出选择物品的情况 1.3 输入/输出设计 本程序通过键盘进行输入、屏幕进行输出。 1.4 符号名说明 符号 说明 S 存放子集 mark 记录子集的可行性 n 物品的个数 c 物品的容量 max 记录背包所能产生的最大价值 flag 记录能产生最大价值的子集的编号 1.5 算法描述 算法的伪代码描述如下: 输入:背包的容量c,物品的个数n,n个物品的重量 wn

3、,价值vn 输出:装入背包的物品编号以及产生的最大价值 1.初始化最大价值 max=0,结果子集 s=; 2.对集合1,2,.n的每一个子集T,执行下述操作: 2.1初始化背包的价值 v=0,背包的重量 w=0; 2.2对子集t的每一个元素j 2.2.1 如果w+wjc,则 w=w+wj,v=v+vj; 2.2.2 否则,转步骤2考察下一个子集; 2.3如果maxc) 4.1 将第i个物品放入背包,objecti.Num=1; 4.2 c-=pron.Weight; 4.3 i+;5.记录最后放入背包的物品的重量: objecti.Num=(double)C/objecti.Weight;4、

4、 分支限界法 4.1数据结构 注:物品结构体,存放物品价值、重量、单位价值、物品编号等信息 struct obj int v;/物品价值 int w;/物品重量 double avg;/物品单位价值 int id;/物品编号 ; 注:结构体node用来存放节点表节点 struct node node *parent,/父亲结点指针 *next;/后继结点指针 int level,/节点所处的层 isin,/记录物品是否装入背包,0代表不装,1代表装入 cw,/当前背包已经装入的物品重量 cv;/当前背包已经装入的物品价值 double ub;/结点的上界值 ; 4.2函数组成 int Part

5、ition(_Object r,int first,int end);以数组第一个元素为准对数组进行一次划分并返回基准元素的位置坐标 void QuickSort(_Object r,int first,int end);快速排序 double Upb(int i,int cw,int cv);/计算上界值 node *nnoder(node * parent1,int isin1,double ub1);生成一个新的结点 void addnode(node *node1);/将结点添加到队列中 node *nextnode(); /取下一个结点 void fenzjx();/分支界限法的主要

6、实现函数 void output();/用于输出物品的选择情况及最优解4.3 输入/输出设计 本程序通过键盘进行输入、屏幕进行输出。 4.4 符号名说明 符号 说明 c 背包的容量 n 物品的个数 pro 存放物品信息 avg 物品的单位价值量 opv 背包容量最优解 popv 指向最优解的指针 level 节点的层 cw 当前背包装载量 cv 当前背包价值 ub 节点的上界值 isin 记录当前结点物品是否放入背包 flag 物品原来位置(4)算法描述 算法的伪代码描述如下: 输入:背包的容量c,物品的个数n,n个物品的信息 pron 输出:装入背包的物品标号和背包获得的最大价值 1.对输入

7、的物品按照单位价值量递减的顺序进行排序 2.初始化问题最优解opv=0,初始化第0层结点,计算上界值 ub=Upb(0,0,0);并设置该结点设为优先级队列的根结点 3.循环直到优先级队列为空 3.1 如果取出当前结点位于第n-1层,则其子结点已是叶子结点,判断子结点取值情况,若得到的解大于当前问题得到的最优解opv,则重置问题的最优解opv 3.2 如果取出当前结点层 level n-1 对结点i的每个孩子结点x执行下列操作: 3.2.1 如果结点x可能产生的最优解ubopv,则丢弃该结点; 3.2.2 否则估算该节点x的目标函数值ub,将结点加入队列; 4.将该结点对应的最优值输出,回溯求

8、得最优解的各个分量三、源程序及注释: 1、蛮力法#include#includeusing namespace std;/物品typedef struct obj int w; int v;/生成子集void subset(int s10,int n) int i,j,m,k; for(i=0;i=0;j-) m=k%2; sij=m; k=k/2; /判断子集可行性void judge(int s10, obj obj,int mark,int n,int c) int i,j,v,w; for(i=0;ipow(2,n);i+) w=0; v=0; for(j=0;jn;j+) w+=ob

9、jj.w*sij; v+=objj.v*sij; if(w=c) marki=v; else marki=0; /求问题的最优解int getmax(int mark,int n,int &flag) int i,max; max=0; for(i=0;imax) max=marki; flag=i; return max;/输出选择物品的情况void outputObj(int flag,int s10,int n) cout装入背包物品的编号为: ; for(int i=0;in;i+) if(sflagi=1) couti+1 ; coutendl;int main() int s102

10、410,mark1024,n,max,c,flag; obj obj10; coutc; coutn; cout请分别输入物品的重量:; for(int i=0;iobji.w; cout请分别输入物品的价值:; for(i=0;iobji.v; subset(s,n); judge(s,obj,mark,n,c); max=getmax(mark,n,flag); outputObj(flag,s,n); cout背包可容纳的最大价值为: maxendl; return 0; 2、动态规划法#includeusing namespace std;/比较并返回两个数中的较大值int max(i

11、nt i,int j) if(ij) return j; else return i;/求解背包取得的最大值int KnapSack (int w,int v,int x,int n,int c) int i,j,V1051005=0; for(i=0;i=n;i+) /初始化第0列 Vi0=0; for(j=0;j=c;j+) /初始化第0行 V0j=0; for(i=1;i=n;i+) /计算第i行,进行第i次迭代 for(j=1;j=c;j+) if(j0;i-) /求装入背包的物品编号 if(VijVi-1j) xi=1; j=j-wi; else xi=0; return Vnc;i

12、nt main() int c,n,w105,v105,x105,max;/x记录物品的选择情况 coutc; coutn; cout请分别输入物品的重量:; for(int i=1;iwi; cout请分别输入物品的价值:; for( i=1;ivi; max=KnapSack(w,v,x,n,c); cout装入背包的物品编号为:; for(i=1;i=n;i+) if(xi=1) couti ; coutendl; cout背包可容纳的最大价值为:maxendl; return 0; 3、贪心法#include#includeusing namespace std;/物品结构体struc

13、t _Object int Value;/物品价值 int Weight;/物品重量 double AveValue;/物品单位价值 double Num;/物品可以放入的数量 int key;/物品标号;/划分int Partition(_Object r,int first,int end) int i=first,j=end; while(ij) while(irj.AveValue) j-; if(ij) _Object temp=ri; ri=rj; rj=temp; i+; while(irj.AveValue) i+; if(ij) _Object temp=ri; ri=rj;

14、 rj=temp; j-; return i;/快速排序void QuickSort(_Object r,int first,int end) int pivot; if(firstend) pivot=Partition(r,first,end); QuickSort(r,first,pivot-1); QuickSort(r,pivot+1,end); double knaspsack(int n,int M,_Object object) /n为物品个数,M为背包容量 int i; int C=M; double maxValue=0; for(i=0;objecti.WeightC;i

15、+) objecti.Num=1;/初始化放入背包的物品为0 maxValue+=objecti.Value; C=C-objecti.Weight; objecti.Num=(double)C/objecti.Weight; maxValue+=objecti.Num*objecti.Value; return maxValue;int main() int n,c; _Object pro1001; coutc; coutn; cout请分别输入物品的重量和价值:;for(int i=0;iproi.Weightproi.Value; proi.AveValue=(double)proi.

16、Value/proi.Weight; proi.Num=0; proi.key=i; QuickSort(pro,0,n-1); double maxValue=knaspsack(n,c,pro); cout背包的可容纳的最大价值为:; printf(%.2f,maxValue); coutendl; int k; cout各个物品装入背包的重量分别为:; for(k=0;kn;k+) for(int j=0;jn;j+) if(proj.key=k) /找到原来顺序的物品编号 coutproj.Weight*proj.Num ; coutendl; return 0; 4、分支限界法 #i

17、nclude #include #include #include #include using namespace std;/物品结构体struct obj int v;/物品价值 int w;/物品重量 double avg;/物品单位价值 int id;/物品编号;/节点结构体struct node node *parent,/父亲结点指针 *next;/后继结点指针 int level,/节点所处的层 isin,/记录物品是否装入背包,0代表不装,1代表装入 cw,/当前背包已经装入的物品重量 cv;/当前背包已经装入的物品价值 double ub;/结点的上界值;/划分int Par

18、tition(obj r,int first,int end) int i=first,j=end; while(ij) while(irj.avg) j-; if(ij) obj temp=ri; ri=rj; rj=temp; i+; while(irj.avg) i+; if(ij) obj temp=ri; ri=rj; rj=temp; j-; return i;/快速排序void QuickSort(obj r,int first,int end) int pivot; if(firstend) pivot=Partition(r,first,end); QuickSort(r,f

19、irst,pivot-1); QuickSort(r,pivot+1,end); class fzjxprivate: node *front,/队首指针 *first,/根节点指针 *popv;/解结点指针 double opv;/背包可产生的最大价值 obj *pro;/物品 int n,/物品个数 c;/背包容量public: fzjx(obj *pro1,int w1,int n1 ); fzjx(); int *flag; double Upb(int i,int cw,int cv);/计算上界值 node *nnoder(node * parent1,int isin1,doub

20、le ub1); void addnode(node *node1);/将结点添加到队列中 node *nextnode(); /取下一个结点 void fenzjx(); void output();fzjx:fzjx(obj *pro1,int c1,int n1 ) int i; n=n1;c=c1; pro=new obj n; flag=new intn; for(i=0;inext=NULL; opv=0; popv=new node1; popv=NULL; QuickSort(pro,0,n-1);fzjx:fzjx() deletefirst; deletefront; deletepopv; deletepro;double fzjx:Upb(int i,int cw,int cv) int cleft=c-cw; double v=(double)cv; if (iparent=parent1; no

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2