Branch and bound method || Queue FIFIO solves 0/1 knapsack problem

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;
}

Guess you like

Origin blog.csdn.net/qq_43759081/article/details/122103386