折叠背包,容量更改基于所选项目而不是数字

时间:2013-10-09 09:25:05

标签: algorithm linear-programming knapsack-problem np-hard

折叠式背包问题是普通背包问题的概括,背包容量是所包含物品数量的非增加函数。

有没有人知道关于背包容量根据您选择的项目而改变的变体(即,域是项目的动力组)而不是项目数量的变体(名称,文献,算法......)? / p>

1 个答案:

答案 0 :(得分:0)

对于'容量'的一般价值,我相信你需要对set元素进行某种枚举。如果我理解正确的话,它或多或少会对一个任意的布尔值进行反应,这个布尔值表示一个子集是可行的(其元素的权重之和低于其容量)或者不是。

背包问题中的“容量”出现在约束的右侧,即

sum p_i x_i <= C

在经典背包中

sum p_i x_i <= C (sum x_i)

在倒塌的背包里。

因为它们是线性约束,它们以某种可预测的方式运行,避免查看 all 可能的组合(幂集的元素)来解决问题。

现在,如果您为权力集的每个元素都有任意容量值C_J,那么您的容量不是向量x的可预测函数,因此您只能从列表中删除必须检查的子集J的方法是,它的值(sum_J a_i x_i)是否低于您已找到的子集之一的是可行的(你没有任何关于能力的信息)。

这尤其意味着无法使用整数程序对此进行建模,因为每个C_J至少需要一个约束(仅计算每个可行子集的成本会更高效)。

我会使用枚举算法并尝试尽可能地减少搜索树。

让我们按非增加值a_0 >= a_1 >= ... >= a_n订购商品。

我们可以通过降低基数来查看所有可能的子集。这是因为对于某些基数k,您知道最多k基数的最佳子集的值为M_k = sum_{i=0}^k a_i,因此您可以在之前停止搜索检查所有子集(我想不出另一种切割搜索树的方法)。

算法将是:

M := 0k=n开始。

重复:

  • 如果其值k优于A
  • ,则找到基数为M的最佳子集
  • M := max (A, M):到目前为止找到的最佳子集的值
  • 如果M >= M_{k-1},请停止:我们找到了最佳
  • else k := k-1

要搜索基数k的最佳子集,您可以使用a_i的顺序:

  • {0, ..., k}开头,递归检查子集{0} U J'J' k-1 {1, ..., n}的基数{1} U J'的子集,
  • 然后检查J'表单的所有子集,k-1 {2, ..., n}的基数M的子集等。

一旦找到可行的子集,就更新绑定的k

这也是因为不包含a_0, ..., a_i的基数a_{i+1} + ... + a_{i+k+1}子集受M限制,只要低于当前界限C_J就可以停止。 1}}。

注意: 我假设容量I没有假设。了解容量在理论意义上是否在增加,即J中包含的C_I <= C_J暗示{{1}},这当然很有趣。