1.问题
有n个集装箱要装上2艘载重量分别为c1和c2的轮船,其中集装箱i的重量为wi,且
是否有一个合理的装载方案,可将这n个集装箱装上这2艘轮船?如果有,找出一种装载方案。
2.解析
例如:当n=3, c1=c2=50
(1)若w=[10, 40, 40]
可将集装箱1和集装箱2装上第一艘轮船,而将集装箱3装上第二艘轮船;
(2)如果w=[20, 40, 40]
则无法将这3个集装箱都装上船;
已证明,如果一个给定装载问题有解,则采用下面的策略可得到最优装载方案。
1. 首先将第一艘轮船尽可能装满;
2. 将剩余的集装箱装上第二艘轮船。
将第一艘轮船尽可能装满等价于选取全体集装箱的一个子集,使该子集中集装箱重量之和最接近c1。由此可知,装载问题等价于以下特殊的0-1背包问题。
3.设计
核心代码
template
void Loading::Backtrack(int i)
{ / /搜索第i层结点
if (i>n) {//到达叶结点
bestw=cw;
return;
}
r - = w[i]; //搜索子树
if (cw+w[i]<=c){ //搜索左子树
x[i]=1;
cw += w[i];
Backtrack (i+1);
cw - = w[i];
}
if (cw+r > bestw){ //搜索右子树
x[i]=0;
Backtrack(i+1);
}
r+=w[i]
4.分析
时间复杂度为O(2^n)
5.源码
https://github.com/951390752/Algorithm_analysis_and_design-homework/blob/main/homework_10/backtrack.cpp