branch and bound
Queue-type FIFIO solves 0/1 knapsack problem
the code
#include<iostream>
#include<queue>
using namespace std;
#define MAXN 105
int n = 3, W = 30;
int w[] = {
0,16,15,15 };
int v[] = {
0,45,25,25 };
int maxv = -9999;
int bestx[MAXN];
int total = 1;
struct NodeType
{
int no;
int i;
int w;
int v;
int x[MAXN];
double ub;
};
void bound(NodeType &e)
{
int i = e.i + 1;
int sumw = e.w;
double sumv = e.v;
while ((sumw + w[i] <= W) && i <= n)
{
sumw += w[i];
sumv += v[i];
i++;
}
if (i <= n)
e.ub = sumv + (W - sumw)*v[i] / w[i];
else
e.ub = sumv;
}
void EnQueue(NodeType e, queue<NodeType> &qu)
{
if (e.i == n)
{
if (e.v > maxv)
{
maxv = e.v;
for (int j = 1; j <= n; j++)
bestx[j] = e.x[j];
}
}
else qu.push(e);
}
void bfs()
{
NodeType e, e1, e2;
queue<NodeType> qu;
e.i = 0;
e.w = 0, e.v = 0;
e.no = total++;
for (int j = 1; j <= n; j++)
e.x[j] = 0;
bound(e);
qu.push(e);
while (!qu.empty())
{
e = qu.front();
qu.pop();
if (e.w + w[e.i + 1] <= W)
{
e1.no = total++;
e1.i = e.i + 1;
e1.w = e.w + w[e1.i];
e1.v = e.v + v[e1.i];
for (int j = 1; j <= n; j++)
e1.x[j] = e.x[j];
e1.x[e1.i] = 1;
bound(e1);
EnQueue(e1, qu);
}
e2.no = total++;
e2.i = e.i + 1;
e2.w = e.w;
e2.v = e.v;
for (int j = 1; j <= n; j++)
e2.x[j] = e.x[j];
e2.x[e2.i] = 0;
bound(e2);
if (e2.ub > maxv)
EnQueue(e2, qu);
}
}
void output()
{
cout << "最优值是:" << maxv << endl;
cout << "(";
for (int i = 1; i <= n; i++)
cout << bestx[i] << " ";
cout << ")";
}
int main()
{
bfs();
output();
system("pause");
return 0;
}