[英]Find All Combinations of Numbers That Uniquely Sum to a Set of Numbers
我有一个数字列表(源集),有人拿走了部分或全部这些数字,然后将它们随机求和,以得出较小的一组数字(目标集)。 我有源集和目标集,但是我需要弄清楚使用了哪种组合。 难度:我不能保证将源集中的所有数字都用作目标集,也不能保证目标集中的所有数字都来自源集合。 这是一个简单的例子:
我已经找到了一些很好的示例,可以在给定单个目标值的情况下推导上述值,但是我找不到一种方法来对目标值数组(而不是单个值)进行处理(很遗憾,我的编码技能无法胜任该任务)。 我最好的开始就是这个问题 ,下面的代码(请注意,我删除了s> = target检查以容纳我的数据):
def subset_sum(numbers, target, partial=[]):
s = sum(partial)
# check if the partial sum is equals to target
if s == target:
print "sum(%s)=%s" % (partial, target)
#if s >= target:
# return # if we reach the number why bother to continue
for i in range(len(numbers)):
n = numbers[i]
remaining = numbers[i+1:]
subset_sum(remaining, target, partial + [n])
if __name__ == "__main__":
subset_sum([1,2,3,4,5],4)
这将输出:
sum([1, 3])=4
sum([4])=4
我已经做了一些英勇的尝试,添加了第二层递归以支持目标数组,但是我不会因为失败而感到尴尬。
我知道上面的代码有局限性,并且我愿意接受基于此代码或全新代码的解决方案,并以几乎任何逻辑格式输出。 强烈推荐使用Python,但是我几乎会接受所有事情(请注意:java给了我荨麻疹)。
您的意思是:
In []:
import itertools as it
source = [1, 2, 3, 4, 5]
targets = [3, 8]
p = [[a for n in range(1, len(source)) for a in it.combinations(source, n) if sum(a) == t] for t in targets]
[dict(zip(targets, a)) for a in it.product(*p) if len(sum(a, tuple())) == len(set(sum(a, tuple())))]
Out[]:
[{3: (3,), 8: (1, 2, 5)}, {3: (1, 2), 8: (3, 5)}]
我发现的唯一方法是效率很低,而且我敢肯定必须有一种更聪明的方法,但是它可以工作。
想法是获取所有组合,获取第一个数字的组合,遍历所有组合,从列表中删除使用的数字,生成所有组合,获取与第二个数字匹配的组合并进行迭代。
这是代码。 同样,这很丑陋,但确实可以做到:
from collections import defaultdict
import itertools as it
def get_all_combinations(l):
return [a for n in range(1, len(l)) for a in it.combinations(l, n)]
def get_combinations_for_target(combinations, target):
if combinations is None:
return []
return [combination for combination in combinations if sum(combination) == target]
def get_list_without_used_numbers(l, combination):
used_numbers = []
for item in combination:
used_numbers.append(item)
diff_list = list(set(l) - set(used_numbers))
return diff_list
source = [1, 2, 3, 4, 5]
combinations = get_all_combinations(source)
combinations_first = get_combinations_for_target(combinations, 3)
combinations_both = defaultdict(dict)
for combination in combinations_first:
partial_list = get_list_without_used_numbers(source, combination)
partial_combinations = get_all_combinations(partial_list)
combinations_both[combination] = get_combinations_for_target(partial_combinations, 8)
print(combinations_both)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.