您的位置:首页 > 编程语言 > C语言/C++

0/1背包问题 - 分枝定界(C++实现)

2017-06-30 15:17 609 查看
0/1背包问题 - 分枝定界(C++实现)

flyfish

#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

struct Item //物品定义
{
int id, weight, value;//编号,重量,价值。
Item(){}
Item(int i, int w, int v) :id(i), weight(w), value(v){}

void operator += (const Item &i) //重载操作符主要是为计算使用
{
this->value = this->value + i.value;
this->weight = this->weight + i.weight;
}
void operator -= (const Item &i)
{
this->value = this->value - i.value;
this->weight = this->weight - i.weight;
}
bool operator ()(const Item & i1, const Item & i2)
{

double r1 = (double)i1.value / i1.weight;
double r2 = (double)i2.value / i2.weight;

if (r1 < r2) return true;

if (r1 > r2)
return false;
else
return false;
}
};

class Node
{
public:
int level;
int profit;
int bound;

int weight;
bool operator ()(const Node & n1, const Node & n2)
{
if (n1.bound < n2.bound) return true;

if (n1.bound > n2.bound)
return false;
else
return false;
}

};
const int n = 4, C = 10;
//C背包所能承受的最大重量
//物品个数n

std::vector<Item> allItems;//所有的物品
int maxValue = 0;//能够装入背包的最大价值
int bound(Node u)
{
if (u.weight >= C)
return 0;
int profit_bound = u.profit;
int j = u.level + 1;
int totweight = u.weight;

while ((j < n) && (totweight + allItems[j].weight <= C))
{
totweight += allItems[j].weight;
profit_bound += allItems[j].value;
j++;
}
if (j < n)
profit_bound += (C - totweight) * allItems[j].value /
allItems[j].weight;
return profit_bound;
}
//计算下一个节点profit, 如果该profit大于maxProfit, 更新maxProfit
//计算下一个节点的bound,如果bound大于maxProfit,将下一层的节点加入Q
int BranchAndBound()
{
std::sort(allItems.begin(), allItems.end(), Item());
std::priority_queue <Node, std::vector <Node>, Node > Q;
Node u, v;

u.level = -1;
u.profit = u.weight = 0;
Q.push(u);

int maxProfit = 0;
while (!Q.empty())
{

u = Q.top();
Q.pop();

if (u.level == -1)
v.level = 0;

if (u.level == n - 1)
continue;

v.level = u.level + 1;
v.weight = u.weight + allItems[v.level].weight;
v.profit = u.profit + allItems[v.level].value;

if (v.weight <= C && v.profit > maxProfit)
maxProfit = v.profit;

v.bound = bound(v);

if (v.bound > maxProfit)
Q.push(v);

v.weight = u.weight;
v.profit = u.profit;
v.bound = bound(v);
if (v.bound > maxProfit)
Q.push(v);
}

return maxProfit;
}
int _tmain(int argc, _TCHAR* argv[])
{

allItems.push_back(Item(1, 3, 30));
allItems.push_back(Item(2, 5, 20));
allItems.push_back(Item(3, 4, 10));
allItems.push_back(Item(4, 2, 40));

std::cout << "max value = "<< BranchAndBound();

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  背包问题