问题提出:
有一批共n个集装箱要装上2艘载重量分别为C1和C2的轮船,其中集装箱i的重量为wi,且∑wi≤C1+C2,装载问题要求确定一个合理的装载方案可将这n个集装箱装上这2艘轮船。
解空间结构:
子集树
代码:
public class loading {
//货箱数目
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 t) {
if(t>n) {//到达叶结点
if(cw>bestw) {
for(int i=1;i<=n;i++) {
bestx[i] = x[i];
}
bestw = cw;
}
return;
}
r -= w[t];
if(cw + w[t] <= c) {//搜索左子树
x[t] = 1;
cw += w[t];
backtrack(t+1);
cw -= w[t];//回溯
}
if(cw + r>bestw) {
x[t] = 0;//搜索右子树
backtrack(t+1);
}
r += w[t];//恢复现场
}
public static void main(String[] args) {
int[] ww = {0,5, 2, 1, 3};
int c1 = 10;
int n = ww.length - 1;
MaxLoading(ww,c1);
for(int i = 1;i<=n;i++) {
System.out.print(bestx[i] + " ");
}
}
}
结果截图: