子集总和:将特殊情况减少为一般情况


20

Wikipedia指出子集总和问题是找到给定整数集合的总和为零的子集。进一步说,这等同于为任何给定找到具有和的子集。ss

因此,我认为,因为它们是等效的,所以任何一方都必须减少。通过设置s = 0,从到零的1是微不足道的。但是我没有运气找到从零到减少小号,即给定的一组整数,构建一组整数包含与总和的子集小号(对于任何小号),当且仅当有作为子集与总和为零。ss=0sABssA

你能给我一些指导吗?

Answers:


11

实际上,您已经从特殊降至一般。通过设置s=0,您基本上是在使用通用算法来解决特殊问题。

另一方面(即从一般减少为特殊):

假设你正在给一组S={x1,,xn}和一些K,你必须确定是否存在的一些子集S其资金以K

现在,您要解决此问题,给定一种算法,可以确定某些子集的总和是否为0

现在,如果xi>0,我们可以轻松地简化为:S={x1,x2,,xn,K}

S具有和的一个子集0当且仅当S具有总和的一个子集K

当我们可以为某些i设置x_i \ le 0时,就会出现问题。xi0i

我们可以假设K>0(为什么?)。

假设正的总和是和负是。 P X ÑxiPxiN

现在构造一个新的集合这样S={y1,y2,yn}

M = P + | N | + Kyi=xi+M,其中。M=P+|N|+K

每个。yi>0

现在在集合上运行零子集和算法

S{(K+M)}

S{(K+2M)}

S{(K+3M)}

S{(K+nM)}

容易表明,如果具有总和的子集,则以上集合中的至少一个具有总和为零的子集。ķSK

我会将另一方向的证明留给您。


非常感谢你。我想知道,是否存在将0-子集和实例转换为K(子集)实例(而不是)的简化方法?n
ipsec 2013年

@ipsec:您的意思是将K-subset-sum的实例转换为0-subset-sum?也许采取上面的集合的和会起作用。n
Aryabhata

好吧,我实际上是在三思而后行。考虑到事实,我想证明每个K的K-subset-sum是NP-hard,则0-subset-sum是NP-hard,我可以使用从0-subset-sum到K-subset-sum的归约法。 ,为此,我需要从0实例到K实例的多次转换。但是我现在不确定这实际上是我在问题中提出的内容。
ipsec 2013年

@ipsec:当您说set,您已经给出了给定零子集和的NP-Hardness的子集和的NP-Hardness:一般问题至少与特殊问题一样困难。请注意,用缩减术语来说,是说您已将零子集和降低为子集和。另外,请注意,是输入。当您谈论“每个给定的 ”时,您到底是什么意思?上面的答案表明,特殊情况(零子集和)与一般情况(子集和,其中是输入)一样硬(在NP硬度意义上)。K K K K k ks=0KKKKkk
Aryabhata

没关系。我最初想知道的是,如果我们知道0个子集和是NP难解的,我们是否可以得出,例如1个子集和也是?维基百科是这样说的,但我一直在寻找适当的减少方法。但是,现在我看到我的措辞被完全弄乱了,实际上我是在问相反的意思。无论如何,对于任何给定的整数K和L,您都给我足够的输入以将其从任何K-子集和实例减少到L-子集和实例,因此我的问题仍然得到解决。
ipsec 2013年

0

可以通过以下事实来固定Aryabhata的答案:我们可以将所有数字乘以一个大,然后在每个数字上加上一些小数字以充当“状态标签”,然后提供一些额外的数字以使我们去零,如果我们能得到没有他们。具体来说,我们将使用和1作为状态标记。cc K c = 2 n + 1 cKc=2(n+1)

给定目标值为的一般问题的实例,我们将创建特定问题的实例(目标值为0),该实例包含:(S={x1,,xn},K)K

  • Y={y1,,yn},其中。yi=2(n+1)xi+1
  • 数。z=2K(n+1)n
  • n1个数字副本,称为“上拉”数字。

