01背包问题分支限界java_分支限界法-01背包问题
1、分支限界法介绍
分支限界法类似于回溯法,也是在问题的解空间上搜索问题解的算法。一般情况下,分支限界法与回溯法的求解目标不同。回溯法的求解目标是找出解空间中满足约束条件的所有解;而分支限界法的求解目标则是找出满足约束条件的一个解,或是在满足约束条件的解中找出使某一目标函数值达到极大或极小的解,即在某种意义下的最优解。
由于求解目标不同,导致分支限界法与回溯法对解空间的搜索方式也不相同。回溯法以深度优先的方式搜索解空间,而分支限界法则以广度优先或以最小耗费优先的方式搜索解空间。
分支限界法的搜索策略是,在扩展结点处,先生成其所有的儿子结点(分支),然后再从当前的活结点表中选择下一扩展结点。为了有效地选择下一扩展结点,加速搜索的进程,在每一个活结点处,计算一个函数值(限界),并根据函数值,从当前活结点表中选择一个最有利的结点作为扩展结点,使搜索朝着解空间上有最优解的分支推进,以便尽快地找出一个最优解。这种方式称为分支限界法。人们已经用分支限界法解决了大量离散最优化的问题。
2、常见的两种分支限界法 队列式(FIFO)分支限界法:按照先进先出原则选取下一个节点为扩展节点。 活结点表是先进先出队列。
LIFO分支限界法:活结点表是堆栈。
LC(least cost)分支限界法(优先队列式分支限界法):按照优先队列中规定的优先级选取优先级最高的节点成为当前扩展节点。 活结点表是优先权队列,LC分支限界法将选取具有最高优先级的活结点出队列,成为新的E-结点。
FIFO分支限界法搜索策略:
§一开始,根结点是唯一的活结点,根结点入队。
§从活结点队中取出根结点后,作为当前扩展结点。
§对当前扩展结点,先从左到右地产生它的所有儿子,用约束条件检查,把所有满足约束函数的儿子加入活结点队列中。
§再从活结点表中取出队首结点(队中最先进来的结点)为当前扩展结点,……,直到找到一个解或活结点队列为空为止。
优先队列式分支限界法搜索策略:
§对每一活结点计算一个优先级(某些信息的函数值);
§根据这些优先级从当前活结点表中优先选择一个优先级最高(最有利)的结点作为扩展结点,使搜索朝着解空间树上有最优解的分支推进,以便尽快地找出一个最优解。
§再从活结点表中下一个优先级别最高的结点为当前扩展结点,……,直到找到一个解或活结点队列为空为止。
3、解决01背包问题算法的思想
01背包问题状态空间树 FIFO限界:若当前分支的“装载的价值上界”,比现有的最大装载的价值小,则该分支就无需继续搜索。
队列式分支法
队列式分支限界法 优先队列限界:优先队列搜索得到当前最优解作为一个“界”,对上界(或下界)不可能达到(大于)这个界的分支则不去进行搜索,这样就缩小搜索范围,提高了搜索效率。
优先队列式分支法
优先队列式分支限界法
算法首先检查当前扩展结点的左儿子结点的可行性。如果该左儿子结点是可行结点,则将它加入到子集树和活结点优先队列中。当前扩展结点的右儿子结点一定是可行结点,仅当右儿子结点满足上界约束时才将它加入子集树和活结点优先队列。当扩展到叶节点时为问题的最优值。
上界函数
1: // maxBound函数求最大上界
2: private double maxBound(int t) {
3: double left = max - c_weight, b = c_value;
4: // 剩余容量和价值上界
5: while (t < n && weight[t] <= left)
6: // 以物品单位重量价值递减装填剩余容量
7: {
8: left -= weight[t];
9: b += value[t];
10: t++;
11: }
12: if (t < n)
13: b += value[t] / weight[t] * left;
14: // 装填剩余容量装满背包
15: return b;
16: }
分支限界算法
1: int i = 0;
2: double upper = maxBound(i);
3: // 调用MaxBound求出价值上界,best为最优值
4: while (true)
5: // 非叶子结点
6: {
7: double wt = c_weight + weight[i];
8: if (wt <= max)
9: // 左儿子结点为可行结点
10: {
11: if (c_value + value[i] > bestv)
12: bestv = c_value + value[i];
13: addLiveNode(upper, c_value + value[i], c_weight + weight[i],
14: i + 1);
15: }
16: upper = maxBound(i + 1);
17: if (upper >= bestv) // 右子数可能含最优解
18: addLiveNode(upper, c_value, c_weight, i + 1);
19: if (heap.empty())
20: return bestv;
21: HeapNode node = heap.peek();
22: // 取下一扩展结点
23: heap.pop();
24: c_weight = node.weight;
25: c_value = node.value;
26: upper = node.upper;
27: i = node.level;
28: }
4、算法实现
1: import java.util.Stack;
2:
3: class HeapNode {
4: double upbound; // 结点的价值上界
5: double value; // 结点所对应的价值
6: double weight; // 结点所相应的重量
7:
8: int level; // 活节点在子集树中所处的层序号
9:
10: public HeapNode() {
11: }
12: }
13:
14: // 分支限界法实现01背包问题
15: public class BB_Knapsack01 {
16:
17: int[] weight;
18: int[] value;
19: int max; // 背包的最大承重量
20:
21: int n;
22:
23: double c_weight; // 当前背包重量
24: double c_value; // 当前背包价值
25:
26: double bestv; // 最优的背包价值
27:
28: Stack heap;
29:
30: public BB_Knapsack01() {
31: weight = new int[] { 15, 16, 15, 0 };
32: value = new int[] { 25, 45, 25, 0 };
33: max = 30;
34:
35: n = weight.length - 1;
36:
37: c_weight = 0;
38: c_value = 0;
39: bestv = 0;
40:
41: heap = new Stack();
42: }
43:
44: // 求子树的最大上界
45: private double maxBound(int t) {
46: double left = max - c_weight;
47: double bound = c_value;
48: // 剩余容量和价值上界
49: while (t < n && weight[t] <= left) {
50: left -= weight[t];
51: bound += value[t];
52: t++;
53: }
54: if (t < n)
55: bound += (value[t] / weight[t]) * left; // 装填剩余容量装满背包
56: return bound;
57: }
58:
59: // 将一个新的活结点插入到子集树和最大堆heap中
60: private void addLiveNode(double upper, double cvalue, double cweight,
61: int level) {
62: HeapNode node = new HeapNode();
63: node.upbound = upper;
64: node.value = cvalue;
65: node.weight = cweight;
66: node.level = level;
67: if (level <= n)
68: heap.push(node);
69: }
70:
71: // 利用分支限界法,返回最大价值bestv
72: private double knapsack() {
73: int i = 0;
74: double upbound = maxBound(i);
75: // 调用maxBound求出价值上界,bestv为最优值
76: while (true) // 非叶子结点
77: {
78: double wt = c_weight + weight[i];
79: if (wt <= max)// 左儿子结点为可行结点
80: {
81: if (c_value + value[i] > bestv)
82: bestv = c_value + value[i];
83: addLiveNode(upbound, c_value + value[i], c_weight + weight[i],
84: i + 1);
85: }
86: upbound = maxBound(i + 1);
87: if (upbound >= bestv) // 右子树可能含最优解
88: addLiveNode(upbound, c_value, c_weight, i + 1);
89: if (heap.empty())
90: return bestv;
91: HeapNode node = heap.peek();
92: // 取下一扩展结点
93: heap.pop();
94: //System.out.println(node.value + " ");
95: c_weight = node.weight;
96: c_value = node.value;
97: upbound = node.upbound;
98: i = node.level;
99: }
100: }
101:
102: public static void main(String[] args) {
103: // TODO Auto-generated method stub
104: BB_Knapsack01 knap = new BB_Knapsack01();
105: double opt_value = knap.knapsack();
106: System.out.println(opt_value);
107: }
108: }
01背包问题分支限界java_分支限界法-01背包问题相关推荐
- 分支限界法 01背包 java_分支限界法解决01背包问题
分支限界法和之前讲的回溯法有一点相似,两者都是在问题的解的空间上搜索问题的解.但是两者还是有一些区别的,回溯法是求解在解的空间中的满足的所有解,分支限界法则是求解一个最大解或最小解.这样,两者在解这一 ...
- 分支限界法 01背包c语言,算法笔记分支限界法01背包问题
<算法笔记分支限界法01背包问题>由会员分享,可在线阅读,更多相关<算法笔记分支限界法01背包问题(12页珍藏版)>请在人人文库网上搜索. 1.问题描述给定n种物品和一背包.物 ...
- c语言 用回溯算法解决01背包问题,回溯法解决01背包问题
<回溯法解决01背包问题>由会员分享,可在线阅读,更多相关<回溯法解决01背包问题(21页珍藏版)>请在人人文库网上搜索. 1.回溯法解决01背包问题,回溯法解决01背包问题, ...
- 多维多重背包问题_满满干货!背包问题全总结(带c++源码)
目录: 动态规划简介 0-1 背包问题 完全背包问题 多重背包问题 混合背包问题 二维(多维)费用背包问题 分组的背包问题 有依赖的背包问题 动态规划简介 在学习背包问题之前需要对动态规划有一定的了解 ...
- 经典背包问题3——背包问题求方案数 、背包问题求具体方案
经典背包问题3--背包问题求方案数 .背包问题求具体方案 1. 背包问题求方案数 2. 背包问题求具体方案 1. 背包问题求方案数 有 N 件物品和一个容量是 V的背包.每件物品只能使用一次. 第 i ...
- (2012.01.12-2012.04.01)八十二天的学习小记
(2012.01.12-2012.04.01)八十二天的学习小记 哈哈,原来又是过了八十二个日子了,真快啊~这次发的学习小记日期记录时间有点长,回看1月份的东西,原来已经隔了八十多个日子了,对于这 ...
- 三天打鱼两天晒网。一年365天,连续工作三天后休息两天,休息日水平下降0.01,工作日要努力到什么程度,一年后的水平才能与每周工作五天休息两天(工作日上升0.01,休息日下降0.01)取得的效果一样呢
文章目录 前言 一.解析 二.使用步骤 代码 结果 总结 前言 三天打鱼两天晒网.一年365天,连续工作三天后休息两天,休息日水平下降0.01,工作日要努力到什么程度,一年后的水平才能与每周工作五天休 ...
- 背包问题(多重背包+0-1背包)
一:0-1背包问题 #include<iostream> #include<algorithm> #include<cstring> const int maxn= ...
- python 完全背包问题_动态规划——背包问题python实现(01背包、完全背包、多重背包)...
参考: 描述: 有N件物品和一个容量为V的背包. 第i件物品的体积是vi,价值是wi. 求解将哪些物品装入背包,可使这些物品的总体积不超过背包流量,且总价值最大. 二维动态规划 f[i][j] 表示只 ...
最新文章
- compareHist函数
- 【论文解读】FcaNet:频率通道注意力网络论文解读
- Scala 求三个数中的最大数代码示例
- #ifndef.#define, #endif 的用法
- 35.NO module named zlib
- 前端:JS/29/实例:控制div显示_滚动的图片
- 反演控制 matlab,基于matlab的反演程序
- android 项目 功能 源码 eclipse的
- 浅谈js与jq给新增元素动态绑定事件(事件委托)
- Python编程输出所有的“水仙花数”
- CSS综合案例——淘宝焦点图(轮播图)布局及网页布局总结
- eclipse导入html页面乱码,Eclipse导入项目乱码问题(中文乱码)
- vue-video-player文档_vue使用video和vue-video-player并且可实现视频铺满呦
- idea运行SSM项目配置tomcat及启动
- html ui动画效果图,20种炫酷的菜单线条动画特效UI设计效果_html/css_WEB-ITnose
- MYSQL5.7多线程复制原理
- 全面解析大数据解决方案的架构层
- office2003、2010、2013下载资源
- 考研807程序设计C语言教程,中央财经大学
- 国内交互智能平板品类首创者希沃联手倍市得,进一步蓄力品牌发展势能