版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、分支限界法解01背包问题学院:网研院姓名:XXX学号:2013XXXXXX1、 分支限界法原理分支限界法类似于回溯法,也是在问题的解空间上搜索问题解的算法。一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出解空间中满足约束条件的所有解;而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。由于求解目标不同,导致分支限界法与回溯法对解空间的搜索方式也不相同。回溯法以深度优先的方式搜索解空间,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间。分支限界法的搜索策略是,在扩展结点处,先生成其
2、所有的儿子结点(分支),然后再从当前的活结点表中选择下一扩展结点。为了有效地选择下一扩展结点,加速搜索的进程,在每一个活结点处,计算一个函数值(限界),并根据函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间上有最优解的分支推进,以便尽快地找出一个最优解。常见的分支限界法有如下两种:队列式(FIFO)分支限界法:按照先进先出原则选取下一个节点为扩展节点。活结点表是先进先出队列。FIFO分支限界法搜索策略:一开始,根结点是唯一的活结点,根结点入队。从活结点队中取出根结点后,作为当前扩展结点。对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的
3、儿子加入活结点队列中。再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,重复上述过程,直到找到一个解或活结点队列为空为止。LC(leastcost)分支限界法(优先队列式分支限界法):按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。活结点表是优先权队列,LC分支限界法将选取具有最高优先级的活结点出队列,成为新的扩展节点。优先队列式分支限界法搜索策略:对每一活结点计算一个优先级(某些信息的函数值);根据这些优先级从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。再从活结点表中下一个优
4、先级别最高的结点为当前扩展结点,重复上述过程,直到找到一个解或活结点队列为空为止。2、 01背包问题简介01背包问题假设有一个容量为c的背包,有n件物品,每件物品有重量w和价值v,求解怎样往背包里装物品能够在不超出背包容量c的情况下获得最大价值(本实验中物品的w和v都是大于0的实数,可以是整数也可以是浮点数)。3、 FIFO分支限界法解01背包问题1 .算法输入背包容量capacity、物品数量count、物品的重量数组weights和物品的价值数组values,根据物品单位价值(value/weight)从大到小构造一个新数组,数组元素(OriginNode)有weight、value和va
5、luePerWeight属性,根据该排序数组构造问题的解空间树(完全二叉树);定义一个FIFO队列(队列元素是节点,见下文),队列可以在队尾插入节点和在队头删除节点;定义节点(ArrayNode),节点是问题的解空间树上的点,它的属性有当前价值currentValue、当前重量currentWeight、上限价值upboundValue、节点对应的选择情况nodeChoses(0表示不选,1表示选,如“101”表示该节点选择了物品1和物品3,没有选择物品2)和节点在问题解空间树上的层次nodeCount(0n);定义一个计算节点价值上限的函数upBound(),upBound函数的计算规章是:
6、价值上限=节点现有价值+背包剩余容量*剩余物品的最大单位重量价值定义一个全局的currentMaxValue记录程序目前取得的最大价值;将一个空节点推入队列,空节点的当前价值、当前重量、节点层次均为0,全局的currentMaxValue初始化为0,使用upBound函数计算几点的价值上限并使用该属性初始化节点的upboundValue属性;当队列不为空时,一直重复下述操作:从队首取得头节点,如果头节点的上限价值upboundValue比全局的currentMaxValue要大,贝表明头节点的子节点中可能有最优节点,取头节点在问题的解空间树上的左子节点和右子节点,若左子节点和右子节点的重量没有
7、超出背包容量且它们的upboundValue大于全局的currentMaxValue,将该子节点插入队尾,否则不插入,同时若子节点的当前价值currentValue大于全局的currentMaxValue,更新currentMaxValue。如果头结点的上限价值upboundValue比全局的currentMaxValue要小,则表明头结点及其子节点不可能有最优节点,将其舍弃。若头结点的当前价值currentValue正好等于全局的currentMaxValue且头结点的层次nodeCount等于物品数量n,则表明头结点是问题的解空间树上的叶子,该头结点可能就是最优节点,将其存储在全局的cur
8、rentMaxNode属性中(随着队列遍历的进行当前存起来的节点仍可能被更优的节点覆盖)。当队列为空时,表明所有的可能情况已被处理,此时全局的currentMaxNode属性指向了最优的节点,该节点的currentvalue属性即为背包问题的最优解。2 .算法复杂度在最坏的情况下所有的节点都入队,最后一个节点才是最优解,这种情况下时间复杂度是指数阶。最好的情况是只装单位价值最大的物品,其余分支都不符合条件被截去这种情况下时间复杂度是常数时间。但分支限界法本质上还是穷举法,平均时间复杂度仍是指数阶。空间复杂度的分析类似时间复杂度,也是指数阶。3 .可能的改进在本次实验中,即便取得了可能是最优解的
9、问题空间树上的叶子节点的时候仍然会遍历其它节点以保证得到的是最优解,当对正确率的要求不是很高的时候,可以在取得第一个可能是最优解的节点时候便停止算法。本次实验使用的是FIFO分支限界法,若使用优先队列式分支限界法(LC),在空间复杂度上的性能肯定会得到改善,若不要求结果十分准确,使用优先队列取得第一个可能节点时候便停止算法,则在时间复杂度上的性能应该也能优于FIFO分支限界(优先队列采取的是深度遍历,能更快到达叶子节点)。4、 算法实现框架本次实验使用的语言是java,OriginNode类用来按价值重量比构造排序数组,sort方法用于数组排序(出于便于实现的考虑使用了冒泡排序,改成快速排序可
10、获得更好的性能)。OriginNode(floatweight;floatvalue;floatvaluePerWeight;publicOriginNode(floatweightyfloatvaluf)thi5.weight=weightthis.value=this,valuePerMeight=value/weight;)H芭0排工谗wm室且二+HA大£小*工publicstaticvoidsort(Or£ginUodenodes)OrigifiMadetmp=null;far(inti-3;i<nodeshLength;in-)for(intj=i+-Ijj
11、<nodesilength;J*)if(n-odesfj.valuePerWeight>rrodesi.vjluePerlJeight)tmp=nodesi;nodesL=nodesJin-odesCJ=tmp;ArrayNode类用于构造问题的解空间树上的节点。cla5sArrayNode- FloatcurrentWei- floatcurrentvalue;- Floatupboundvalue;StringnodeChoLces;intnodE匚cu门t;publicArrayNcde(floatcurrentHeightjfloatcurrerrtValuejString
12、nodeCholc&sTintnod&Count)(this.CurrentLJelght=cu.rrentlrJelglrtjthis.currentValue=currenValuethis.nodechoices=nadeChoices;this.rodeCaurt=nodeC-ount;FIFOBBKnapsac疑是程序的主类,定义了currentMaxValue等属性,起全局变量的作用供节点共同维护,upBound方法用于计算节点价值上限。publicclassFIFOBBKrapsackintcapacity;intcountjfloatweightsifloatv
13、alues;OriginNodeoriginNodes;floatcurrentMaxValue;ArrayNodecjrrenthaxNode;privatefloatupEound(ArrayModenode)floatweightLeft-this.capacity-node.currentWeightjfloatbound-node-currentvalue;intt-node.nodeCount*while(t<this.count&&originNodtst.weight<-weightLeft)weightiest-=orIginNodesft,wei
14、ghtybound+=originNodest.value;七";if(t<this*count)bound4-=(originNodestxvalue/originNodestweiglit)*weightLeft;returnbound;publicstaticvoidinain(Stringargs)while(true)(在FIFOBBKnapsac蟆的main方法里定义了分支限界法的逻辑,截取主要部分如下。LinkedList<Arrayttode>arrayWodeList-newLinkedLi5t<ArrayH-ode>();ArrayN
15、odeheadNode=newArrayNode(&f*幻:headhode.upbQurrdalue=knapsack.upBcund(hadlJade)jknapsackxCurrentMaxValue=&knapsack+currenti-laxNcde=null;arrayNodeList,push(headMode);whil«(!a*rayNodeList.isEmptyO)|ArrayNodefirstNode=arrayHodaList.pop()if(firstNode.rodeCount=-knapsack.count&&first
16、Node.currentvalue=knapsack.currentMaxValue)knapsck(currenriaxhode=firstNode;continue;)if(firstNade.upboundValue>"knapsack,currerrtMaxValce*&firitNode.nodeCount<knapsack.court)ArrayJodeleftNode=newArrayN-ode(firstMode.currenfideiht+knapsack,origirirJadestfirstNode-nodeCount*weightj.fir
17、stNode.currentValue+knapsack.originNodesfir5tNod&*nodeCount.value,firstNadc.nodechoices+"liptfirstModenodeCount+1)jleftNod>upbcundValu?=knmp&mtk.upBound(le十七【和(1£)jif(leftNodecurr'entlJeight<=knepsackncapacityleftMods,upboundValue>knapsack.currenWaxValue)arrayiNedeLlst
18、.addfleftHode);if(IwftWod.curr0ntUalLi白>knapsack.currentMaxValue)knapsack,curren'axValde=l&ftN-odecurrentvalue;)rrayNoderightMode=newArr3yNocle(firstNadecurrentWeig.ht,firstNod«.currentValue>firstNade.ncdeChoices+*'5"jfirstNcde.nodeCount+1)jrightNode.upboundl'a1ue=kna
19、psack.upBound(rightFlode);iftrightMode.uphoundValue>=knapsack.current;axValue)arrayiNcdeList.add(rightNode);五、总结在本科的时候曾经做过背包问题的项目,所以本次实验我选择了01背包问题该题目。但在做本次实验之前,我对分支限界法的原理并不是很理解,经过查看课件及网上查找资料,同时结合自己对回溯法等的理解,我对分支限界法有了一个较好的理解,知道了两种主要的分支限界法及分支限界法如何应用于解01背包问题。在查找资料的过程中,我查看了许多网上的别人的代码实现,但大多都存在着问题或者混淆使用
20、了两种分支限界法,最后通过参考别人的部分代码以及结合自己对FIFO分支限界法的理解,使用了java语言完成了该实验。通过本次试验,我基本上掌握了分支限界法解0-1背包问题的原理,同时锻炼了自己动手编写及调试代码的能力,收获良多。附录程序运行示例:*FIFOh豆诅,法鼻。1号里向罢产运*郭*一-左轮工当巨姿工二二戛£1样亘=-三通人片R或五:正充£3片回土1»-*注又把1鼻庄耳三;FEI-9S7523735022557399昌-T轮入E鼻学工三尸亘壬-89的19431崎724416764三巨莅戋=今亭土/笠壶:38S.0三里至三:294.0次8无d安言主跑二丁不主*
21、22.。50.095.02375,巧96,073.057.0S?t0填同步£44.072.&106439.®19.®59,g64,043,01d。1.电唠捶由W:伺森三串出1段事丐::1111191330代码importjava.util.LinkedList;importjava.util.Scanner;publicclassFIFOBBKnapsackintcapacity;intcount;float口weights;floatvalues;OriginNodeoriginNodes;floatcurrentMaxValue;ArrayNodecu
22、rrentMaxNode;privatefloatupBound(ArrayNodenode)floatweightLeft=this.capacity-node.currentWeight;floatbound=node.currentValue;intt=node.nodeCount;while(t<this.count&&originNodest.weight<=weightLeft)weightLeft-=originNodest.weight;bound+=originNodest.value;t+;if(t<this.count)bound+=(o
23、riginNodest.value/originNodest.weight)*weightLeft;returnbound;publicstaticvoidmain(Stringargs)while(true)Scannerin=newScanner(System.in);FIFOBBKnapsackknapsack=newFIFOBBKnapsack();System.out.println("*FIFO分支限界法解01背包问题开始*");/输入背包容量System.out.println("-请输入背包容量(正整数)并回车-");knapsack.c
24、apacity=in.nextInt();/输入物品数量System.out.println("-请输入物品数量(正整数)并回车-");knapsack.count=in.nextInt();knapsack.weights=newfloatknapsack.count;knapsack.values=newfloatknapsack.count;/构造物品重量数组System.out.println("-请输入物品重量数组(空格隔开)并回车-");for(inti=0;i<knapsack.count;i+)knapsack.weightsi=i
25、n.nextFloat();/构造物品价值数组System.out.println("-请输入物品价值数组(空格隔开)并回车-");for(inti=0;i<knapsack.count;i+)knapsack.valuesi=in.nextFloat();/排序knapsack.originNodes=newOriginNodeknapsack.count;for(inti=0;i<knapsack.count;i+)knapsack.originNodesi=newOriginNode(knapsack.weightsi,knapsack.valuesi);
26、OriginNode.sort(knapsack.originNodes);/FIFO队列LinkedList<ArrayNode>arrayNodeList=newLinkedList<ArrayNode>();ArrayNodeheadNode=newArrayNode(0,0,"",0);headNode.upboundValue=knapsack.upBound(headNode);knapsack.currentMaxValue=0;knapsack.currentMaxNode=null;arrayNodeList.push(headNo
27、de);while(!arrayNodeList.isEmpty()ArrayNodefirstNode=arrayNodeList.pop();if(firstNode.nodeCount=knapsack.count&&firstNode.currentValue=knapsack.currentMaxValue)knapsack.currentMaxNode=firstNode;continue;if(firstNode.upboundValue>=knapsack.currentMaxValue&&firstNode.nodeCount<kn
28、apsack.count)ArrayNodeleftNode=newArrayNode(firstNode.currentWeight+knapsack.originNodesfirstNode.nodeCount.weight,firstNode.currentValue+knapsack.originNodesfirstNode.nodeCount.value,firstNode.nodeChoices+"1",firstNode.nodeCount+1);leftNode.upboundValue=knapsack.upBound(leftNode);if(leftN
29、ode.currentWeight<=knapsack.capacity&&leftNode.upboundValue>knapsack.currentMaxValue)arrayNodeList.add(leftNode);if(leftNode.currentValue>knapsack.currentMaxValue)knapsack.currentMaxValue=leftNode.currentValue;ArrayNoderightNode=newArrayNode(firstNode.currentWeight,firstNode.current
30、Value,firstNode.nodeChoices+"0",firstNode.nodeCount+1);rightNode.upboundValue=knapsack.upBound(rightNode);if(rightNode.upboundValue>=knapsack.currentMaxValue)arrayNodeList.add(rightNode);System.out.println("背包能装下的最大价值是:"+knapsack.currentMaxNode.currentValue+"此时背包装的重量是:"+knapsack.currentMaxNode.currentWeight);System.out.println("物品的选择情况是:");System.out.print("物品重量:");for(inti=0;i<knapsack.count;i+)System.out.print(knapsack.originNodesi.weight+"&q
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年版影视制作与发行合同
- 美业门店培训课程设计
- 英语加国学课程设计理念
- 感觉统合课程设计大班
- 油画初学者 课程设计
- 2024政法干警考试复习资料
- 系统动力学课程设计总结
- 深圳市政府投资交通建设项目管理模式-第二册
- 大班社会签到课程设计
- 2024年羽绒家纺销售岗位职责(共8篇)
- 2024年6月浙江省高考历史试卷(真题+答案)
- 住友(SWS)汽车连接器(Connectors)产品配套手册
- 办公楼室内装饰工程施工设计方案技术标范本
- 2023年香港华夏杯六年级竞赛初赛数学试卷
- 高中数学放缩法
- 上海市闵行区2024-2025学年八年级(上)期末物理试卷(解析版)
- 2024年国考行测真题-言语理解与表达真题及完整答案1套
- 人教版三年级上册数学期末测试卷可打印
- 医疗高级职称评审论文答辩
- 设计服务保障措施方案
- 软件测试方案模板(完整版)
评论
0/150
提交评论