【问题标题】:Combinations to Equal Sums (similar to Subset-Sum and Coin Changing Algorithms)等和的组合(类似于子集和和硬币改变算法)
【发布时间】:2018-03-09 05:29:53
【问题描述】:

我有硬币兑换问题,除了 twist:不是从无限硬币中找到等于单个总和的解决方案,而是从一组有限硬币中找到小于的解决方案列表总和的集合。

(经典问题的一个很好的链接是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]]]

【问题讨论】:

  • 这看起来像广义的子集和(即子集和可以简化为它)。

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


【解决方案1】:

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

Wikipedia 提供了问题的整数规划公式,这就是我解决实际示例所采用的方法——通过使用 IP 求解器。

为完整起见,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)

也就是说,您要最大化背包中物品的总重量,这样没有物品被分配到一个以上的背包,没有背包超过其容量,并且物品是离散的(它们不能部分分配到一个背包)。这被表述为一个优化问题——当然,您可以查看最佳解决方案,看看它是否分配了所有项目。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 2018-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多