繁体   English   中英

子集和变化,动态规划

[英]Subset sum variation, dynamic programming

我正在尝试解决经典的子集总和问题,但需要注意的是子集的总和应该尽可能接近tgt而不会超过它。 这是我的递归,它找出数字子集的总和与数字之间的距离,它按预期工作。 inf承认如果总和超过tgt ,我们不想要它:

def targetSum(S, i,  tgt):
    # your code here
    k = len(S)
    #base case
    if tgt < 0:
        return float('inf')
    if i >= k and tgt >= 0:
        return tgt
    else:
        return min(targetSum(S, i+1, tgt-S[i]), targetSum(S, i+1, tgt))

对于备忘录表,以下是说明:

使用 [(,)] 形式的备忘录表记住您的重复,其中 0≤≤() 和 0≤≤。 在代码中添加 function lookupMemoTable 可能会有所帮助,以帮助您处理 <0 的查找。 假设目标满足 tgt >= 0。

我无法弄清楚 function lookupMemoTable (这可能是我的问题),但这是我的代码到目前为止,它适用于一些示例(a1 = [1, 2, 3, 4, 5, 10],tgt = 15)但不是全部(a3= [11, 23, 37, 48, 94, 152, 230, 312, 339, 413], tgt = 457):

def memoTargetSum(S, tgt):
    k = len(S)
    assert tgt >= 0
    ## Fill in base case for T[(i,j)] where i == k
    T = {} # Memo table initialized as empty dictionary
    for j in range(tgt+1):
        T[(k,j)] = j
        #print(T[(k,j)], j)
        
    #def lookupMemoTable

    for i in range(k-1, -1, -1):
        for j in range(tgt, -1, -1):
            if T[(i + 1, j)]-S[i] < 0:
                T[(i,j)] = T[(i + 1, j)]
            else:
                T[(i,j)] = T[(i + 1, j)]-S[i]
    print(T)
    return T

在此先感谢您的帮助!

我认为你不必完全改变整个 function。 该表用于存储以后可以再次使用的计算。 您可以将每个递归调用的结果添加到您的dict 如果使用相同的输入再次调用 function ,您可以简单地返回dict内的值。 例如,像这样:

a3 = [11, 23, 37, 48, 94, 152, 230, 312, 339, 413]
tgt = 457

mem = {}

def targetSum(S, i,  tgt):
    k = len(S)
    
    # If calculation with this input is already computed return result from mem
    if (i,tgt) in mem:
        print('used mem')
        return mem[(i,tgt)]
    
    if tgt < 0:
        return float('inf')
    if i >= k and tgt >= 0:
        return tgt
    else:        
        minimum =  min(targetSum(S, i+1, tgt-S[i]), targetSum(S, i+1, tgt))
        
        # Store result of current calculation in mem if needed again later
        mem[(i,tgt)] = minimum
        return minimum
        

targetSum(a3, 0, tgt)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM