收藏 分享(赏)

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

上传人:s36f12 文档编号:4123433 上传时间:2018-12-10 格式:DOCX 页数:12 大小:150.96KB
下载 相关 举报
分支限界法解01背包问题.docx_第1页
第1页 / 共12页
分支限界法解01背包问题.docx_第2页
第2页 / 共12页
分支限界法解01背包问题.docx_第3页
第3页 / 共12页
分支限界法解01背包问题.docx_第4页
第4页 / 共12页
分支限界法解01背包问题.docx_第5页
第5页 / 共12页
点击查看更多>>
资源描述

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营业执照举报