Algorithm 求和匹配的两组整数的子集的算法

Algorithm 求和匹配的两组整数的子集的算法,algorithm,bidirectional,subset-sum,Algorithm,Bidirectional,Subset Sum,我正在寻找一种算法,它可以取两组整数(正数和负数),并在每个整数中找到具有相同和的子集 这个问题类似于,只是我在两边寻找子集 下面是一个例子: 列出一个{4,5,9,10,1} 清单B{21,7,-4,180} 因此,这里唯一的匹配是: {10,1,4,9}{21,7,-4} 有人知道有没有解决这类问题的现有算法吗 迄今为止,我唯一的解决方案是一种蛮力的方法,它尝试每一个组合,但是它在指数时间内执行,并且我不得不对要考虑的元素的数量施加一个严格的限制,以避免它花费太长时间。 我能想到的唯一其他解

我正在寻找一种算法,它可以取两组整数(正数和负数),并在每个整数中找到具有相同和的子集

这个问题类似于,只是我在两边寻找子集

下面是一个例子:

列出一个{4,5,9,10,1}

清单B{21,7,-4,180}

因此,这里唯一的匹配是: {10,1,4,9}{21,7,-4}

有人知道有没有解决这类问题的现有算法吗

迄今为止,我唯一的解决方案是一种蛮力的方法,它尝试每一个组合,但是它在指数时间内执行,并且我不得不对要考虑的元素的数量施加一个严格的限制,以避免它花费太长时间。


我能想到的唯一其他解决方案是在两个列表上运行阶乘,并在那里寻找等式,但这仍然不是非常有效,而且随着列表变大,所需时间会呈指数增长。

子集和是Np完全的,您可以多项式地将问题简化为它,所以你的问题也是NP完全的。

就像子集和问题一样,这个问题是NP完全的,所以它有一个以时间多项式(M)运行的解,其中M是问题实例中出现的所有数字的和。您可以通过动态编程实现这一点。对于每个集合,您可以通过填充二维二进制表来生成所有可能的和,其中(k,m)处的“真”表示可以通过从集合的前k个元素中选取一些元素来实现子集和m

迭代填充-如果(k-1,m)设置为“真”,则将(k,m)设置为“真”(显然,如果可以从k-1元素中获取m,则可以通过不拾取第k个元素从k个元素中获取),或者如果(k-1,m-d)设置为“真”,其中d是集合中第k个元素的值(拾取第k个元素的情况)


填充表格可以得到最后一列(代表整个集合的那一列)中所有可能的总和。对这两个集合执行此操作,并找到公共和。您可以通过颠倒填写表格的过程来回溯表示解决方案的实际子集。

其他人所说的是正确的:

  • 这个问题是NP完全问题。一个简单的方法是将其简化为通常的子集和。您可以通过注意到只有当并集(-B)的非空子集和为零时,a的子集和B的子集(不是都为空)之和来说明这一点

  • 这个问题只是弱NP完全问题,因为它是一个多项式,其大小与所涉及的数字相同,但其对数是指数的。这意味着这个问题比“NP完全”这个绰号所暗示的要容易

  • 你应该使用动态规划

  • 那么我对这次讨论有什么贡献呢?好的,代码(Perl):

    它打印

    sum(4 5 9 10) = sum(21 7)
    sum(4 9 10 1) = sum(21 7 -4)
    
    因此,值得注意的是,在您的原始问题中有不止一种解决方案有效


    编辑:用户伊齐正确地指出,这个解决方案是错误的,更糟糕的是,在多个方面!!对此我非常抱歉,我希望在上面的新代码中解决了这些问题。尽管如此,仍然存在一个问题,即对于任何特定的子集和,它只打印一个可能的解决方案。与之前的问题不同,这些问题都是直接错误,我将其归类为故意限制。祝你好运,小心虫子

    非常感谢您的快速回复

    < >动态规划解决方案与我们现在所使用的穷举方法没有什么不同,我猜想如果我们需要最优解,我们确实需要考虑每一个可能的组合,但是生成这个穷尽的总和列表所需的时间太长了。 进行了快速测试,快速生成x个元素的所有可能总和所需的时间超过1分钟:

    11 elements took - 0.015625 seconds
    12 elements took - 0.015625 seconds
    13 elements took - 0.046875 seconds
    14 elements took - 0.109375 seconds
    15 elements took - 0.171875 seconds
    16 elements took - 0.359375 seconds
    17 elements took - 0.765625 seconds
    18 elements took - 1.609375 seconds
    19 elements took - 3.40625 seconds
    20 elements took - 7.15625 seconds
    21 elements took - 14.96875 seconds
    22 elements took - 31.40625 seconds
    23 elements took - 65.875 seconds
    24 elements took - 135.953125 seconds
    25 elements took - 282.015625 seconds
    26 elements took - 586.140625 seconds
    27 elements took - 1250.421875 seconds
    28 elements took - 2552.53125 seconds
    29 elements took - 5264.34375 seconds
    
    这对于我们试图解决的商业问题来说是不可接受的。。我将回到绘图板上,看看我们是否真的需要知道所有的解决方案,或者我们可以只使用一个(例如,最小/最大的子集),希望这能帮助解决问题,并使我的算法达到预期效果


    还是谢谢你

    也许你想提一提缩减:如果A和B是这个问题的集合,在通常的子集和中取一个并集(-B),你要求和0。嗨,burningmonk。在回答您刚刚删除的问题时:是.NET的伦敦用户组。这是Google dude的第一个结果!我想这里可能有个虫子。如果我用@a=qw(4 5 10)和@b=qw(14 15)运行这段代码,输出是sum(4 10)=sum(14),但是如果我只是切换@b的顺序,那么它是@b=qw(15 14),那么就没有输出了。数组是否需要排序,或者是否存在其他问题?此解决方案还存在其他问题。这里还有更多的讨论:@itzy:你完全正确!很抱歉延迟了响应--我最近没有激活堆栈溢出。感谢您注意到这些错误!
    11 elements took - 0.015625 seconds
    12 elements took - 0.015625 seconds
    13 elements took - 0.046875 seconds
    14 elements took - 0.109375 seconds
    15 elements took - 0.171875 seconds
    16 elements took - 0.359375 seconds
    17 elements took - 0.765625 seconds
    18 elements took - 1.609375 seconds
    19 elements took - 3.40625 seconds
    20 elements took - 7.15625 seconds
    21 elements took - 14.96875 seconds
    22 elements took - 31.40625 seconds
    23 elements took - 65.875 seconds
    24 elements took - 135.953125 seconds
    25 elements took - 282.015625 seconds
    26 elements took - 586.140625 seconds
    27 elements took - 1250.421875 seconds
    28 elements took - 2552.53125 seconds
    29 elements took - 5264.34375 seconds