分支限界法之01背包优先队列版

Posted wangxuelin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分支限界法之01背包优先队列版相关的知识,希望对你有一定的参考价值。

代码:

  1 #include <cstdio>
  2 #include <algorithm>
  3 #include <iostream>
  4 #include <queue>
  5 #include <vector>
  6 using namespace std;
  7 
  8 const int maxn=100;
  9 
 10 class node
 11 {
 12 public:
 13     int id,w,p;
 14     double average;
 15     bool operator < (const node &a)const
 16     {
 17         return average>a.average;
 18     };
 19 }ths[maxn];
 20 
 21 class bbnode
 22 {
 23 public:
 24     bbnode *parent;
 25     bool lchild;
 26     bbnode(bbnode *b,bool f)
 27     {
 28         parent=b;
 29         lchild=f;
 30     };
 31 };
 32 
 33 class headnode
 34 {
 35 public:
 36     double up;
 37     int cp,cw;
 38     int level;
 39     bbnode *bb;
 40     headnode(double u,int p,int w,int l,bbnode b)
 41     {
 42         up=u;
 43         cp=p;
 44         cw=w;
 45         level=l;
 46         bbnode *yy=new bbnode(b.parent,b.lchild);
 47         bb=yy;
 48     }
 49     bool operator < (const headnode &a)const
 50     {
 51         return up<a.up;
 52     };
 53 };
 54 
 55 int n;
 56 int c;
 57 int cw;
 58 int cp;
 59 int bestp;
 60 int best[maxn];
 61 
 62 bool cmpp(node a,node b)
 63 {
 64     return a.id<b.id;
 65 }
 66 double bound(int num)
 67 {
 68     int cleft=c-cw;
 69     double p=cp;
 70     while(num<=n && ths[num].w <= cleft)
 71     {
 72         cleft-=ths[num].w;
 73         p+=ths[num].p;
 74         num++;
 75     }
 76     if(num<=n)
 77     {
 78         p+=1.0*cleft/ths[num].w * ths[num].p;
 79     }
 80     return p;
 81 }
 82 
 83 
 84 void init()
 85 {
 86     cw=0;
 87     cp=0;
 88     bestp=0;
 89 }
 90 
 91 int bfs()
 92 {
 93     priority_queue<headnode> que;
 94     bbnode *E;
 95     E=0;
 96     int i=1;
 97     int t=bound(1);
 98     while(i<=n)
 99     {
100         if(cw+ths[i].w<=c)
101         {
102             if(cp+ths[i].p>bestp)
103                 bestp=cp+ths[i].p;
104             que.push(headnode(t,cp+ths[i].p,cw+ths[i].w,i+1,bbnode(E,true)));
105         }
106         t=bound(i+1);
107         if(t>=bestp)
108             que.push(headnode(t,cp,cw,i+1,bbnode(E,false)));
109         headnode now=que.top();
110         que.pop();
111         cp=now.cp;
112         cw=now.cw;
113         i=now.level;
114         t=now.up;
115         E=now.bb;
116     }
117     for(int j=n;j>0;j--)
118     {
119         best[j]=E->lchild;
120         E=E->parent;
121     }
122     return cp;
123 }
124 
125 int main()
126 {
127     cin>>n>>c;
128     for(int i=1;i<=n;i++)
129     {
130         cin>>ths[i].p;
131         ths[i].id=i;
132     }
133     for(int i=1;i<=n;i++)
134     {
135         cin>>ths[i].w;
136         ths[i].id=i;
137         ths[i].average=1.0*ths[i].p/ths[i].w;
138     }
139     sort(ths+1,ths+n+1);
140     init();
141     cout<<bfs()<<endl;
142     vector<node> v;
143     for(int i=1;i<=n;i++)
144         if(best[i])
145             v.push_back(ths[i]);
146     sort(v.begin(),v.end(),cmpp);
147     for(int i=0;i<v.size();i++)
148         cout<<"The "<<v[i].id<<"th : "<<"p="<<v[i].p<<" w="<<v[i].w<<endl;
149     return 0;
150 }
151 /*
152 4 7
153 9 10 7 4
154 3 5 2 1
155   
156 6 12
157 8 10 6 3 7 2
158 4 6 2 2 5 1
159  */

输入示例1:

4 7

9 10 7 4

3 5 2 1

输出示例1:

20

The 1th : p=9 w=3

The 3th : p=7 w=2

The 4th : p=4 w=1

输入示例2:

6 12

8 10 6 3 7 2

4 6 2 2 5 1

输出示例2:

24

The 1th : p=8 w=4

The 2th : p=10 w=6

The 3th : p=6 w=2

以上是关于分支限界法之01背包优先队列版的主要内容,如果未能解决你的问题,请参考以下文章

分支限界法之单源最短路径问题

对比Dijakstra和优先队列式分支限界

优先队列式分支限界法-最小重量机器设计问题

分支限界法C++ 学习&练习

分支限界法C++ 学习&练习

分支限界法C++ 学习&练习