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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

分支限界法解01背包问题.docx

1、分支限界法解 01 背包问题学院:网研院 姓名:XXX 学号:2013XXXXXX一、 分支限界法原理分支限界法类似于回溯法, 也是在问题的解空间上搜索问题解的算法。一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出解空间中满足约束条件的所有解;而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。由于求解目标不同,导致分支限界法与回溯法对解空间的搜索方式也不相同。回溯法以深度优先的方式搜索解空间,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间。分支限界法的搜索策略是,在扩展结点处

2、,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一扩展结点。为了有效地选择下一扩展结点,加速搜索的进程,在每一个活结点处,计算一个函数值(限界),并根据函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间上有最优解的分支推进,以便尽快地找出一个最优解。常见的分支限界法有如下两种:队列式(FIFO)分支限界法:按照先进先出原则选取下一个节点为扩展节点。 活结点表是先进先出队列。FIFO 分支限界法搜索策略: 一开始,根结点是唯一的活结点,根结点入队。 从活结点队中取出根结点后,作为当前扩展结点。 对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,

3、把所有满足约束函数的儿子加入活结点队列中。 再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,重复上述过程,直到找到一个解或活结点队列为空为止。LC(least cost)分支限界法(优先队列式分支限界法):按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。活结点表是优先权队列,LC 分支限界法将选取具有最高优先级的活结点出队列,成为新的扩展节点。优先队列式分支限界法搜索策略: 对每一活结点计算一个优先级(某些信息的函数值); 根据这些优先级从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个

4、最优解。 再从活结点表中下一个优先级别最高的结点为当前扩展结点,重复上述过程,直到找到一个解或活结点队列为空为止。二、 01 背包问题简介01 背包问题假设有一个容量为 c 的背包,有 n 件物品,每件物品有重量 w和价值 v,求解怎样往背包里装物品能够在不超出背包容量 c 的情况下获得最大价值(本实验中物品的 w 和 v 都是大于 0 的实数,可以是整数也可以是浮点数)。三、 FIFO 分支限界法解 01 背包问题1. 算法 输入背包容量 capacity、物品数量 count、物品的重量数组weights 和物品的价值数组 values,根据物品单位价值(value/weight)从大到小

5、构造一个新数组,数组元素(OriginNode)有 weight、value 和 valuePerWeight 属性,根据该排序数组构造问题的解空间树(完全二叉树); 定义一个 FIFO 队列(队列元素是节点,见下文),队列可以在队尾插入节点和在队头删除节点; 定义节点(ArrayNode),节点是问题的解空间树上的点,它的属性有当前价值 currentValue、当前重量 currentWeight、上限价值upboundValue、节点对应的选择情况 nodeChoses(0 表示不选,1表示选,如“1 0 1”表示该节点选择了物品 1 和物品 3,没有选择物品 2)和节点在问题解空间树上

6、的层次 nodeCount(0 n); 定义一个计算节点价值上限的函数 upBound(),upBound 函数的计算规章是:价值上限=节点现有价值+背包剩余容量*剩余物品的最大单位重量价值 定义一个全局的 currentMaxValue 记录程序目前取得的最大价值; 将一个空节点推入队列,空节点的当前价值、当前重量、节点层次均为 0,全局的 currentMaxValue 初始化为 0,使用 upBound 函数计算几点的价值上限并使用该属性初始化节点的 upboundValue 属性; 当队列不为空时,一直重复下述操作:从队首取得头节点,如果头节点的上限价值 upboundValue 比全

7、局的 currentMaxValue 要大,则表明头节点的子节点中可能有最优节点,取头节点在问题的解空间树上的左子节点和右子节点,若左子节点和右子节点的重量没有超出背包容量且它们的 upboundValue 大于全局的currentMaxValue,将该子节点插入队尾,否则不插入,同时若子节点的当前价值 currentValue 大于全局的 currentMaxValue,更新currentMaxValue。如果头结点的上限价值 upboundValue 比全局的currentMaxValue 要小,则表明头结点及其子节点不可能有最优节点,将其舍弃。若头结点的当前价值 currentValue

8、 正好等于全局的 currentMaxValue 且头结点的层次 nodeCount 等于物品数量 n,则表明头结点是问题的解空间树上的叶子,该头结点可能就是最优节点,将其存储在全局的 currentMaxNode 属性中(随着队列遍历的进行当前存起来的节点仍可能被更优的节点覆盖)。 当队列为空时,表明所有的可能情况已被处理,此时全局的currentMaxNode 属性指向了最优的节点,该节点的 currentValue属性即为背包问题的最优解。2. 算法复杂度在最坏的情况下所有的节点都入队,最后一个节点才是最优解,这种情况下时间复杂度是指数阶。最好的情况是只装单位价值最大的物品,其余分支都不

