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
}
相关文章推荐
- 贪心算法运用于背包问题(C++实现)
- 背包问题的c++解法
- 动态规划解背包问题/C++/Knapsack problem
- 动态规划解背包问题/C++/Knapsack problem
- 最简单的0-1背包问题c++代码实例及运行结果
- C++动态规划算法之0-1背包问题
- 经典背包问题(装船问题)C++版
- 0-1背包问题与完全背包问题C++实现 动态规划
- C++回溯法0/1背包问题DKNAP
- 动态规划解背包问题/C++/Knapsack problem
- 最简单的0-1背包问题c++代码实例及运行结果
- 最简单的0-1背包问题c++代码实例及运行结果
- c++动态规划——背包问题
- C++数据结构--背包问题
- C++ 背包问题
- 0-1背包问题与完全背包问题C++实现 动态规划
- c++实现0-1背包问题完整源码(动态…
- (C++)分支限界法求解背包问题
- 最简单的0-1背包问题c++代码实例及运行结果
- 最简单的0-1背包问题c++代码实例及运行结果