下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、算法综合实验报告学号:1004121206姓名: 林一、实验内容:分别用蛮力、动态规划、贪心及分支限界法实现对0-1背包问题的求解,并至少用两个测试用例对所完成的代码进行正确性及效率关系上的验证。二、程序设计的基本思想、原理和算法描述:1、蛮力法1.1 数据结构注:结构体obj用来存放单个物品的价值和重量typedef struct objint w;/物品的重量int v;/物品的价值;1.2 函数组成void subset(int s10,int n):用来生成子集的函数void judge(int s10, obj obj口,int mark,int n,int c):判断子集的可行性i
2、nt 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,价值vn 输出:装入背包的物品编号以及产生的最大价值1. 初始化最大价值 max=0,结果子集s
3、二小;2. 对集合1,2,n的每一个子集T,执行下述操作:2.1 初始化背包的价值v=0 ,背包的重量w=0;2.2 对子集t的每一个元素j2.2.1 如果 w+wj<c5U w=w+wj,v=v+vj;2.2.2 否则,转步骤2考察下一个子集;2.3 如果 max<v,贝 U max=v;s=t;3. 输出子集S中的各元素2、动态规划法3.1 数据结构该程序不涉及任何数据结构3.2 函数组成int max(int i,int j); 比较并返回两个数中的较大值int KnapSack (int w口,int v口,int x口,int n,int c);求解背包取得的最大值3.3
4、 输入/输出设计本程序通过键盘进行输入、屏幕进行输出2.4符号名说明符号说明n物品的个数c物品的容量w口物品的重量v口物品的价值x口物品的选择情况V叩存放迭代结果2.5算法描述算法的伪代码描述如下:输入:背包的容量c,物品的个数n,n个物品的重量wn,价值vn 输出:装入背包的物品标号和背包获得的最大价值1 .初始化二维数组V=02 .初始化二维数组的第0行,第0列3 .循环直到i=n3.1 循环直到j二c3.1.1 如果背包的容量不足以装入物品i,则装入前i个物品得到的最大价值和装入前i-1个物品得到的最大价值相等3.1.2 如果背包的容量可以装入物品i,分别计算装入物品i可达到的彳/T值量
5、Vi-1wi+vi,以及不放入物品i可以得到的最大价值Vi-1j,取二者中的较大者作为把前i个物品装入容量为j的背包 中的最优解3、贪心法3.1 数据结构注:结构体用来存放物品的重量、价值、单位价值、物品编号等信息struct _Objectint Value;/物品价值int Weight;/物品重量double AveValue;/ 物品单位价值double Num;/物品可以放入的数量int key;/ 物品标号;3.2 函数组成;以数组第一个元;求解背包问题int Partition(_Object r口,int first,int end) 素为准对数组进行一次划分并返回基准元素的位
6、置坐标void QuickSort(_Object r口,int first,int end) double knaspsack(int n,int M,_Object object口) 的最优解3.3 输入/输出设计本程序通过键盘进行输入、屏幕进行输出。3.4符号名说明符号说明n物品的个数c物品的容量pro物品的重量、价值、单位价值、编号3.5算法描述算法的伪代码描述如下:输入:背包的容量c,物品的个数n,n个物品的重量pron.Weight,价值 pron.Value输出:装入背包的物品标号和背包获得的最大价值1 .计算物品的单位价值并存入pron.2 .将物品按照单位价值递减的顺序进行排
7、序3.i=0;4. 循环直到(objecti.Weight>c )4.1 将第 i 个物品放入背包,objecti.Num=1 ;4.2 c-=pron.Weight ;4.3 i+;5. 记录最后放入背包的物品的重量:objecti.Num=(double)C/objecti.Weight;4、分支限界法4.1 数据结构注:物品结构体,存放物品价值、重量、单位价值、物品编号等信息struct objint v;/物品价值int w;/物品重量double avg;/ 物品单位价值int id;/ 物品编号;注:结构体node用来存放节点表节点struct nodenode *paren
8、t,/ 父亲结点指针*next;/ 后继结点指针int level,/节点所处的层isin,/ 记录物品是否装入背包,0代表不装 ,1 代表装入cw,/当前背包已经装入的物品重量cv;/当前背包已经装入的物品价值double ub;/ 结点的上界值;4.2 函数组成;以数组第一个元int Partition(_Object r口,int first,int end)素为准对数组进行一次划分并返回基准元素的位置坐标void QuickSort(_Object r口,int first,int end);快速排序double Upb(int i,int cw,int cv);/计算上界值node
9、*nnoder(node * parent1,int isin1,double ub1);生成一个新的结点void addnode(node *node1);/ 将结点添加到队列中node *nextnode(); /取下一个结点void fenzjx();/分支界限法的主要实现函数void output();/用于输出物品的选择情况及最优解4.3 输入/输出设计本程序通过键盘进行输入、屏幕进行输出。4.4 符号名说明符号说明c背包的容量n物品的个数pro存放物品信息avg物品的单位价值量opv背包容量最优解popv指向最优解的指针level节点的层cw当前背包装载量cv当前背包价值ub节点的
10、上界值isin记录当前结点物品是否放入背包flag物品原来位置(4) 算法描述算法的伪代码描述如下:输入:背包的容量c, 物品的个数n,n 个物品的信息pron输出:装入背包的物品标号和背包获得的最大价值1. 对输入的物品按照单位价值量递减的顺序进行排序2. 初 始 化 问 题 最 优 解 opv=0, 初 始 化 第 0层 结 点 , 计 算 上 界 值 ub=Upb(0,0,0); 并设置该结点设为优先级队列的根结点3. 循环直到优先级队列为空3.1 如果取出当前结点位于第n-1 层,则其子结点已是叶子结点,判断子结点取值情况,若得到的解大于当前问题得到的最优解opv,则重置问题的最优解o
11、pv3.2 如果取出当前结点层level< n-1对结点i的每个孩子结点x执行下列操作:3.2.1 如果结点x可能产生的最优解ub<opv,则丢弃该结点;3.2.2 否则估算该节点x的目标函数值ub,将结点加入队列;4. 将该结点对应的最优值输出,回溯求得最优解的各个分量三、源程序及注释:1、蛮力法#include<iostream>#include<math.h> using namespace std;/ 物品typedef struct objint w;int v;/ 生成子集void subset(int s10,int n)int i,j,m,k
12、;for(i=0;i<pow(2,n);i+)k=i;for(j=n-1;j>=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;i<pow(2,n);i+)w=0;v=0;for(j=0;j<n;j+)w+=objj.w*sij;v+=objj.v*sij;if(w<=c)marki=v;else marki=0;/ 求问题的最优解int getmax(int mark,int n,int &flag)i
13、nt i,max;max=0;for(i=0;i<pow(2,n);i+)if(marki>max)max=marki;flag=i;return max;/ 输出选择物品的情况void outputObj(int flag,int s10,int n)cout<<" 装入背包物品的编号为:"for(int i=0;i<n;i+)if(sflagi=1)cout<<i+1<<" "cout<<endl;int main()int s102410,mark1024,n,max,c,flag;
14、obj obj10;cout<<" 请输入背包的容量:"cin>>c;cout<<" 请输入物品的个数:"cin>>n;cout<<" 请分别输入物品的重量:"for(int i=0;i<n;i+)cin>>obji.w;cout<<" 请分别输入物品的价值:"for(i=0;i<n;i+)cin>>obji.v;subset(s,n);judge(s,obj,mark,n,c);max=getmax(mar
15、k,n,flag);outputObj(flag,s,n);cout<<" 背包可容纳的最大价值为:"<<max<<endl;return 0;2、动态规划法 #include<iostream>using namespace std;/ 比较并返回两个数中的较大值int max(int i,int j)if(i<j)return j;elsereturn i;/ 求解背包取得的最大值int KnapSack (int w,int v,int x,int n,int c) int i,j,V1051005=0;初始化第0
16、列初始化第0行计算第 i 行, 进行第 i 次迭代for(i=0;i<=n;i+)/Vi0=0;for(j=0;j<=c;j+)/V0j=0;for(i=1;i<=n;i+)/for(j=1;j<=c;j+)if(j<wi)Vij=Vi-1j;elseVij=max(Vi-1j,Vi-1j-wi+vi);for(j=c,i=n;i>0;i-)/if(Vij>Vi-1j)xi=1;j=j-wi;else xi=0;return Vnc;int main()int c,n,w105,v105,x105,max;/xcout<<" 请输
17、入背包的重量:"cin>>c;cout<<" 请输入物品的个数:"cin>>n;cout<<" 请分别输入物品的重量:for(int i=1;i<=n;i+)cin>>wi;cout<<" 请分别输入物品的价值:"for( i=1;i<=n;i+)cin>>vi;max=KnapSack(w,v,x,n,c);cout<<" 装入背包的物品编号为:求装入背包的物品编号记录物品的选择情况for(i=1;i<=n;i
18、+)if(xi=1)cout<<i<<" "cout<<endl;cout<<" 背包可容纳的最大价值为:"<<max<<endl;return 0;3、贪心法#include<iostream>#include<stdio.h>using namespace std;/ 物品结构体struct _Objectint Value;/ 物品价值int Weight;/ 物品重量double AveValue;/ 物品单位价值double Num;/ 物品可以放入
19、的数量int key;/ 物品标号;/ 划分int Partition(_Object r,int first,int end)int i=first,j=end;while(i<j)while(i<j&&ri.AveValue>rj.AveValue)j-;if(i<j)_Object temp=ri;ri=rj;rj=temp;i+;while(i<j &&ri.AveValue>rj.AveValue) i+;if(i<j)_Object temp=ri;ri=rj;rj=temp;j-;return i;/ 快速
20、排序void QuickSort(_Object r,int first,int end) int pivot;if(first<end)pivot=Partition(r,first,end);QuickSort(r,first,pivot-1);QuickSort(r,pivot+1,end);为物品个数,Mdouble knaspsack(int n,int M,_Object object) /n 为背包容量int i;int C=M;double maxValue=0;for(i=0;objecti.Weight<C;i+)objecti.Num=1;/ 初始化放入背包的
21、物品为0maxValue+=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;cout<<" 背包的容量:"cin>>c;cout<<" 请输入物品的个数:"cin>>n;cout<<" 请分别输入物品的重量和价值:"
22、for(int i=0;i<n;i+)cin>>proi.Weight>>proi.Value;proi.AveValue=(double)proi.Value/proi.Weight;proi.Num=0;proi.key=i;QuickSort(pro,0,n-1);double maxValue=knaspsack(n,c,pro);cout<<" 背包的可容纳的最大价值为:"printf("%.2f",maxValue);cout<<endl;int k;cout<<"
23、各个物品装入背包的重量分别为:"for(k=0;k<n;k+)for(int j=0;j<n;j+)if(proj.key=k) /找到原来顺序的物品编号cout<<proj.Weight*proj.Num<<" "cout<<endl;return 0;4、分支限界法#include<iostream>#include<cstdio>#include<conio.h>#include<iomanip>#include<stdlib.h>using name
24、space std;/ 物品结构体struct obj int v;/物品价值int w;/物品重量double avg;/ 物品单位价值int id;/ 物品编号;/ 节点结构体struct nodenode *parent,/ 父亲结点指针*next;/后继结点指针int level,/ 节点所处的层isin,/记录物品是否装入背包,0代表不装 ,1 代表装入cw,/当前背包已经装入的物品重量cv;/当前背包已经装入的物品价值double ub;/ 结点的上界值;/ 划分int Partition(obj r,int first,int end)int i=first,j=end;whil
25、e(i<j)while(i<j&&ri.avg>rj.avg)j-;if(i<j)obj temp=ri;ri=rj;rj=temp;i+;while(i<j &&ri.avg>rj.avg) i+;if(i<j)obj temp=ri;ri=rj;rj=temp;j-; return i;/ 快速排序void QuickSort(obj r,int first,int end) int pivot;if(first<end)pivot=Partition(r,first,end);QuickSort(r,firs
26、t,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,double ub1);void add
27、node(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;i<n;i+)proi.w=pro1i.w;proi.v=pro1i.v;proi.id=pro1i.id;proi.avg=pro1i.avg;flagi=i;front=new node1;front->next=NULL;opv=0;popv
28、=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 (i<n)v+=1.0*proi.avg*cleft;return v;node * fzjx:nnoder(node * parent1,int isin1,double ub1)/ 生成一个新结点node * node2=new(node);n
29、ode2->parent=parent1;node2->next=NULL;node2->level=(parent1->level)+1;node2->isin=isin1;node2->ub=ub1;if(isin1=1)node2->cw=parent1->cw+proparent1->level.w;node2->cv=parent1->cv+proparent1->level.v ;elsenode2->cw=parent1->cw;node2->cv=parent1->cv;return
30、(node2);void fzjx:addnode(node *node1)/ 将结点加入优先队列node *p=front->next,*next1=front;double ub=node1->ub;while(p!=NULL)if(p->ub<ub)node1->next=p;next1->next=node1;break;next1=p;p=p->next;if(p=NULL)next1->next=node1;node * fzjx:nextnode()/ 取上限最大结点node *p=front->next;front->
31、next=p->next;return(p);void fzjx:fenzjx()int i;double ub2;node *node3;first=new node1; / 根结点 first->parent=NULL;first->next=NULL;first->level=0;first->cw=0;first->cv=0;first->isin=0;ub2=Upb(0,0,0);first->ub=ub2;front->next=first;while(front->next!=NULL)node3=nextnode();
32、 i=node3->level;if(i=n-1)if(node3->cw+proi.w<=c&&(node3->cv+proi.v)>opv)opv=node3->cv+proi.v;popv=nnoder(node3,1,opv);if(node3->cv)>opv)opv=node3->cv;popv=nnoder(node3,0,opv);if(i<n-1)if(node3->cw+proi.w<=c&&Upb(i+1,node3->cw+proi.w,node3->cv
33、+proi.v)>opv) ub2=Upb(i,node3->cw+proi.w,node3->cv+proi.v);addnode(nnoder(node3,1,ub2);ub2=Upb(i,node3->cw,node3->cv);if(ub2>opv)addnode(nnoder(node3,0,ub2);void fzjx:output()(int i;for(i=n-1 ;i>=0;i-)(flagproi.id=popv->isin; popv=popv->parent;)cout«"装入背包的物品编号为:f
34、or(i=0;i<n;i+)(if(flagi=1) cout«i+1«")cout«endl;:"«opv«endl;cout«"背包可以产生的最大价值是)int main ()(int c,n;int i=0;obj *pro1;COUtVV”请输入背包的容量:"; cin»c;cout<<" 请输入物品的个数: "cin>>n;pro1 = new objn;cout<<" 请分别输入物品的重量和价值for(
35、i=0;i<n;i+)cin>>pro1i.w>>pro1i.v;pro1i.avg=1.0*pro1i.v/pro1i.v;pro1i.id=i;fzjx fzjx(pro1,c,n);fzjx.fenzjx();fzjx.output();return 0;四、运行输出结果:1、蛮力法用例测试1 :用例测试2 :*E: DebugOlbaj lanli. exe"B 5BU> n 为tl值为值on一r价 c¥扳的的编大to 容个品品的最y 的的物物品的帕 包口<人物纲9 "居福曹容M 一人人永丞皆可ff 箱介入包M 三阴二喝用一工目打2、动态规划法用例测试1 :'CikProerM Fileslicrosoft Visual Si(idioMyPrcjjectslinDebugl量值为值:重 c 量数的的维大to 重个品品匚邛最y物物物的kB入包 请请请请装背用例测试2 :3、贪心法用例测试1:80 100 33 55 4s 90 22 FkR用例测试2:重量和价值45 12 67 9 234酬5 E询# 3口编号为+ 2 6 7 9 1B墨大411是fM
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 产科入科健康宣教
- 儿童自闭症宣教
- 肝炎患者临床表现及护理要点
- 自主决策能力培养课程设计
- 汽车行业市场前景及投资研究报告:轴向磁通电机高功率密度特点下一代执行器用电机
- 精神分裂症科普
- 校区合伙人合同协议
- 民宿加盟合同协议书
- 竹林损坏赔偿协议书
- 村民草场权属协议书
- 2025年考研英语二冲刺押题卷含答案
- 高性能芳纶纤维生产线项目可行性研究报告
- 铝合金门窗工程设计、施工及验收规范
- 行星减速机原理课件讲解
- 2025秋季学期国开电大法学本科《国际私法》期末纸质考试案例分析题库珍藏版
- 贸易安全知识培训内容课件
- 第四讲-正确认识中国经济热点问题-2025秋版本-建设更高水平平安中国国家安全
- 2025年易驱变频器说明书
- 医院儿科简介
- 2025山东发展投资控股集团有限公司权属企业招聘4人笔试历年参考题库附带答案详解
- IPC7530A2017GuidelinesTemperatureProfilingMassSolderingProcessesReflowWave(IPC-7530A 2017 回流焊和波峰焊工艺温度曲线指南)
评论
0/150
提交评论