分支限界法求最优装载

//分支限界法求最优装载
#include <iostream>
#include <time.h>
#include <iomanip>
#include <queue>
using namespace std;

class QNode
{
	friend void Enqueue(queue<QNode *>&,int,int,int,int,QNode *,QNode *&,int *,bool);
	friend void Maxloading(int *,int,int,int *);
	private:
		QNode *parent; //指向父节点的指针
		bool LChild;  //左儿子标志,用来表明自己是否为父节点的左儿子
		int weight;   //节点所相应的载重量,已累加前面的已装入的物品重量 
}; 

void Enqueue(queue<QNode *>&Q,int wt,int i,int n,int bestw,QNode *E,QNode *&bestE,int bestx[],bool ch)
{
	//将活节点加入到队列中
	if(i==n) //到达叶子节点
	{
		if(wt==bestw) //确保当前解为最优解
		{
			bestE=E;
			bestx[n]=ch;
		} 
		return;
	}
	
	//当不为叶子节点时,加入到队列中,并更新载重、父节点等信息 
	QNode *b;
	b=new QNode;
	b->weight=wt;
	b->parent=E;
	b->LChild=ch;
	Q.push(b);  
}

void Maxloading(int w[],int c,int n,int bestx[]) //其中w[]为重量数组
{   // c为船的总载重量,n为节点数 
	//初始化
	queue<QNode *> Q; //活节点队列
	Q.push(0); //将第一个节点加入队列中,并用0表示同层节点的尾部标志
	int i=1; //当前扩展节点的层数,此时为1
	int Ew=0; //扩展结点相应的载重量
	int bestw=0; //当前最优载重量 
	int r=0; //剩余集装箱的重量
	for(int j=2;j<=n;j++) //求得最初的剩余载重量 
		r+=w[j];  
		
	QNode *E =0; //当前扩展节点
	QNode *bestE; //当前最优扩展节点
	
	//搜索子集空间树
	while(true)
	{
		//首先检查左儿子节点
		int wt=Ew+w[i];
		if(wt<=c) //左儿子节点为可行结点 
		{
			if(wt>bestw)
				bestw=wt;
		    Enqueue(Q,wt,i,n,bestw,E,bestE,bestx,true);//将左节点加入队列 
		} 
		
		//检查右儿子节点,利用上界函数
		if(Ew+r>=bestw) //当Ew+r<=bestW时,可以把右子树剪去,if判断语句可不需要等号 
			Enqueue(Q,Ew,i,n,bestw,E,bestE,bestx,false);//将右节点加入队列
			
		E=Q.front(); //取出当前扩展节点
		Q.pop(); 
		
		if(!E) //到达同层的最末,此时需要更新剩余装箱载重量
		{
			if(Q.empty()) break; //此时队列为空
		    Q.push(0); //加入0,表示该层结束
			E=Q.front();
			Q.pop();
			i++; //进入下一层 
			r-=w[i];//更新剩余集装箱的值 
		}
		Ew=E->weight; //新扩展的节点对应的载重量 
	} 
	
	//构造当前最优解
	for(int j=n-1;j>0;j--)
	{
		bestx[j]=bestE->LChild;
		bestE=bestE->parent;
	}
	
	cout<<"最优载重量为:"<<bestw<<endl;
	cout<<"最优载重方式:"<<"("; 
	for(int i=1;i<n;i++)
		cout<<bestx[i]<<",";
	cout<<bestx[n]<<")"<<endl;
}

//解决问题,并计算程序运行时间 
void time(int* w,int c,int n,int* bestx)
{
	clock_t start,end,over;
	start=clock();
	end=clock();
	over=end-start;
	start=clock();
	Maxloading(w,c,n,bestx);
	cout<<"The time is "<<((double)(end-start-over)/CLK_TCK)<<endl; 
} 

int main()
{
	int n;
	cout<<"please input number of node:";
	cin>>n;
	int *w=new int[n+1];
	int *bestx=new int[n+1]; //最优解向量
	cout<<"please input weight:"<<endl;
	for(int i=1;i<=n;i++)
		cin>>w[i];
	int c; 
    cout<<"please input limit weight:";
	cin>>c;
	
	time(w,c,n,bestx);
	
	system("pause");
	
	return 0;
}
发布了23 篇原创文章 · 获赞 13 · 访问量 3004

猜你喜欢

转载自blog.csdn.net/qq_29856169/article/details/90761651