我假设随着Aryabhatta的出现,为正。(由于已经有6年了,所以我将为读者回答他的练习:之所以这样做,是因为如果我们在一般问题的一个实例(包括交换所有数字的符号,则最后得到一个新的等价问题实例,这意味着一个解决正实例的算法就足以解决任何问题-要解决一个负实例,我们可以执行此符号交换,运行该算法并将其答案转发为原始问题的答案。当然,如果那么我们根本不需要将一般情况转换为特殊情况!)KK K K K = 0KKKK=0

首先让我们证明,对一般问题的给定实例的是,对特殊问题的构造实例的回答是。 在这里,我们可以假设一些解决方案一般的问题存在:那就是,这个非空集合数的款项,以。因此,如果我们采取相应 -值到我们的解决方案的构造实例,它们将总结到。然后,我们可以选择在解决方案中包括,使我们剩下。由于,这在范围内{xj1,,xjm}mKy{yj1,,yjm}2K(n+1)+m2K(n+1)nmn1mn[n+1,0],我们可以通过包含一些上拉数字来成功上拉到0。

现在,让我们说明对构造实例的“是”答案意味着对原始给定实例的“是”答案。 在这里,乘以变得很重要-这就是使我们可以确定所包含的额外数字不能“做太多”的地方。2(n+1)

在这里,我们可以假定存在一些构造实例的解决方案:也就是说,此数字的非空集合的总和为0根据问题要求,该解决方案至少包含一个要素。此外,它必须至少包含一个元素,因为没有它,就不可能达到0的总数:如果仅存在上拉数字,则总和必须在范围内(注意,在这种情况下必须至少存在一个上拉数字,并且所有上拉均严格为正,因此总和不能为0);而如果解决方案仅由和一些上拉数组成,则总数必然为负,因为{yj1,,yjm}mY[1,n1]ž ž = - 2 ķ Ñ + 1 - ñ - ñ ñ - 1zz=2K(n+1)nn,上拉数字最多可以将和增加。n1

现在假设矛盾的是,解不包含。每个元素都包含两个术语:倍数和+1“状态标记”。请注意,如果选择了该元素,则的元素中的每个元素上的+1项会使总和增加1,所选择的最多拉数字中的每个数字也是如此,因此这2元素的总和任何解决方案的来源至少为1(因为我们在上一段中确定,必须选择至少一个元素),并且最多。特别是,这意味着这两组项的总和取模时zY2(n+1)nYn1Yn+n1=2n12(n+1) z 2 n + 1 Y 2 n + 1 2 n + 1 ž = - 2 ķ ñ + 1 -为非零。在解决方案不包含的假设下,该总和中仅有的其他分量是的选定成员贡献的的倍数,当取模。因此,以模为模时,解中所有项的总和为非零,这意味着它不能等于目标总和0,这意味着它根本不是有效的解:我们发现了一个矛盾,这意味着必须在每个解决方案中都存在。z2(n+1)Y2(n+1)2(n+1)z=2K(n+1)n

因此,每个解决方案都包含。我们知道z

(2K(n+1)n)+i=1m(2(n+1)xji+1)+pull-ups=0

我们可以重新排列以下术语:

2K(n+1)+i=1m(2(n+1)xji)(n+i=1m1+pull-ups)=0

2K(n+1)+i=1m(2(n+1)xji)(n+m+pull-ups)=0

2(n+1)(K+i=1mxji)(n+m+pull-ups)=0

由于总和为0,取为模时必须保持为0 ,这意味着我们可以舍弃所有包含倍数的项,以获得新方程2(n+1)2(n+1)

(n+m+pull-ups)=0

可以直接将其代入前面的等式以获得

2(n+1)(K+i=1mxji)=0

最后,将两边除以叶子2(n+1)

K+i=1mxji=0

这为原始的一般问题实例提供了解决方案。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.