装载问题的java实现(回溯法)
具体问题描述以及C/C++实现参见网址
http://blog.csdn.net/liufeng_king/article/details/8762073
package tanxin; /** * 装载问题–回溯法 * @author Lican * */ public class load { static int n;//集装箱数目 static int[] w;//集装箱重量数组 static int c;//第一艘轮船的载重量 static int cw;//当前载重量 static int bestw;//当前最优载重量 static int r;//剩余集装箱重量 static int[] x;//当前解,记录从根至当前节点的路径 static int[] bestx;//记录当前最优解 public static int maxLoading(int[] ww,int cc){ //初始化类数据成员,数组下标从1开始 n=ww.length-1; w=ww; c=cc; cw=0; bestw=0; x=new int[n+1]; bestx=new int[n+1]; //初始化r,即剩余最大重量 for(int i=1;i<=n;i++){ r+=w[i]; } //计算最优载重量 backtrack(1); return bestw; } //回溯算法 public static void backtrack(int i){ //搜索第i层节点 if(i>n){//到达叶节点 if(cw>bestw){ for(int j=1;j<=n;j++){ bestx[j]=x[j]; } bestw=cw; } return; } r-=w[i]; if(cw+w[i]<=c){//搜索左子树(约束函数) x[i]=1;//左子树标志为1 cw+=w[i]; backtrack(i+1);//搜索下一层 cw-=w[i];//恢复现场,因为cw是全局变量 } if(cw+r>bestw){//搜索右子树(限界函数) x[i]=0;//右子树标志为0 backtrack(i+1); } r+=w[i];//恢复现场,r是全局变量 } public static void main(String[] args) { int[] w={0,10,40,40}; int c1=50; int c2=50; int n=w.length-1; int weight1=maxLoading(w,c1); int weight2=0;//保存第2艘船可能要装的重量 for(int i=1;i<=n;i++) weight2+=w[i]*(1-bestx[i]);//剩余未装入的集装箱全部装入第二艘船,bestx[i]为1或者0 if(weight2>c2) System.out.println(“无法将全部集装箱装入两艘船。”); else{ System.out.println(“第一艘船装入的重量是:”+weight1); System.out.println(“第二艘船装入的重量是:”+weight2); for(int i=1;i<=n;i++){ if(bestx[i]==1) System.out.println(“集装箱”+i+”装入第一艘船;”); else System.out.println(“集装箱”+i+”装入第二艘船;”); } } } } /* 输出: 第一艘船装入的重量是:50 第二艘船装入的重量是:40 集装箱1装入第一艘船; 集装箱2装入第一艘船; 集装箱3装入第二艘船; */