队列式分支限界法 装载问题

今晚终于把老师发布的算法题的思路理清楚了,很是开心。
这次的算法是用队列式分支限界法解决装载问题。
下面对于算法的几乎每一步都给了详细解释。需要的同学可以借鉴一下。嘻嘻。
希望大家一起共同进步呀~

//队列式分支限界法_集装箱问题
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]);
	

}

}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值