题目概述
设n=3, c1 =30, c2 =30, w={16, 15, 15},n为集装箱数量,c1和c2代表两艘轮船的装载量,w数组代表着集装箱的重量,采用队列式分支限界算法解决该装载问题,问是否有一个合理的装载方案能够将n个集装箱装上这两艘轮船?
题目分析
上述对两艘轮船的装载问题可简化成对装载量较小的一艘轮船装载问题,使得这艘装载量较小的轮船装进总质量最多的集装箱即可。
效果图
代码实现
FIFOBBloding 类中的代码:
import java.util.LinkedList;
import java.util.Queue;
public class FIFOBBloding {
private static void enQueue(int wt, int i, QNode parent, boolean leftchild){
if(i == n) {
if(wt == bestw) {
bestE = parent;
bestx[n] = (leftchild)?1:0;
for(int j = n-1; j >0; j--) {
bestx[j] = (bestE.leftChild)?1:0;
//System.out.println("bestx[" + j + "] = " + bestx[j]);
bestE = bestE.parent;
}
}
return;
}
QNode b = new QNode(parent, leftchild, wt);
queue.offer(b);
}
static int n;
static int bestw;
static Queue<QNode> queue;
static QNode bestE;
static int[] bestx;
static int[] w;
public static int maxLoading(int[] w, int c, int[] xx){
queue = new LinkedList<QNode>();
bestw = 0;
queue.offer(null);
QNode e = new QNode(null, true, 0);
bestE = e;
bestx = xx;
int i = 1;
int ew = 0;
int r = 0;
for(int j = 2; j <= n; j++)
r += w[j];
while(true){
int wt = ew + w[i];
if(wt <= c) {
if(wt > bestw) {
bestw = wt;
}
enQueue(wt, i, e, true);
}
//System.out.println("r = " + r);
if(ew+r >= bestw)
enQueue(ew, i, e, false);
e =(QNode) queue.poll();
if(e == null) {
if(queue.isEmpty())
break;
queue.offer(null);
e = (QNode) queue.poll();
i++;
r-=w[i];
}
ew = e.weight;
}
System.out.println("最优解为:");
for(int k = 1; k <= n; k++) {
System.out.print(bestx[k] + " ");
}
System.out.println();
return bestw;
}
public static void main(String[] args) throws Exception {
int c2 = 30;
int c1 = 30;
int c = c1 <c2 ? c1 : c2;
int flag = -1;
int[] ww= {flag, 16, 15, 15};
w = ww;
n = w.length-1;
bestx = new int[w.length];
int value = maxLoading(w, c, bestx);
System.out.println("可装载的最大重量为:" + value);
}
}
QNode 类中的代码:
public class QNode {
QNode parent;
boolean leftChild;
int weight;
QNode(QNode theParent, boolean theLeftChild, int theWeight) {
this.parent = theParent;
this.leftChild = theLeftChild;
this.weight = theWeight;
}
}
代码解析
- i为当前扩展结点所在的层,当出队的元素为null时,i++
- ew为扩展结点相应的质量,即每次装进集装箱的重量
- r为剩余集装箱的总重量
- wt<=c:约束函数,检查扩展的左孩子结点
- ew+r >= bestw:限定函数,检查扩展的右孩子结点