优先队列式分支限界法求解01背包问题Word文档格式.docx
《优先队列式分支限界法求解01背包问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《优先队列式分支限界法求解01背包问题Word文档格式.docx(25页珍藏版)》请在冰豆网上搜索。
定义堆结点类HeapNode,用于定义堆元素类型;
定义最大堆类MaxHeap,用于实现优先队列定义.物品类Object,用于保存物品编号和物品的单位重量价值;
定义解决0-1背包问题的主类Knap。
2、设计求解0-1背包问题的主函数Knapsack,在其中对物品以单位价值量排序。
3、设计负责求解0-1背包问题的最优值和最优解函数MaxKnapsack在其中调用计算结点价值上界函数Bound,向子集树和最大堆中插入结点函数AddLiveNode和释放最大堆最大结点的函数DeleteMax,实现优先级队列。
4、输入数据到input.txt文件中。
5、添加计算运行时间的代码,计算不同规模数据的运行时间,并将结果输出到output文件中。
6、分析时间复杂度:
在最坏的情况下所有的节点都入队,最后一个节点才是最优解,这种情况下时间复杂度是指数阶。
最好的情况是只装单位价值最大的物品,其余分支都不符合条件被截去这种情况下时间复杂度是常数时间。
但分支限界法本质上还是穷举法,平均时间复杂度仍是指数阶。
关键代码
//物品类
classObject{
friendTypepKnapsack(Typew*,Typep*,Typew,int,int*);
public:
intoperator<
=(Objecta)const{
return(d>
=a.d);
}
private:
intID;
//物品编号
floatd;
//单位重量价值
};
//树结点类
classbbnode{
friendclassKnap;
bbnode*parent;
//指向父节点的指针
intLChild;
//堆结点类
classHeapNode{
friendclassMaxHeap;
operatorTypep()const{returnuprofit;
Typepuprofit,//结点的价值上界
profit;
//结点所相应的价值
Typewweight;
//结点所相应的重量
intlevel;
//活结点在子集树中所处的层序号
bbnode*elemPtr;
//指向该活结点在子集树中相应结点的指针
//最大堆类
classMaxHeap{
MaxHeap(intmaxElem)
{
HeapElem=newHeapNode*[maxElem+1];
//下标为0的保留
capacity=maxElem;
size=0;
voidInsertMax(HeapNode*newNode);
HeapNodeDeleteMax(HeapNode*&
N);
intcapacity;
intsize;
HeapNode**HeapElem;
//0-1背包问题的主类
classKnap{
TypepMaxKnapsack();
MaxHeap*H;
TypepBound(inti);
voidAddLiveNode(Typepup,Typepcp,Typewcw,intch,intlevel);
bbnode*E;
//指向扩展结点的指针
Typewc;
//背包容量
intn;
//物品总数
Typew*w;
//物品重量数组(以单位重量价值降序)
Typep*p;
//物品价值数组(以单位重量价值降序)
Typewcw;
//当前装包重量
Typepcp;
//当前装包价值
int*bestx;
//最优解
voidMaxHeap:
:
InsertMax(HeapNode*newNode)
{
inti=1;
for(i=++size;
i/2>
0&
&
HeapElem[i/2]->
uprofit<
newNode->
uprofit;
i/=2)
HeapElem[i]=HeapElem[i/2];
HeapElem[i]=newNode;
}
HeapNodeMaxHeap:
DeleteMax(HeapNode*&
N)
if(size>
0)
N=HeapElem[1];
while(i<
size)
if(((i*2+1)<
=size)&
HeapElem[i*2]->
uprofit>
HeapElem[i*2+1]->
uprofit)
HeapElem[i]=HeapElem[i*2];
i=i*2;
else
if(i*2<
=size)
break;
if(i<
HeapElem[i]=HeapElem[size];
size--;
return*N;
TypepKnap:
MaxKnapsack()
H=newMaxHeap(10000);
bestx=newint[n+1];
E=0;
cw=0;
cp=0;
Typepbestp=0;
Typepup=Bound
(1);
while(i!
=n+1)
Typewwt=cw+w[i];
if(wt<
=c){
if(cp+p[i]>
bestp)
bestp=cp+p[i];
AddLiveNode(up,cp+p[i],cw+w[i],1,i);
up=Bound(i+1);
if(up>
=bestp)
AddLiveNode(up,cp,cw,0,i);
HeapNode*N;
H->
DeleteMax(N);
E=N->
elemPtr;
cw=N->
weight;
cp=N->
profit;
up=N->
i=N->
level+1;
for(inti=n;
i>
0;
i--)
bestx[i]=E->
LChild;
E=E->
parent;
returncp;
Bound(inti)
Typewcleft=c-cw;
Typepb=cp;
while(i<
=n&
w[i]<
=cleft)
cleft-=w[i];
b+=p[i];
i++;
if(i<
=n)b+=p[i]/w[i]*cleft;
returnb;
voidKnap:
AddLiveNode(Typepup,Typepcp,Typewcw,intch,intlevel)
bbnode*b=newbbnode;
b->
parent=E;
LChild=ch;
HeapNode*N=newHeapNode;
N->
uprofit=up;
profit=cp;
weight=cw;
level=level;
elemPtr=b;
InsertMax(N);
//Knapsack返回最大价值,最优值保存在bestx
TypepKnapsack(Typew*w,Typep*p,Typewc,intn,int*bestx)
{
TypewW=0;
TypepP=0;
Object*Q=newObject[n];
for(inti=1;
i<
=n;
i++)
Q[i-1].ID=i;
Q[i-1].d=1.0*p[i]/w[i];
P+=p[i];
W+=w[i];
if(W<
=c)
bestx[i]=p[i];
returnP;
for(inti=1;
n;
for(intj=1;
j<
=n-i;
j++)
if(Q[j-1].d<
Q[j].d)
Objecttemp=Q[j-1];
Q[j-1]=Q[j];
Q[j]=temp;
KnapK;
K.p=newTypep[n+1];
K.w=newTypew[n+1];
K.p[i]=p[Q[i-1].ID];