9、符合条件被截去这种情况下时间复杂度是常数时间。但分支限界法本质上还是穷举法,平均时间复杂度仍是指数阶。空间复杂度的分析类似时间复杂度,也是指数阶。3. 可能的改进在本次实验中,即便取得了可能是最优解的问题空间树上的叶子节点的时候仍然会遍历其它节点以保证得到的是最优解,当对正确率的要求不是很高的时候,可以在取得第一个可能是最优解的节点时候便停止算法。本次实验使用的是 FIFO 分支限界法,若使用优先队列式分支限界法(LC),在空间复杂度上的性能肯定会得到改善,若不要求结果十分准确,使用优先队列取得第一个可能节点时候便停止算法,则在时间复杂度上的性能应该也能优于 FIFO 分支限界(优先队列采取的

10、是深度遍历,能更快到达叶子节点)。四、 算法实现框架本次实验使用的语言是 java,OriginNode 类用来按价值重量比构造排序数组,sort 方法用于数组排序(出于便于实现的考虑使用了冒泡排序,改成快速排序可获得更好的性能)。ArrayNode 类用于构造问题的解空间树上的节点。FIFOBBKnapsack 类是程序的主类,定义了 currentMaxValue 等属性,起全局变量的作用供节点共同维护,upBound 方法用于计算节点价值上限。在 FIFOBBKnapsack 类的 main 方法里定义了分支限界法的逻辑,截取主要部分如下。五、 总结在本科的时候曾经做过背包问题的项目,所

11、以本次实验我选择了 01 背包问题该题目。但在做本次实验之前,我对分支限界法的原理并不是很理解,经过查看课件及网上查找资料,同时结合自己对回溯法等的理解,我对分支限界法有了一个较好的理解,知道了两种主要的分支限界法及分支限界法如何应用于解 01 背包问题。在查找资料的过程中,我查看了许多网上的别人的代码实现,但大多都存在着问题或者混淆使用了两种分支限界法,最后通过参考别人的部分代码以及结合自己对 FIFO 分支限界法的理解,使用了 java 语言完成了该实验。通过本次试验,我基本上掌握了分支限界法解 0-1 背包问题的原理,同时锻炼了自己动手编写及调试代码的能力,收获良多。附录程序运行示例:代

12、码import java.util.LinkedList;import java.util.Scanner;public class FIFOBBKnapsack int capacity;int count;float weights;float values;OriginNode originNodes;float currentMaxValue;ArrayNode currentMaxNode;private float upBound(ArrayNode node) float weightLeft = this.capacity - node.currentWeight;float

13、bound = node.currentValue;int t = node.nodeCount;while (t arrayNodeList = new LinkedList();ArrayNode headNode = new ArrayNode(0, 0, “, 0);headNode.upboundValue = knapsack.upBound(headNode);knapsack.currentMaxValue = 0;knapsack.currentMaxNode = null;arrayNodeList.push(headNode);while (!arrayNodeList.

14、isEmpty() ArrayNode firstNode = arrayNodeList.pop();if (firstNode.nodeCount = knapsack.countcontinue;if (firstNode.upboundValue = knapsack.currentMaxValueif (leftNode.currentValue knapsack.currentMaxValue) knapsack.currentMaxValue = leftNode.currentValue;ArrayNode rightNode = new ArrayNode(firstNode

15、.currentWeight, firstNode.currentValue,firstNode.nodeChoices + “ 0“,firstNode.nodeCount + 1);rightNode.upboundValue = knapsack.upBound(rightNode);if (rightNode.upboundValue = knapsack.currentMaxValue) arrayNodeList.add(rightNode);System.out.println(“背包能装下的最大价值是:“+ knapsack.currentMaxNode.currentValu

16、e + “ 此时背包装的重量是:“+ knapsack.currentMaxNode.currentWeight);System.out.println(“物品的选择情况是:“);System.out.print(“物品重量:“);for (int i = 0; i nodesi.valuePerWeight) tmp = nodesi;nodesi = nodesj;nodesj = tmp;class ArrayNode float currentWeight;float currentValue;float upboundValue;String nodeChoices;int nodeCount;public ArrayNode(float currentWeight, float currentValue,String nodeChoices, int nodeCount) this.currentWeight = currentWeight;this.currentValue = currentValue;this.nodeChoices = nodeChoices;this.nodeCount = nodeCount;

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报