算法java实现--分支限界法--0-1背包问题
来源:互联网 发布:c语言中产生随机数 编辑:程序博客网 时间:2024/05/01 19:49
布线问题的java实现(分支限界法)
具体问题描述以及C/C++实现参见网址
http://blog.csdn.net/liufeng_king/article/details/8915285
import java.util.Collections;import java.util.LinkedList;/** * 0-1背包问题 * @author Lican * *//** * 子集空间树中结点类型为BBnode * @author Lican * */class BBnode{BBnode parent;//父节点boolean leftChild;//左儿子结点标志public BBnode(BBnode par,boolean left){parent=par;leftChild=left;}}/** * 优先级队列的结点 * @author Lican * */class HeapNode implements Comparable{BBnode liveNode;//活结点double upperProfit;//结点的价值上界double profit;//结点所相应的价值double weight;//结点所相应的重量int level;//活结点在子集树种所处的层序号//构造方法HeapNode(BBnode node,double up,double pp,double ww,int lev){liveNode=node;upperProfit=up;profit=pp;weight=ww;level=lev;}@Overridepublic int compareTo(Object x) {//降序排列double xs=((HeapNode) x).upperProfit;if(upperProfit>xs) return -1;if(upperProfit==xs) return 0;return 1;}}/** * 每个背包的类 * @author Lican * */class Element implements Comparable{int id;//背包编号double d;//单位重量价值public Element(int id,double d){this.id=id;this.d=d;}@Overridepublic int compareTo(Object o) {//降序排列double xs=((Element) o).d;if(d>xs) return -1;if(d==xs) return 0;return 1;}public boolean equals(Object o){return d==((Element) o).d;}}public class BBKnapsack {public double c;//背包容量public int n;//物品总数public double[] w;//物品重量数组public double[] p;//物品价值数组public double cw;//当前重量public double cp;//当前价值public int[] bestx;//最优解public LinkedList<HeapNode> heap;//活结点优先队列//上界函数bound计算结点所相应价值的上界public double bound(int i){double cleft=c-cw;//剩余容量double b=cp;//以物品单位重量价值递减顺序装填剩余容量while(i<=n&&w[i]<=cleft){cleft-=w[i];b+=p[i];i++;}if(i<=n)b+=p[i]*cleft/w[i];return b;}public void addLiveNode(double up,double pp,double ww,int lev,BBnode par,boolean ch){BBnode b=new BBnode(par,ch);HeapNode node=new HeapNode(b,up,pp,ww,lev);heap.add(node);Collections.sort(heap);}/** * 优先队列式分支限界法,返回最大价值,bestx返回最优解 * @return */public double bbKnapsack(){//初始化BBnode enode=null;int i=1;double bestp=0.0;//当前最优解double up=bound(1);//价值上界//搜索子集空间树while(i!=n+1){//非叶节点//检查当前扩展结点的左儿子结点double wt=cw+w[i];if(wt<=c){//左儿子结点可行if(cp+p[i]>bestp){bestp=cp+p[i];}addLiveNode(up,cp+p[i],cw+w[i],i+1,enode,true);}up=bound(i+1);//检查当前扩展结点的有儿子结点if(up>=bestp){//右子树可能含有最优解addLiveNode(up,cp,cw,i+1,enode,false);}HeapNode node=heap.poll();enode=node.liveNode;cw=node.weight;cp=node.profit;up=node.upperProfit;i=node.level;}//构造当前最优解for(int j=n;j>0;j--){bestx[j]=(enode.leftChild)?1:0;enode=enode.parent;}return cp;}/** * 返回最大价值 * @param pp * @param ww * @param cc * @param xx * @return */public double knapsack(double[] pp,double[] ww,double cc,int[] xx){c=cc;n=pp.length-1;double ps=0;//统计所有背包的价值总量double ws=0;//统计所有的背包重量之和Element[] q=new Element[n];for(int i=1;i<=n;i++){q[i-1]=new Element(i,pp[i]/ww[i]);ps+=pp[i];ws+=ww[i];}if(ws<=c){//所有物品之和<=最大容量C,即可全部物品装包for(int i=1;i<=n;i++){xx[i]=1;}return ps;}//依物品单位重量价值排序java.util.Arrays.sort(q);//初始化数据成员p=new double[n+1];w=new double[n+1];for(int i=1;i<=n;i++){p[i]=pp[q[i-1].id];w[i]=ww[q[i-1].id];}cw=0;cp=0;bestx=new int[n+1];heap=new LinkedList<HeapNode>(); //调用bbKnapsack求问题的最优解double maxp=bbKnapsack();for(int i=1;i<=n;i++){xx[q[i-1].id]=bestx[i];}return maxp;}public static void main(String[] args) {double pp[]={0,2,1,4,3};double ww[]={0,1,4,2,3};double cc=8;int n=pp.length-1;int[] xx=new int[n+1];BBKnapsack b=new BBKnapsack();double maxp=b.knapsack(pp, ww, cc, xx);System.out.println("装入背包中物品总价值最大为:"+maxp);System.out.println("装入的物品的序号为:");for(int i=1;i<=n;i++){System.out.println(i+":"+xx[i]);}}}/*输出结果:装入背包中物品总价值最大为:9.0装入的物品的序号为:1:12:03:14:1 */
0 0
- 算法java实现--分支限界法--0-1背包问题
- 分支限界法的0-1背包问题Python实现
- 0-1背包问题---分支限界法
- 【算法】分支限界法实现0-1背包问题【原创技术】
- 分支限界法实现背包问题
- 0/1背包问题的分支限界
- 算法java实现--分支限界法--单源最短路径问题
- 算法java实现--分支限界法--最优装载问题
- 算法java实现--分支限界法--布线问题
- 算法java实现--分支限界法--最大团问题
- 算法java实现--分支限界法--旅行售货员问题
- 算法java实现--分支限界法--电路板排线问题
- 算法java实现--分支限界法--批处理作业调度问题
- 0036算法笔记——【分支限界法】0-1背包问题
- 0036算法笔记——【分支限界法】0-1背包问题
- 0-1背包问题之分支限界法
- 分支限界法解0-1背包问题
- 回朔法、分支限界法解0-1背包问题程序, Java, C#
- 【Unity3D】【NGUI】UICamera
- Windows无法启动OracleOraDb10g_home1TNSListener服务,错误1067
- zip_support/ioapi
- DispatchMessage是异步的吗
- Oracle基础知识(二十) - 临时表
- 算法java实现--分支限界法--0-1背包问题
- test
- 欧拉项目005:最小公倍数
- MFC 添加状态栏
- F# 20分钟快速上手(一)
- java中返回临时对象的问题,求大神破解
- 让金山词霸在 Adobe Reader XI 的 PDF 中取词
- CSS 内阴影
- 分享--linux 学习之路(学linux必看)