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

时间:2010-10-11 15:17:57

标签: algorithm complexity-theory

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

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

7 个答案:

答案 0 :(得分:40)

O(n*W)看起来像多项式时间,但,它是pseudo-polynomial

时间复杂度衡量算法作为其输入的位长的函数所花费的时间。动态编程解决方案的确是线性的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)

线性增加算法输入的大小是什么意思?这意味着逐渐使用更长的项目数组(所以nn+1n+2,...)并逐步延长W(因此,如果W为{ {1}}位长,在一步后我们使用x位,然后x+1位,...)。但是x+2随着W指数增长,因此算法不是真正的多项式,它是指数的(但看起来它是多项式的,因此名称:“pseudo -polynomial“)。


进一步参考

答案 1 :(得分:18)

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

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

  3. 假设n = 10且W = 8:

    1. n = [n1,n2,n3,...,n10]
    2. W = 1000,二进制术语(4位长)
    3. 所以时间复杂度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 = 16,但长度将是两倍:

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

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

      所需时间以指数词增加,因此它是一个NPC问题。

答案 2 :(得分:6)

这完全取决于您在O(...)内放置的参数。

如果目标权重受数量W限制,则问题的复杂性会O(n*W),如您所述。

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

答案 3 :(得分:4)

这是因为背包问题有一个伪多项式解决方案,因此被称为 weakly NP-Complete (而不是 > strongly NP-Complete 的)。

答案 4 :(得分:3)

输入的大小为权重log(W)位(O(n)为"值""权重"数组)。

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

最终的复杂性为O(n * W)

  

O(n * W)可以重写为O(n * 2ʲ),其大小与输入的大小成正比。

所以,这个解决方案不是多项式的。

答案 5 :(得分:2)

您可以阅读以下简短说明:The NP-Completeness of Knapsack

答案 6 :(得分:0)

要理解NP-completeness,你必须学习一点复杂性理论。然而,基本上,它是NP完全的,因为背包问题的有效算法也是SATTSP和其余的有效算法。