优先队列式分支限界法 轮船装载问题(集装箱问题)

上一次介绍了集装箱装载问题的队列式分支限界法,本次将分享优先队列式分支限界法解决这个问题的算法。
Problem:
装载问题的问题提出是,有一批共n个集装箱要装上2艘载重量分别为 c1和c2 的轮船,其中集装箱i的重量为 wi,且(集装箱总重量和)w<=c1+c2 。问是否有一个合理的装载方案能将这n个集装箱装上这两艘轮船。
由于 王晓东先生著的《算法设计与分析》里面的代码由于缺少了最大堆类的描述,所以并不能运行,这里对该算法进行了增加与修改。若有需要的同学可以参考一下。

//优先队列式分支限界法_集装箱装载问题
public class PriorityBBloding {
// 优先队列式分支限界法,返回最优载重量 bestx返回最优解
static MaxHeap heap=new MaxHeap();
static int n;//集装箱数量
static class BBNode//解空间树的结点类
{
BBNode parent; //指向父结点的指针
boolean leftChild; //左儿子结点标志
BBNode(BBNode par,boolean ch)
{ parent=par;
leftChild=ch;
}
}

 static class HeapNode implements Comparable//堆的元素类型类
 {  BBNode liveNode; //指向活结点在子集树中相应结点的指针
     int  uweight; //活结点优先级(上界)
     int  level; //活结点在子集树中所处的层序号 
     HeapNode(BBNode node,int up,int lev)
       {//构造方法
         liveNode=node;
         uweight=up;
         level=lev;      }
      public int compareTo(Object x)
       {
        int xuw=((HeapNode)x).uweight;
        if(uweight=front;i--) {//创建堆
			 sift(i,n);
		 }
	 }
	 //取出堆顶元素,并且重新调整堆为最大堆的算法
	 static HeapNode removeheapSort() {
		 int n=rear-front;//
		 int i=n-1;//堆的最后一个结点
		 HeapNode temp=maxheap[front];//将堆中最小关键字值移到最前面
		 maxheap[front]=maxheap[i];
		 sift(front,i);//并且调整成堆
		 return temp;//返回最顶堆结点 
	 }
	//将堆元素node加入堆,并且调整堆
	 static void insert(HeapNode node) {
		 maxheap[rear]=node;
		 rear+=1;//修改尾指针
		 insertheapSort();//调整堆
	 }
	//将堆顶元素取出,并且调整堆
	public HeapNode removeMax() {
		HeapNode temp=removeheapSort();
		rear-=1;
		return temp;
	}
 }

 public static int maxLoading(int[] w,int c,int []bestx)
   {
       // 初始化
       BBNode A=null;
        BBNode e= A;        //当前扩展结点        
        int i=1;                     //当前扩展结点所处的层
        int ew=0;                    //扩展结点所相应的载重量
        int [ ]r=new int[n+1];        //定义剩余重量数组r
        for(int j=n-1;j>=0;j--)
         {r[j]=r[j+1]+w[j+1];}
 
      //搜索子集空间树
        while(i!=n+1)
        {//非叶结点,检查当前扩展结点的儿子结点
          if(ew+w[i]<=c)  
          //左儿子结点为可行结点
          addLiveNode(ew+w[i]+r[i],i+1,e,true);        
         // 右儿子结点总为可行结点 
          addLiveNode(ew+r[i],i+1,e,false); 
         //取下一个扩展结点       
        HeapNode node=(HeapNode)heap.removeMax();
        i=node.level;
        e=node.liveNode; //下一扩展结点
        ew=node.uweight-r[i-1];
       }
     for(int j=n;j>0;j--)
     {//构造当前最优解
      bestx[j]=(e.leftChild)?1:0;
      e=e.parent;
     }
    return ew;
   }
 
public static void main(String[] args) {
	n=5;//集装箱个数
	int []w= {0,60,40,10,30,50};//集装箱重量
	int c=120;//轮船载重量
	int[] bestx=new int[n+1];//最优解
	int a=maxLoading(w,c,bestx);
	System.out.println("最优载重量为:"+a);
	System.out.println("最优解为:");
	for(int i=1;i

}

优先队列式分支限界法 轮船装载问题(集装箱问题)_第1张图片

你可能感兴趣的:(优先队列式分支限界法 轮船装载问题(集装箱问题))