[英]Subset sum recursively in Python
I will be happy to get some help.我很乐意得到一些帮助。
I have the following problem:我有以下问题:
I'm given a list of numbers seq
and a target number and I need to write 2 things:我得到了一个数字
seq
列表和一个目标数字,我需要写两件事:
A recursive solution that returns True
if there is a sum of a subsequence that equals the target number and False
otherwise.如果子序列的总和等于目标数,则返回
True
递归解决方案,否则返回False
。 example:例子:
subset_sum([-1,1,5,4],0) # True subset_sum([-1,1,5,4],-3) # False
Secondly, I need to write a solution using what I wrote in the previous solution but now with memoization that uses a dictionary in which the keys are tuples: (len(seq),target)
其次,我需要使用我在之前的解决方案中编写的内容编写一个解决方案,但现在使用使用字典的记忆化,其中键是元组:
(len(seq),target)
For number 1 this is what I got to so far:对于第 1 点,这就是我到目前为止所做的:
def subset_sum(seq, target):
if target == 0:
return True
if seq[0] == target:
return True
if len(seq) > 1:
return subset_sum(seq[1:],target-seq[0]) or subset_sum(seq[1:],target)
return False
Not sure I got it right so if I could get some input I will be grateful.不确定我做对了,所以如果我能得到一些意见,我将不胜感激。
For number 2:对于数字 2:
def subset_sum_mem(seq, target, mem=None ):
if not mem:
mem = {}
key=(len(seq),target)
if key not in mem:
if target == 0 or seq[0]==target:
mem[key] = True
if len(seq)>1:
mem[key] = subset_sum_mem(seq[1:],target-seq[0],mem) or subset_sum_mem(seq[1:],target,mem)
mem[key] = False
return mem[key]
I can't get the memoization to give me the correct answer so I'd be glad for some guidance here.我无法获得记忆来给我正确的答案,所以我很高兴在这里得到一些指导。
Thanks for anyone willing to help!感谢任何愿意提供帮助的人!
Just for reference, here's a solution using dynamic programming:仅供参考,这是使用动态规划的解决方案:
def positive_negative_sums(seq):
P, N = 0, 0
for e in seq:
if e >= 0:
P += e
else:
N += e
return P, N
def subset_sum(seq, s=0):
P, N = positive_negative_sums(seq)
if not seq or s < N or s > P:
return False
n, m = len(seq), P - N + 1
table = [[False] * m for x in xrange(n)]
table[0][seq[0]] = True
for i in xrange(1, n):
for j in xrange(N, P+1):
table[i][j] = seq[i] == j or table[i-1][j] or table[i-1][j-seq[i]]
return table[n-1][s]
I have this modified code:我有这个修改后的代码:
def subset_sum(seq, target):
left, right = seq[0], seq[1:]
return target in (0, left) or \
(bool(right) and (subset_sum(right, target - left) or subset_sum(right, target)))
def subset_sum_mem(seq, target, mem=None):
mem = mem or {}
key = (len(seq), target)
if key not in mem:
left, right = seq[0], seq[1:]
mem[key] = target in (0, left) or \
(bool(right) and (subset_sum_mem(right, target - left, mem) or subset_sum_mem(right, target, mem)))
return mem[key]
Can you provide some test cases this does not work for?你能提供一些这不起作用的测试用例吗?
This is how I'd write the subset_sum
:这是我会写的
subset_sum
:
def subset_sum(seq, target):
if target == 0:
return True
for i in range(len(seq)):
if subset_sum(seq[:i] + seq[i+1:], target - seq[i]):
return True
return False
It worked on a couple of examples:它适用于几个例子:
>>> subset_sum([-1,1,5,4], 0))
True
>>> subset_sum([-1,1,5,4], 10)
True
>>> subset_sum([-1,1,5,4], 4)
True
>>> subset_sum([-1,1,5,4], -3)
False
>>> subset_sum([-1,1,5,4], -4)
False
To be honest I wouldn't know how to memoize it.老实说,我不知道如何记住它。
Old Edit: I removed the solution with any()
because after some tests I found out that to be slower!旧编辑:我用
any()
删除了解决方案,因为经过一些测试我发现它变慢了!
Update: Just out of curiosity you could also use itertools.combinations
:更新:出于好奇,您也可以使用
itertools.combinations
:
from itertools import combinations
def com_subset_sum(seq, target):
if target == 0 or target in seq:
return True
for r in range(2, len(seq)):
for subset in combinations(seq, r):
if sum(subset) == target:
return True
return False
This can do better that the dynamic programming approach in some cases but in others it will hang (it's anyway better then the recursive approach).在某些情况下,这可以比动态编程方法做得更好,但在其他情况下它会挂起(无论如何它比递归方法更好)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.