等和组合(类似于子集和和换币算法)

Combinations to Equal Sums (similar to Subset-Sum and Coin Changing Algorithms)

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

(一个很棒的link到经典问题是here)

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

一个类似但不同且似乎更难编码的问题:

给定-

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

例如,此示例可能找到 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]]]

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

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)

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