分支界限法與優先佇列發求解揹包問題
阿新 • • 發佈:2018-12-17
#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; }