繁体   English   中英

我怎样才能减少子集和问题的时间复杂度

[英]how can i reduce the time complexity of subset sum problem

所以最近我一直在尝试解决一些有趣的问题,但在这个问题上陷入了困境。

给定一组对象 1 到 N。n1 个值为 0 的对象和 n2 个值为 1 的对象和 n3 个值为 2 的对象。需要计算总和为 3 或其倍数的所有子集。

n1+ n2 + n3 = N <= 100000 在满足上述条件的情况下,n1、n2、n3的值也可以为0。

我已经能够解决问题,但无法降低这个问题的时间复杂度。 我的解决方案仍然具有指数时间复杂度。 我试图降低时间复杂度,以便我可以在 5 秒内运行 N = 100,000 的大型集合。

这是我偶然发现的另一个简单但直观的解决方案,但问题又是时间复杂度。

def mask(lst, m):
    # pad number to create a valid selection mask
    # according to definition in the solution laid out
    m = m.zfill(len(lst))
    return map(lambda x: x[0], filter(lambda x: x[1] != '0', zip(lst, m)))

def subset_sum(lst, target):
    # there are 2^n binary numbers with length of the original list
    for i in range(2**len(last)):
        # create the pick corresponsing to current number
        pick = mask(lst, bin(i)[2:])
        if sum(pick) == target:
            yield pick

我不需要确切的编码解决方案,但如果你能指出正确的方向并且任何编程语言都可以,那就太好了,我想知道解决方案的逻辑/方法。

看起来,给定一个数字数组(所有数字均为 0、1 或 2),您想要返回这些数字的每个子集,这些数字总和为 3 的倍数,并且您希望以多项式的方式进行。

这是不可能的。

要看到这一点,请考虑数组 [2,1,0,0,0,0,0,...,0]。 为了得到 3 的总和,我们将始终需要前两个数字,但除此之外,任何子集总和为 3。因为我们有N-2 0,所以总共有2**(N-2)个子集符合要求。 无法在多项式时间内返回指数数量的答案。

所以这里的一个关键知识就是和必须是3的倍数,即sum = 0 (mod 3)。

这意味着您可以在任何子集中包含尽可能多或尽可能少的 n1,因为它们不会改变总和。

因此,您可以立即将问题简化为从 n2 和 n3 中找到总和为 0 (mod 3) 的子集,然后将所有可能的 2**n1 个子集添加到这些子集。 请注意,对于 n1 的任何显着值(如 50 以上),列出它们变得无法计算。

但是很容易计算:

那么 go 如何从 n2 和 n3 中找到 sum = 0 (mod 3) 的集合。 我们知道 n2 中的任何元素都会使总和增加 1,给定 n2 中的 m 个元素,我们可以计算出有多少个元素是可能的

所以一个用于计数的松散伪代码:

def f(n1,n2,n3):
    for i in range(0,n2+1):
        # i elements of n2
        # compute i%3
        # if i%3 0 then we can pick j = 0,3,6,9 ... elements from n3
        # if i%3 1 then we can pick j = 1,4,7,10 .. elements from n3
        # if i#3 2 then we cannot j = 2, 5, 8, 11 .. elements from n3
        # compute the combination c = (n choose i) * (n choose j) for each j
        # for each c multiply by 2**n1 (adding on all possible subsets from n1)

暂无
暂无

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

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