如何理解背包问题是NP完全?

cnh*_*nhk 71 algorithm complexity-theory

我们知道背包问题可以通过动态编程以O(nW)复杂度来解决.但我们说这是一个NP完全问题.我觉得这里很难理解.

(n是项目数.W是最大音量.)

Giu*_*one 41

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
Run Code Online (Sandbox Code Playgroud)

因此,时间复杂性显而易见O(n*W).

线性增加算法输入的大小意味着什么?这意味着使用越来越长的项目阵列(所以n,n+1,n+2,...),并逐渐变长W(所以,如果Wx位长,一步之后,我们使用x+1位,则x+2位,...).但是W增长呈指数级增长x,因此算法不是真正的多项式,它是指数的(但它看起来像是多项式,因此名称:"伪多项式").


进一步的参考

  • 为了帮助你理解它__1)__考虑一个`for`循环,它从`1`变为`n`(其中`n`是输入); 在这种情况下,当你的循环进行10 ^ 12次迭代时,输入的大小仍然是大约40位.迭代次数的增长速度快于编码输入的位数.时间复杂度不是线性的.__2)__再次考虑一个`for`循环,它遍历输入数组(大小为'n`)从`1`到'n`; 如果你有10 ^ 12次迭代,那么这意味着你的数组包含10 ^ 12项.迭代次数的增长速度与输入的大小相同.时间compl.是线性的. (4认同)
  • @AkshayLAradhya如果我们考虑我的例子,那么让我们只添加一个额外的位到输入.有了这个,我们将迭代次数加倍(额外的10 ^ 12次迭代),但输入的长度只增加了一次.随着下一个额外的位,我们将获得更多的额外迭代.等等.因此,"迭代次数增长的速度快于编码输入所需的位数",其中输入表示迭代次数.得到它了?:-) (4认同)
  • 我没有看到编码中的位数与此问题有任何关系.我确实理解了位数如何影响整数分解的复杂性,因为单个整数是你的"输入".但是,这里的数字"W"和"n"表示循环迭代的**数.**您可以按照您想要的任何方式对它们进行编码,并且该循环仍将迭代"n*W"次.我相信这个"​​伪多项式"的原因是因为`n`是实际输入大小,而`W`可能比`n`大得多,所以不能公平地将其视为常数. (3认同)
  • 有两种方法可以衡量数字的大小.给定数字10和1000,你可以说1000是两倍大(字符数)或一百倍大.由于差异是指数的,因此您可以使用一种算法,该算法的多项式是针对数字量值进行测量的,而指数是针对位数进行测量的. (2认同)
  • 对我来说,让我点击的是,对于背包问题的输入,n 不是数字,它是实际的东西,而 W 是一个数字。你无法解决重量为 10 和物品数量为 6 的背包问题。你实际上需要 n 成为事物......一个增长的数组。我们表示 n(一个数组)的 SIZE 的方式是用一个数字,但我们表示 W(一个数字)的 SIZE 的方式是用位。 (2认同)

YoE*_*ene 20

在背包0/1问题中,我们需要2个输入(1个数组和1个整数)来解决这个问题:

  1. n个项目的数组:[n1,n2,n3,...],每个项目都有其值索引和权重索引.
  2. 整数W作为可接受的最大重量

假设n = 10且W = 8:

  1. n = [n1,n2,n3,...,n10]
  2. 二进制项W = 1000 (4位长)

所以时间复杂度T(n)= O(nW)= O(10*8)= O(80)


如果你加倍n的大小:

n = [n1,n2,n3,...,n10 ] - > n = [n1,n2,n3,...,n20 ]

所以时间复杂度T(n)= O(nW)= O(20*8)= O(160)


但是当你把W的大小加倍时,它并不意味着W = 20,但长度是两倍长:

W = 1000 - > W = 10000000二进制项(8位长)

所以T(n)= O(nW)= O(10*128)= O(1280)

所需的时间以指数项增加,因此这是一个NPC问题.


Nik*_*bak 6

这一切都取决于你放在哪个参数O(...).

如果目标权重受数量限制W,那么问题O(n*W)就像你提到的那样复杂.

但是如果权重太大而你需要复杂性独立的算法W,那么问题就是NP完全.(O(2^n*n)在最天真的实施中).


kau*_*nav 6

输入的大小是log(W)权重的位(以及O(n)“值”和“权重”数组)。

\n\n

因此,权重的输入大小为j = log(W)(而不仅仅是W)。所以,W = 2\xca\xb2(使用二进制时)。

\n\n

最终复杂度为O(n * W)

\n\n
\n

O(n * W)可以重写为O(n * 2\xca\xb2),它与输入的大小呈指数关系。

\n
\n\n

所以,这个解不是多项式。

\n