Algorithm 如何理解背包问题是NP完全问题?
我们知道,背包问题可以通过动态规划在O(nW)复杂度下求解。但是我们说这是一个NP完全问题。我觉得这里很难理解Algorithm 如何理解背包问题是NP完全问题?,algorithm,complexity-theory,Algorithm,Complexity Theory,我们知道,背包问题可以通过动态规划在O(nW)复杂度下求解。但是我们说这是一个NP完全问题。我觉得这里很难理解 (n是项目的数量,W是最大容量。)这取决于您在O(…)中放置了哪些参数 若目标权重受到数字W的限制,那个么问题就具有O(n*W)复杂性,正如您所提到的 但若权重太大,需要的算法复杂性与W无关,那个么问题就是NP完全问题。(O(2^n*n)在最简单的实现中) 要理解,你必须学习一点复杂性理论。然而,基本上,它是NP完全的,因为背包问题的一个有效算法也是,和其他问题的一个有效算法 您可以阅
(n是项目的数量,W是最大容量。)这取决于您在
O(…)
中放置了哪些参数
若目标权重受到数字W
的限制,那个么问题就具有O(n*W)
复杂性,正如您所提到的
但若权重太大,需要的算法复杂性与
W
无关,那个么问题就是NP完全问题。(O(2^n*n)
在最简单的实现中) 要理解,你必须学习一点复杂性理论。然而,基本上,它是NP完全的,因为背包问题的一个有效算法也是,和其他问题的一个有效算法 您可以阅读以下简短解释:。O(n*W)
看起来像一个多项式时间,但它不是,它是
时间复杂度度量算法作为其输入的长度(以位为单位)函数的时间。动态规划解在W
的值上确实是线性的,但在W
的长度上却是指数的,这才是最重要的
更准确地说,背包问题动态解的时间复杂度基本上由嵌套循环给出:
// here goes other stuff we don't care about
for (i = 1 to n)
for (j = 0 to W)
// here goes other stuff
因此,时间复杂度显然是O(n*W)
线性增加算法输入的大小意味着什么?这意味着使用越来越长的项目数组(因此n
,n+1
,n+2
,…)和越来越长的W
(因此,如果W
是x
位长,在一步之后我们使用x+1
位,然后x+2
位,…)。但是W
的值随着x
呈指数增长,因此该算法不是真正的多项式,而是指数(但它看起来像多项式,因此得名为“伪多项式”)
进一步参考
假设n=10,W=8:
如果将n的大小加倍: n=[n1,n2,n3,…n10]->n=[n1,n2,n3,…n20] 所以时间复杂度T(n)=O(nW)=O(20*8)=O(160)
但是,当您将W的大小增加一倍时,这并不意味着W=16,但长度将增加一倍: W=1000->W=10000000二进制项(8位长) 所以T(n)=O(nW)=O(10*128)=O(1280)
所需时间以指数形式增加,因此这是NPC问题。输入的大小是权重的
log(W)
位(对于“值”和“权重”数组,O(n)
)
因此,权重的输入大小是j=log(W)
(而不仅仅是W
)。因此,W=2ʲ
(使用二进制)
最后的复杂性是O(n*W)
这个O(n*W)
可以重写为O(n*2ʲ)
,它与输入的大小成指数关系
所以,这个解不是多项式。其他动态规划问题呢?例如,最长的公共子序列问题可以在O(L_1*L_2)时间内解决?我们能说它不是多项式吗?@cnhk看起来有多项式复杂性,O(n^2)。但是有各种各样的DP算法,例如那些处理给定集合(2^n组合)的所有子集的算法,所以我不会说每个DP问题都可以在多项式时间内解决。有两种方法可以测量数字的大小。给定数字10和1000,可以说1000是两倍大(字符数)或一百倍大。因为差异是指数的,你可以有一个算法,它是根据数值大小测量的多项式,根据位数测量的指数。我看不出编码中的位数与这个问题有任何关系。我确实理解位数如何影响整数分解的复杂性,因为单个整数是您的“输入”。然而,这里的数字
W
和n
表示循环迭代次数。您可以按任何方式对它们进行编码,而该循环仍将迭代n*W
次。我认为这个“伪多项式”的原因是因为<代码> n>代码>是实际的输入大小,<>代码> w <代码>可以比<代码> n>代码>大得多,所以不能被公平地对待。为了帮助你理解它,1)考虑一个< <代码> > <>代码>循环,从<代码> 1 <代码>到<代码> n>代码>(其中代码< n>代码>是输入); 在这种情况下,当循环进行10^12次迭代时,输入的大小仍然在40位左右。迭代次数的增长速度快于编码输入的位数。时间复杂性不是线性的。2)再次,考虑< <代码> >循环>一个输入数组(大小为<代码> n>代码>),从<代码> 1 < /代码>到<代码> n>代码>;如果有10^12个迭代,则表示数组包含10^12个项。迭代次数的增长速度与输入的大小相同。时间比较。如果我们考虑我的例子,那么我们只需在输入中添加一个额外的位即可。有了这个,我们就完蛋了