【问题标题】:How to find all combinations that sum up to at most a constant?如何找到总和最多为常数的所有组合?
【发布时间】:2017-10-25 21:56:10
【问题描述】:

P=[P1, P2, ..., Pk]k 正整数,让T 为正整数。我想生成最多为T 的所有组合。也就是说,sum(x[i] * P[i] for i in 1:k) <= T 其中x[i] = 1 iff i 在组合中被选中。

示例。

P=[1, 2, 3]T=4。组合应该是:

1
2
3
1, 2
1, 3
2, 3

所以只有1, 2, 3 的组合不能存在,因为1 + 1 + 3 = 5 > 4

我想先生成所有组合,然后开始验证约束sum(x[i] * P[i] for i in 1:k) <= T。但这种方法可能比其他聪明的方法更耗时。我们如何生成这样的组合?

注意。如果您知道 Python 或 Matlab 中任何可用于生成此类组合的函数,您可以提供。

谢谢。

【问题讨论】:

  • 2,3... 2+3 = 5 > 4 也
  • @scharette 2, 3 的组合表示P[2] + P[3] <= 4 就是这样。
  • @Ribz 对不起,如果P = [1,2,3] 你怎么能访问P[3]。我疯了吗?
  • 你不是。我刚刚在1 而不是0 开始阵列。

标签: python algorithm matlab combinations


【解决方案1】:

这类似于子集总和问题(在 cmets 中提到),除了它是关于找到与目标相加 等于 的数字。您想要找到总和小于或等于到目标的数字。

不过,可以使用类似的动态规划方法:

def subset_sum(vals, target=0):
    sums = {0: [()]}  # key=sum, value=list of subsets for the sum
    if target in sums:
        yield from sums[target]  # annoying base case
    for val in vals:
        items = sums.items()  # don't change dict size during iteration
        sums = dict(items)
        for prev_sum, prev_subsets in items:
            sum_ = prev_sum + val
            subsets = [s + (val,) for s in prev_subsets]
            sums[sum_] = sums.get(sum_, []) + subsets
            if sum_ <= target:
                yield from subsets

演示:

>>> for subset in subset_sum([1, 2, 3], target=4):
...     print(*subset, sep='+')
...     
1
2
1+2
3
1+3

【讨论】:

  • 我认为这仍然是重复的,也许我错了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多