【问题标题】:Subset sum - Recover solution子集和 - 恢复解决方案
【发布时间】:2017-08-09 04:27:33
【问题描述】:

我编写了一个动态规划算法,它可以找到总和为目标值的子集的总量。但是,我无法开发一个函数来恢复解决方案(即打印出实际的子集)。

例如,我们以集合 [1,3,5,7,9,10] 为例,目标为 13。 我的算法计算出有 3 个子集。输出表如下图所示。

因为这是一个简单的集合,我可以手动确定哪三个子集构成目标。那就是:

[3,10]
[1,3,9]
[1,5,7]

但是,对于更复杂的解决方案,我将如何使用输出表递归地恢复解决方案?任何帮助表示赞赏。

【问题讨论】:

  • 如果你的算法已经告诉你存在多少和子集,你必须在算法的某个地方计算每个可能的子集,不是吗?为什么不直接使用相同的公式?

标签: algorithm dynamic sum subset recover


【解决方案1】:

警告

如果没有看到您的算法及其任何输入限制(例如,集合中是否允许重复值?),可能无法设计出适用于所有可能情况的方法。

但是,以下内容似乎适用于您的示例结果表中列出的所有情况。如果您发现这不适用于其他情况,请将这些示例添加到您的问题中。 (我忽略了 target = 0 作为特例。)

算法草图

按升序遍历目标列的结果。

当结果增加时,您已经确定了另一个子集,并在该子集中找到了最大值。

要查找子集中的剩余值,请以店员的方式“进行更改”。换句话说,沿着设定值往回走,尽可能从剩余的总数中减去。

样品运行

对于集合 [1,3,5,7,9,10] 中子集的目标总和 = 13 的给定示例:

resultCount = 0

result(13,1) is 0; this result - resultCount = 0, so no new subsets

result(13,3) is 0; this result - resultCount = 0, so no new subsets

result(13,5) is 0; this result - resultCount = 0, so no new subsets

result(13,7) is 1; this result - resultCount = 1, so resultCount = 1
                                                     and new subset = [7]
                                                     and remaining = 13 - 7 = 6
    5 < 6, so subset = [7,5] and remaining = 6 - 5 = 1
    3 > 1, so remaining is still 1
    1 = 1, so subset = [7,5,1] and remaining = 0 (subset complete)

result(13,9) is 2; this result - resultCount = 1, so resultCount = 2
                                                     and new subset = [9]
                                                     and remaining = 13 - 9 = 4
    7 > 4, so remaining is still 4
    5 > 4, so remaining is still 4
    3 < 4, so subset = [9,3] and remaining = 4 - 3 = 1
    1 = 1, so subset = [9,3,1] and remaining = 1 - 1 = 0 (subset complete)

result(13,10) is 3; this result - resultCount = 1, so resultCount = 3
                                                      and new subset = [10]
                                                      and remaining = 13 - 10 = 3
    9 > 3, so remaining is still 3
    7 > 3, so remaining is still 3
    5 > 3, so remaining is still 3
    3 = 3, so subset = [10,3] and remaining = 3 - 3 = 0 (subset complete)

识别出 3 个子集的运行结束:

[7,5,1]
[9,3,1]
[10,3]

【讨论】:

  • 啊!这个逻辑对我帮助很大。但是,这似乎有点……贪婪地恢复解决方案。假设我们在列表 [15,6,6,8,16] 中找到了目标的新结果,例如 20。如果您从任一端开始查看集合,并在可能的情况下从 20 中减去,您最终会处于一个奇怪的位置。如果我们一次找到 2 个或更多新子集,我们将需要一些方法来“标记”值。但是,尽管如此,这非常有帮助!我想我可以从这里弄清楚。
  • 是的,我假设结果表中的值是按升序排序的,因此在新示例中为 [6,6,8,15,16]。我猜目标为 20,您的算法在第 20 列中的结果为 0、0、1、1、1。但也许您的评论有错字,您的意思是 [1,5,6,6, 8,16] 在这种情况下,我猜第 20 列将显示 0、0、0、0、3、3,并且正如您所说,您需要解决同时查找多个子集的问题。开始看起来像 Cribbage 得分。无论如何,很高兴这有帮助!
猜你喜欢
  • 2010-10-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-21
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
  • 2020-11-09
相关资源
最近更新 更多