我们知道背包问题可以通过动态编程以O(nW)复杂度来解决。但我们说这是一个NP完全问题。我觉得这里很难理解。
(n是项目数.W是最大音量。)
答案 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)
。
线性增加算法输入的大小是什么意思?这意味着逐渐使用更长的项目数组(所以n
,n+1
,n+2
,...)并逐步延长W
(因此,如果W
为{ {1}}位长,在一步后我们使用x
位,然后x+1
位,...)。但是x+2
的值随着W
指数增长,因此算法不是真正的多项式,它是指数的(但看起来它是多项式的,因此名称:“pseudo -polynomial“)。
答案 1 :(得分:18)
在背包0/1问题中,我们需要2个输入(1个数组和1个整数)来解决这个问题:
假设n = 10且W = 8:
所以时间复杂度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完全的,因为背包问题的有效算法也是SAT,TSP和其余的有效算法。