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
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小学三年级学生不听话怎么办 司法考试成绩单没打印怎么办 高一200分怎么办 初一孩子语文差怎么办 大学专业没选好怎么办 减肥口渴的厉害怎么办 开胸手术后胸闷气短怎么办 打游戏上网成瘾怎么办 老公打游戏成瘾怎么办 我老是沉迷游戏怎么办 18孩子沉迷游戏怎么办 志愿提交码丢失怎么办 幼儿园报名没进怎么办 考完教师资格证怎么办 两套房改房怎么办 cad打开无响应怎么办 高中生脸上痘痘怎么办 孩子玩心太大怎么办 开会听不懂讲什么怎么办 在国外玩手游老是进不去怎么办 广东普法考试不合格怎么办 尔雅考试错过了怎么办 大四考试错过了怎么办 电大考试错过了怎么办 吃了桂圆咳嗽怎么办 初中生游戏网瘾怎么办 孩子染上网瘾怎么办 郑州孩子厌学有网瘾怎么办 孩子网瘾严重怎么办 学生上课玩手机怎么办 老脱发怎么办才好 好几个月不来月经怎么办 电脑辐射脸上起痘痘怎么办 脸被手机辐射怎么办 宝宝沉迷于电视怎么办 青少年长了白发怎么办 刮胡子刮多了怎么办 孩子就不学习怎么办 长大了内心脆弱怎么办 10岁不想长大怎么办 18青少年血压高怎么办