如何理解子集和问题

时间:2013-01-03 16:56:24

标签: c algorithm subset-sum

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

(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]的初始值?

有人可以帮我澄清一下吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

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

subset-sum的递归公式的更好的停止子句是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]

要获取实际位于子集中的元素,您需要遵循使用动态编程构建的矩阵。 “跟随”矩阵所做的选择,并坚持产生真实的路径,直到找到“停止子句”(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]?