算法分析与设计实验报告第八次附加实验
for(int i=1;i<n;i++)
cout<<bestx[i]<<",";
cout<<bestx[n]<<")"<<endl;
}
测试结果
当输入物品数量较少时:
当输入物品数量较一般时:
当输入物品数量较大时:
实验心得
最优装载就是求解载重量最好的载重方案,之前最优装载采用了贪心算法,这里使用的使分支限界法;其实在使用分支限界法进行了单源最短路径的
实现之后,在完成这个实验就显得更简单一点。
分支限界法的算法思想本身还
是很好理解的,但是在这个问题中由于涉及到了剪枝的问题,所以新加入了一
个0来判断一层是否结束,因为在一层结束的时候,代表该集装箱的情况已经
考虑完了,需要考虑下一个集装箱,这个时候就需要更新剩余集装箱的重量,
这会影响到一个右子树是否会被剪掉,因此要特别注意。
完整代码(分支限界法)
//分支限界法求最优装载
#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; //当前扩展节点的层数,此时为
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)
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;
}
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;
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;
system("pause");
return 0;
}。