等和的组合(类似于子集和和硬币更改算法)

时间:2018-03-09 05:29:54

标签: python-3.x algorithm recursion combinations subset-sum

我有硬币更改问题,除了扭曲:而不是从无限硬币中找到等于一个总和的解决方案,找到一组有限硬币的解决方案列表小于一系列的总和。

(经典问题的一个很好的链接是here

(这也类似于子集和问题,除了一组目标而不只是一个 - 链接here

一个类似但不同且看似更难的代码问题:

鉴于 -

  • 所有必须使用的可能数值列表 [1,9,4,1,3,2]
  • 可以达到最大总数的组列表[(GroupA,17),(GroupB,1),(GroupC,5)]

目标 - 将列表中的每个数值分配给一个组,以便所有项目都使用以下约束:每个组的值的总和不得超过指定的最大值。

例如,此示例可能会找到3个解决方案:

[[GroupA,[9,4,1,3]], [GroupB, [1]], [GroupC, [2]],
[GroupA,[9,4,1,2]], [GroupB, [1]], [GroupC, [3]],
[GroupA,[9,2,1,3]], [GroupB, [1]], [GroupC, [4]]]

1 个答案:

答案 0 :(得分:1)

这称为多背包问题。您有n个项目,其权重为w[i]m背包的容量为c[i],您需要将这些项目分配给背包,以便没有超出其容量。

Wikipedia提供问题的整数规划表达式,这是我通过使用IP求解器解决实际例子的方法。

为完整起见,知识产权制定为:

maximize sum(x[i,j] * w[j], i=1..m, j=1..n)
such that:
sum(x[i,j], i=1..m) <= 1 (for all j=1..n)
sum(x[i,j] * w[j], j=1..n) < c[i]  (for all i=1..m)
x[i][j] = 0 or 1 (for all i=1..m, j=1..n)

也就是说,你最大化背包中物品的总重量,这样就不会将物品分配给多个背包,没有背包超过其容量,物品是离散的(他们不能这样做)部分分配到背包)。这是一个优化问题 - 当然,您可以查看最佳解决方案,看看它是否分配了所有项目。