折叠式背包问题是普通背包问题的概括,背包容量是所包含物品数量的非增加函数。
有没有人知道关于背包容量根据您选择的项目而改变的变体(即,域是项目的动力组)而不是项目数量的变体(名称,文献,算法......)? / p>
答案 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 := 0
和k=n
开始。
重复:
k
优于A
M
的最佳子集
M := max (A, M)
:到目前为止找到的最佳子集的值M >= M_{k-1}
,请停止:我们找到了最佳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}},这当然很有趣。