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

0-1背包问题(C++)

2010-07-12 21:22 363 查看

0-1背包问题是一个经典的动态规划问题,问题定义如下:有n个物品,其重量分别为W={w1, w1, w3, ... wn},其价值分别为V={v1, v2, v3, .. vn}。现在要将这N个物品放入允许的最大重量为w的包中,问怎样选择物品能使包中的物品总价值最大。

可以将背包问题划分成若干个子问题,关键在于如何对问题进行划分。现在将问题表述为在重量限制为w的情况下,求对前N个物品进行选择能得到的最大价值,即v[n, w]。对于一个物品i,求v[i, w']时有两种情况可供选择:若选中物品i,则所得的最大价值为v[i-1, w'-wi]+vi;若不选中物品i,则所得的最大价值为v[i-1, w']。选择二者之间的较大值即可求出最优解。因此,子问题可以分解成两个更小的子问题。

解决0-1背包问题的C++代码如下所示, 代码中用到了boost库中的multi_array:




0-1背包问题
1

#include <iostream>
2

#include <boost/multi_array.hpp>
3


4

using namespace std;
5


6

// 动态规划解决0-1背包问题
7

void Knapsack(int weightArray[], int valueArray[], size_t length, int totalWeight)
8





{
9

// 价值表
10

boost::multi_array<int, 2> valueTable(boost::extents[length + 1][totalWeight + 1]);
11

// 选择表
12

boost::multi_array<bool, 2> selectionTable(boost::extents[length + 1][totalWeight + 1]);
13

// 初始化前0个物品的最大价值为0
14

for (size_t itemIdx = 0; itemIdx <= length; ++itemIdx)
15





{
16

valueTable[itemIdx][0] = 0;
17

}
18

// 初始化允许重量为0是的最大价值为0
19

for (int weightIdx = 0; weightIdx <= totalWeight; ++weightIdx)
20





{
21

valueTable[0][weightIdx] = 0;
22

}
23


24

// 从底层开始填写价值表和选择表
25

for (size_t itemIdx = 1; itemIdx <= length; ++itemIdx)
26





{
27

for (int weightIdx = 1; weightIdx <= totalWeight; ++weightIdx)
28





{
29

// 先计算不选择当前物品时的最大价值
30

int valueUnselected = valueTable[itemIdx - 1][weightIdx];
31

// 允许的重量需大于等于当前物品的重量,否则当前物品不可选
32

if (weightIdx >= weightArray[itemIdx - 1])
33





{
34

// 计算选择当前物品时的最大价值
35

int valueSelected = valueArray[itemIdx - 1] +
36

valueTable[itemIdx - 1][weightIdx - weightArray[itemIdx - 1]];
37

// 若选择当前物品时所得到的最大价值大于不选择时的最大价值,
38

// 则选择当前物品,并进行下一次循环
39

if (valueSelected >= valueUnselected)
40





{
41

valueTable[itemIdx][weightIdx] = valueSelected;
42

selectionTable[itemIdx][weightIdx] = true;
43

continue;
44

}
45

}
46


47

// 处理不选择当前物品的情况
48

valueTable[itemIdx][weightIdx] = valueUnselected;
49

selectionTable[itemIdx][weightIdx] = false;
50

}
51

}
52


53

// 打印最大值以及被选中的物品编号
54

cout << "最大价值为:" << valueTable[length][totalWeight] << endl;
55

cout << "以下编号的物品被选中:";
56

for (size_t itemIdx = length, weightIdx = totalWeight; itemIdx > 0; --itemIdx)
57





{
58

if (selectionTable[itemIdx][weightIdx])
59





{
60

cout << itemIdx << " ";
61

weightIdx -= weightArray[itemIdx - 1];
62

}
63

}
64

cout << endl;
65

}
66


67

int main()
68





{
69



int weights[] =

{1, 2, 3, 2, 2};
70



int values[] =

{8, 4, 0, 5, 3};
71

int totalWeight = 4;
72

Knapsack(weights, values, sizeof(weights) / sizeof(int), totalWeight);
73

return 0;
74

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