【问题标题】:How can I memoize this subset sum algorithm?我怎样才能记住这个子集和算法?
【发布时间】:2016-12-02 15:47:01
【问题描述】:

这和这个问题不一样:find all subsets that sum to a particular value 因为我不仅需要count 子集的总数,还需要存储所有子集并返回它。

我编写了一个简单的(指数)算法,可以找到汇总到特定目标的子集:

Eg:
arr = [1,2,3,4,5,6,7,8]
Possible subsets:
5
4,1
3,2

这是我的算法

n -> 列表索引(从末尾开始)

目标 -> 我要创建的子集的总和

arr = [1,2,3,4,5,6,7,8]
def subset_sum(arr, n, target, result):

    if target == 0:
        print result
        return

    if target < 0 or n < 0:
        return False



    subset_sum(arr, n-1, target - arr[n], result + str(arr[n]))
    subset_sum(arr, n - 1, target, result)

print subset_sum(arr, len(arr) - 1, 5, '' )

我希望优化这一点,可能通过记忆。 但是我很难弄清楚这个函数的状态应该是什么(应该是ntarget?.. 但我不认为它会重复)

【问题讨论】:

  • subset_sum(n) 先前计算的结果是什么? subset_sum(n-1)。存储每个 n-1 的所有子集似乎是合理的。
  • 是的,但我不知道如何将结果(子集编号)存储在缓存中。我希望以自上而下的方式记住它。
  • 当您说您不知道如何存储它时,您必须更具体地说明问题所在。您是否完全不知道可用的数据结构,或者您在选择一种数据结构时遇到了麻烦?为什么不选择一个并做一些初步分析?
  • @MichaelFoukarakis 我的意思是我不知道如何将预缓存结果(可能包含多个结果)存储在缓存字典中。通常 cache[n] 存储 True 或 False ,这意味着它是否可能从状态 n 到达解决方案。另外,这里的 n 不是这个函数的唯一状态:它可能是 ntarget 的组合,可以用作缓存结果的唯一状态。

标签: python algorithm dynamic-programming


【解决方案1】:

“我没有看到它被重复。”

考虑一个具有重复值或零的数组的简单示例。
例如arr = [3,2,4,5,0,5],并且您正在寻找总和为 7 的子集,请参见此处索引 3(如果起始索引为 1),结果 2 被命中两次,一次最后 5 个包含在答案中,当它从答案中排除时再次包含在答案中
为了更清楚,请在此处查看另一个示例
arr = [5,2,3,6,3,5,8],您正在寻找总和 12,您选择最后一个索引,即 7,然后离开 6,5,因此总和 4 达到索引 4,或者您离开索引7 并选择索引 6,5 并再次以总和 4 到达索引 4。
所以这里需要memoization。
您还可以通过构建一个由 n 行和列求和的矩阵来解决问题,反之亦然。

【讨论】:

  • 谢谢!这是有道理的。
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多