#include <iostream>
#include<queue>
#define N 5
#define W 10
/*
2 6
2 3
6 5
5 4
4 6
测试用例
另:solve1()为队列式分支界限法求解结果
solve2()为优先队列式分支界限法求解结果
*/
using namespace std;
class Pack
{
public:
int cw,cp,isleft,level;
Pack *parent;
Pack(){}
Pack(int weight,int value,int Isleft,int Level,Pack* p)
{
cw=weight;
cp=value;
isleft=Isleft;
level=Level;
parent=p;
}
};
class Pack1
{
public:
int cw,cp,isleft,level,up;
Pack1 *parent;
Pack1(){}
Pack1(int weight,int value,int Isleft,int Level,Pack1* p,int Up)
{
cw=weight;
cp=value;
isleft=Isleft;
level=Level;
parent=p;
up=Up;
}
};
struct cmp
{
bool operator()(Pack1 *&a, Pack1 *&b) const
{
return a->up < b->up;
}
};
class solve
{
public:
int *w,*v,*X1,*X2,bestp1,bestp2;
solve()
{
int i=0;
w=new int[N];
v=new int[N];
X1=new int[N];
X2=new int[N];
bestp1=0;
bestp2=0;
for (i=0;i<N;i++)
{
cin>>w[i]>>v[i];
X1[i]=0;
X2[i]=0;
}
}
void answer1copy(Pack *qnode)
{
int i=N-1;
while(qnode!=NULL)
{
if(qnode->isleft==1)
{
X1[i]=1;
}
else
{
X1[i]=0;
}
i--;
qnode=qnode->parent;
}
}
void answer2copy(Pack1 *qnode)
{
int i=N-1;
while(qnode!=NULL)
{
if(qnode->isleft==1)
{
X2[i]=1;
}
else
{
X2[i]=0;
}
i--;
qnode=qnode->parent;
}
}
int BOUND(int i)
{
int j,sum=0;
for (j=i;j<N;j++)
{
sum+=v[j];
}
return sum;
}
void solve1()
{
queue<Pack*> qpack;
int cw,cp,bestp,i;
i=0;
cw=0;
cp=0;
bestp=0;
Pack *qNode=NULL,*qNode1=NULL;
if (cw+w[i] <= W) //左子结点. 这里也可以考虑限界条件
{
bestp=(cp+v[i]>bestp) ? cp+v[i] : bestp;
qNode1=new Pack(cw+w[i],cp+v[i],1,i+1,qNode);
qpack.push(qNode1);
}
if (BOUND(i+1)+cp >= bestp) //右子结点. BOUND为限界函数
{
qNode1=new Pack(cw,cp,0,i+1,qNode);
qpack.push(qNode1);
}
while (1)
{
qNode=qpack.front();
if(qNode==NULL)
{
break;
}
cw = qNode->cw;
cp = qNode->cp;
i = qNode->level;
if ((qNode->level == N)&& (qNode->cp >= bestp))
{
bestp1=bestp;
answer1copy(qNode);
}
if(i<N)
{
if (cw+w[i] <= W) //左子结点. 这里也可以考虑限界条件
{
bestp=(cp+v[i]>bestp) ? cp+v[i] : bestp;
qNode1=new Pack(cw+w[i],cp+v[i],1,i+1,qNode);
qpack.push(qNode1);
}
if (BOUND(i+1)+cp >= bestp) //右子结点. BOUND为限界函数
{
qNode1=new Pack(cw,cp,0,i+1,qNode);
qpack.push(qNode1);
}
}
qpack.pop();
}
}
void solve2()
{
priority_queue<Pack1 *, vector<Pack1 *>, cmp > qpack;
int cw,cp,bestp,i;
i=0;
cw=0;
cp=0;
bestp=0;
Pack1 *qNode=NULL,*qNode1=NULL;
if (cw+w[i] <= W) //左子结点. 这里也可以考虑限界条件
{
bestp=(cp+v[i]>bestp) ? cp+v[i] : bestp;
qNode1=new Pack1(cw+w[i],cp+v[i],1,i+1,qNode,BOUND(i)+cp);
qpack.push(qNode1);
}
if (BOUND(i+1)+cp >= bestp) //右子结点. BOUND为限界函数
{
qNode1=new Pack1(cw,cp,0,i+1,qNode,BOUND(i+1)+cp);
qpack.push(qNode1);
}
while (1)
{
qNode=qpack.top();
if(qNode==NULL)
{
break;
}
cw = qNode->cw;
cp = qNode->cp;
i = qNode->level;
if ((qNode->level == N)&& (qNode->cp >= bestp))
{
bestp2=bestp;
answer2copy(qNode);
break;
}
if(i<N)
{
if (cw+w[i] <= W) //左子结点. 这里也可以考虑限界条件
{
bestp=(cp+v[i]>bestp) ? cp+v[i] : bestp;
qNode1=new Pack1(cw+w[i],cp+v[i],1,i+1,qNode,BOUND(i)+cp);
qpack.push(qNode1);
}
if (BOUND(i+1)+cp >= bestp) //右子结点. BOUND为限界函数
{
qNode1=new Pack1(cw,cp,0,i+1,qNode,BOUND(i+1)+cp);
qpack.push(qNode1);
}
}
qpack.pop();
}
}
};
int main()
{
solve s;
s.solve1();
s.solve2();
cout <<"队列式分支界限法求解结果:"<<endl<< "the best value is "<<s.bestp1 <<" "<< endl<<"selected packages are ";
for (int i=0;i<N;i++)
{
if(s.X1[i]==1)
{
cout<<"No."<<i+1<<" ";
}
}
cout<<endl;
cout <<"优先队列式分支界限法求解结果:"<<endl<< "the best value is "<<s.bestp2 <<" "<< endl<<"selected packages are ";
for (int i=0;i<N;i++)
{
if(s.X2[i]==1)
{
cout<<"No."<<i+1<<" ";
}
}
cout<<endl;
return 0;
}
分支界限法与优先队列发求解背包问题
原文作者:分支限界法
原文地址: https://blog.csdn.net/Shunfengyang/article/details/83310881
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/Shunfengyang/article/details/83310881
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。