Java语言描述:分支限界法之01背包问题
来源:互联网 发布:公司公司招聘数据 编辑:程序博客网 时间:2024/05/18 21:41
问题描述:
已知:有一个容量为V的背包和N件物品,第i件物品的重量是weight[i],收益是value[i]。
限制:每种物品只有一件,可以选择放或者不放
问题:在不超过背包容量的情况下,最多能获得多少价值或收益。
/* * 本代码实现了运用优先队列式分支限界法解决了01背包问题。解决问题的大致思想和前2篇博客的回溯法 * 大致相同,都属于搜索算法,不过实现方式上略有不同。对于子集树问题,利用优先队列式分支限界法 * 的关键之一就是要确定优先级的设置。在本代码中,优先级设置为每个节点处能够取到的价值上界。 * 对于寻找剩余物品的最高价值上界,按照背包中剩余空间依次取剩下的物品,当空间不足以取下一个 * 物品时,则将下一个物品的单位重量价值折算到现在的剩余空间中去计算理想最高上界。计算出某个 * 节点的上界后,比较上界和已经找到的最大值之间的关系。 * 当然,首先要背包中的物品按照单位重量价值进行排序,方便于后面右子树的剪枝操作。 * 在本代码中,省略了该排序过程,在初始化物品的重量和价值时,已经按照单位重量的价值排好了序。 * * 剪枝函数: * 对于向左搜索,可以通过是否超过背包容量和该节点价值上界能否超过最大值进行剪枝。 * 对于向右搜索,则可以用其父节点的上界减去本层物品的价值,即可得到右边节点的上界。 * */package BranchAndBounding;import java.util.PriorityQueue;//定义节点中的参数以及优先级设置的对象class thingNode implements Comparable<thingNode>{int weight;//该节点目前背包中的重量double value;//该节点目前背包中的总价值double upprofit;//该节点能够达到的价值上界int Left; //该节点是否属于左节点(用于最终构造最优解)int level; //该节点是第几个物品的选择thingNode father; //该节点的父节点public int compareTo(thingNode node){if(this.upprofit<node.upprofit)return 1;else if(this.upprofit == node.upprofit)return 0;elsereturn -1;}}public class bag01 {int n = 5;int capacity = 10;int[] weight = {2,6,4,1,5};double[] value = {6,9,6,1,4};int maxValue = 0;int[] bestWay = new int[n];public void getMaxValue(){PriorityQueue<thingNode> pq = new PriorityQueue<thingNode>();//构造一个初始化节点,属于-1层thingNode initial = new thingNode();initial.level = -1;initial.upprofit = 26;pq.add(initial);while(!pq.isEmpty()){thingNode fatherNode = pq.poll();//当已经搜索到叶子节点时if(fatherNode.level == n-1){if(fatherNode.value > maxValue){maxValue = (int)fatherNode.value;for(int i=n-1;i>=0;i--){bestWay[i] = fatherNode.Left;fatherNode = fatherNode.father;}}}else{//先统计其左节点信息,判断是否加入队列。if(weight[fatherNode.level+1]+fatherNode.weight <= capacity){thingNode newNode = new thingNode();newNode.level = fatherNode.level+1;newNode.value = fatherNode.value + value[fatherNode.level+1];newNode.weight = weight[fatherNode.level+1]+fatherNode.weight;newNode.upprofit = Bound(newNode);newNode.father = fatherNode;newNode.Left = 1;if(newNode.upprofit > maxValue)pq.add(newNode);}//向右节点搜索,其能够取到的价值上界通过父亲节点的上界减去本层物品的价值。if((fatherNode.upprofit - value[fatherNode.level+1])> maxValue){thingNode newNode2 = new thingNode();newNode2.level = fatherNode.level+1;newNode2.value = fatherNode.value;newNode2.weight = fatherNode.weight;newNode2.father = fatherNode;newNode2.upprofit = fatherNode.upprofit - value[fatherNode.level+1];newNode2.Left = 0;pq.add(newNode2);}}}}//用于计算该节点的最高价值上界public double Bound(thingNode no){double maxLeft = no.value;int leftWeight = capacity - no.weight;int templevel = no.level;//尽力依照单位重量价值次序装剩余的物品while(templevel <= n-1 && leftWeight > weight[templevel] ){leftWeight -= weight[templevel];maxLeft += value[templevel];templevel++;}//不能装时,用下一个物品的单位重量价值折算到剩余空间。if( templevel <= n-1){maxLeft += value[templevel]/weight[templevel]*leftWeight;}return maxLeft;}public static void main(String[] args){bag01 b = new bag01();b.getMaxValue();System.out.println("该背包能够取到的最大价值为:"+b.maxValue);System.out.println("取出的方法为:");for(int i : b.bestWay)System.out.print(i+" ");}}
程序运行结果:
0 0
- Java语言描述:分支限界法之01背包问题
- Java语言描述:分支限界法之单源最短路径问题(全网独家)
- 0-1背包问题之分支限界法
- 算法java实现--分支限界法--0-1背包问题
- 分支限界——01背包问题
- 分支限界法实现背包问题
- (C++)分支限界法求解背包问题
- 0-1背包问题---分支限界法
- 商旅问题的分支限界法 java语言实现
- 装载问题之分支限界法
- 分支限界法之最大团问题
- TSP问题之分支限界法
- 回朔法、分支限界法解0-1背包问题程序, Java, C#
- 分支限界法的0-1背包问题Python实现
- 分支限界法解0-1背包问题
- 最优装载问题或者01背包问题的分支限界法求解
- 分支限界法之LC 0/1背包
- 0/1背包问题的分支限界
- Combination Sum III Leecode Java
- Linux--内核Uevent事件机制 与 Input子系统
- Android25_ActionBar
- jQuery中的小知识:first-child和first-of-type的区别
- 只获得当前一个对象数据实现
- Java语言描述:分支限界法之01背包问题
- linux下安装mysql5.5.x的过程笔记
- 《机器学习实战》学习笔记——kNN算法
- hdu 1025 Constructing Roads In JGShining’s Kingdom 【dp+二分】
- Java反射机制详解。
- 顺手笔记---javac,javap,javah
- nginx + FastDFS分布式文件服务器搭建及配置
- Android:横行滚动且隔行变色的ListView控件
- C++对象模型:第2章(1)-构造函数