//分支限界法求最优装载
#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;
}
分支限界法求最优装载
猜你喜欢
转载自blog.csdn.net/qq_29856169/article/details/90761651
今日推荐
周排行