共有4个项目:A 2LB的权重为40美元,B权重为5LB,利润为30美元,C权重为10LB,利润为50美元,D权重为5LB,利润为10美元。计算背包重量为16LB的4件物品中的任何一件可获得的最大总利润。你不能把整个项目的任何部分都拿走。
请说明如何使用背包问题方法解决上述问题。
答案 0 :(得分:1)
一个简单的解决方案是考虑所有项目子集并计算所有子集的总权重和值。那么你应该考虑只采用重量小于或等于背包容量的子集。从所有这些子集中,选择最大值子集。
要考虑所有项目的子集,每个项目可以有两种情况:
让我们说你背包的容量 W 。因此,可以从 n 项中获得的最大值是以下两个值的最大值。
如果第n项的权重大于 W ,则不能包括第n项,并且案例1是唯一选项。这将是一种天真的方法,解决方案将需要 2 n 时间。
现在重叠的子问题:
weight = {2, 5, 10, 5}
Capacity = 16
The recursion tree would look like:
// Here n,k -> items remaining, capacity remaining
// Going to left child -> including the item at hand
// Going to right child -> excluding the item at hand
_______4,16______
/ \
/ \
3,14 3,16
/ \ / \
/ \ / \
2,9 2,14 2,5 2,16
\ / \ \ / \
\ / \ \ / \__
1,9 1,4 1,14 1,5 1,6 1,16
/\ /\ /\ /\ / \
/ \ / \ / \ / \ / \
0,4 0,9 0,9 0,14 0,0 0,0 0,1 0,6 0,11 0,16
由于叶子中存在重叠的子问题,我们可以使用动态编程来解决它。如果存储值,稍后使用它们将会很有效。这里匹配发生在叶子节点中,如果你采用其他例子,你会看到匹配可以发生在叶节点之前。
伪代码看起来像:
Procedure Knapsack(n, W): //here, n = number of items, W = capacity of Knapsack
for i from 0 up to n
for j from 0 up to W
if i == 0 or j == 0
table[i][j] :=0
else if weight[i-1] <= j
table[i][j] := max(profit[i-1] + table[i-1][w-weight[i-1]], table[i-1][j])
else
table[i][j] := table[i-1][j]
end if
end for
end for
Return table[n][W]