【问题标题】:How to understand the subset-sum issue如何理解子集和问题
【发布时间】:2013-01-03 16:56:23
【问题描述】:

我正在学习子集和问题,我想在这里问一些问题

(1)Subset Sum algorithm

刚才看了这个链接的C代码,不知道作者为什么可以定义?

S[i,0]=true ,S[0,j]=false

S[i,0] 表示subset[1,...i] 等于0,为什么它可以分配给true.?如果要打印子集的内容,我该如何修改这个算法? 因为好像禁止和作者私聊,所以我要贴出来。

(2)如果数组中有负数,我试过测试不合适。如何定义S[i,0]S[0,j]的初始值?

谁能帮我澄清一下?

提前致谢!

【问题讨论】:

    标签: c algorithm subset-sum


    【解决方案1】:

    建议的基本子句有问题,因为有了它,你也可以将s[n,0]作为初始值。

    对子集和的递归公式更好的停止子句是s[i,xi] = true。这个想法很简单,集合{x1,x2,...,xi} 包含一个子集,总和为xi - 它是子集{xi}。递归将稍后处理其余部分,如果有一个子集总和为 0,它会找到它。

    根据这种方法,基本子句是:

    s[i,xi] = true (for each i)
    s[0,j] = false (for each j)
    

    而递归公式为:

    s[i,j] = s[i-1,j] OR s[i-1,j-xi]
    

    要获取子集中实际存在哪些元素,您需要遵循使用动态规划构建的矩阵。 “遵循”矩阵所做的选择,并坚持一条产生 true 的路径,直到找到“停止子句”(s == xi)

    可以递归描述为:

    getSubset(i,s):
       if s[i-1,s]: //there is a solution without choosing xi
           return getSubset(i-1, s)
       if (xi == s): //true base clause
            l <- new list
            l.append(xi)
            return l
       if s[i -1, s-xi]: //there is a solution when choosing xi
            l <- getSubset(i-1,s-xi)
            l.append(xi)
            return l
    

    很像(确保你明白为什么):How to find which elements are in the bag, using Knapsack Algorithm [and not only the bag's value]?

    【讨论】:

    • 如果要定义s[i,xi]=true,会不会占用更多的空间?因为xi的值可能很大。而且总和可能不会那么大,更小。跨度>
    • @liumilan:不,它不会花费更多空间。在某些时候,您将不得不在这两种方法中计算 s[i,xi] - 因此无论如何都必须存储这个值。请注意,您提出了这个解决方案的一个重要问题 - 它是 伪多项式,即它消耗的时间(和空间)线性取决于子集中的数字 - 比特数是指数的需要代表他们。
    猜你喜欢
    • 2011-01-22
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多