今晚终于把老师发布的算法题的思路理清楚了,很是开心。
这次的算法是用队列式分支限界法解决装载问题。
下面对于算法的几乎每一步都给了详细解释。需要的同学可以借鉴一下。嘻嘻。
希望大家一起共同进步呀~
//队列式分支限界法_集装箱问题
public class FIFOBBloding {
static int n;
static int bestw; // 当前最优载重量
static ArrayQueue queue; // 活结点队列
static QNode bestE;
static int [ ] bestx;
//队列中每一个结点类描述
private static class QNode
{ QNode parent;//父节点
boolean leftChild; //左儿子节点
int weight; //节点所相应的载重量
private QNode(QNode theParent,boolean theLeftChild,int theWeight)
{ parent=theParent;
leftChild=theLeftChild;
weight=theWeight;
}
}
//队列类
private static class ArrayQueue {
private static QNode[] queueElem;//队列的存储空间
private static int front;//队首引用,若队列不空,指向队首元素
private static int rear;//队尾引用,若队列不空,指向队尾元素的下一个位置
//链队列类的构造函数
public ArrayQueue() {
front=rear=0;//队首、队尾初始化
queueElem=new QNode[10];
}
//入队(循环顺序队列入队)
private static void put(QNode b) {
queueElem[rear]=b;//将b存入rear所指的数组的存储位置,并且使其成为新的队尾元素
rear=(rear+1)%queueElem.length;//修改队尾指针
}
//出队(循环顺序队列出队)
public QNode remove() {
if(front==rear)//队列为空
return null;
else
{
QNode p=queueElem[front];
front=(front+1)%queueElem.length;
return p;
}
}
//判空
public boolean isEmpty() {
return front==rear;
}
}
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; }
return; }
//非叶节点,将节点加入到活节点队列
QNode b=new QNode(parent,leftchild,wt);
queue.put(b); }
public static int maxLoading(int[] w,int c,int []xx)
{// 该算法实施对解空间树的队列式分支限界搜索,返回最优载重量
//初始化
bestw=0;
queue=new ArrayQueue();//队列用来存放活节点表。
queue.put(null); //当元素的值为空时,表示队列已到达解空间树 同一层结点尾部
QNode A=null;
QNode e=A;
bestE= A;
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);}
//检查右儿子结点
if(ew+r>bestw) enQueue(ew,i,e,false);
e=(QNode)queue.remove();//取下一扩展结点
if(e==null)
{//同层结点尾部
if(queue.isEmpty())break;
queue.put(null); //同层结点尾部标志
e=(QNode)queue.remove(); //下一扩展结点
i++; //进入下一层
r-=w[i]; //剩余集装箱重量
}
ew=e.weight;}
return bestw;
}
public static void main(String[] args) {
n=5;
int []x= new int[] {0,0,0,0,0,0};
int w[]=new int[]{0,60,40,10,30,50};
System.out.println("最优载重量为"+maxLoading(w,120,x));
for(int i=n-1;i>=1;i--) {//求出最优解
if(bestE.leftChild)
bestx[i]=1;
else
bestx[i]=0;
bestE=bestE.parent;
}
System.out.println("最优解为:");
for(int i=1;i<=n;i++)//输出最优解
System.out.print(bestx[i]);
}
}