满足Python标准的组合

时间:2014-01-12 23:01:54

标签: python list combinations criteria

我有一个名称和数字的字典,范围从700到2500,我想将它们组合在一个新的列表中,其中组的总和不超过4500.然后我将选择最少量的一个条目。

我知道我可以列出所有可能的组合,然后删除超过4500的条目,但这会产生太多不可用的项目。

任何提示?

更新: 感谢@Andrea de Marco,我有一部分问题。

现在使用背包功能我有最好的条目,但并非所有条目都在列表中。所以我必须运行该函数n次,直到列表为空。

由于我没有对问题使用任何“值”,我将值设置为1。

2 个答案:

答案 0 :(得分:1)

答案 1 :(得分:0)

如果您想使用不同的项目组合,则需要itertools。这将允许您生成所有可能的项目组合,而无需通过一次构建整个批次来实际填充内存。你可能会发现这个食谱很有用:

def powerset(iterable):
    "powerset([1,2,3]) --> () (1,) (2,) (3,) (1,2) (1,3) (2,3) (1,2,3)"
    s = list(iterable)
    return chain.from_iterable(combinations(s, r) for r in range(len(s)+1))

您可以使用它来生成词典中values()的所有组合。

假设您希望尽可能接近某些target但是尽可能少的值,您可以尝试:

best = None
for set_ in powerset(d.values()):
    if best is None and sum(set_) <= target:
        best = set_
    elif (sum(best) < sum(set_) <= target or # closer or
          (sum(best) == sum(set_) and # as close and 
           len(set_) < len(best))): # shorter
        best = set_

然而,请注意,随着len(d.values())越来越大,这种天真的蛮力方法非常缓慢;集合S的powerset中的子集数量为2**n,其中n == len(S)