views:

150

answers:

4

We know that the knapsack problem can be solved in O(nW) complexity by dynamic programming. But we say this is a NP-complete problem. I feel it is hard to understand here.

(n is the number of items. W is the maximum volume.)

+2  A: 

It all depends on which parameters you put inside O(...).

If target weight is limited by number W, then problem has O(n*W) complexity, as you mentioned.

But if weights are way too big and you need algorithm with complexity independent of W, then problem is NP-complete. (O(2^n*n) in most naive implementation).

Nikita Rybak
What about other dynamic programming problem? For example, the longest common subsequence problem can be solved in O(L_1*L_2) time? Can we say it is not polynomial?
cnhk
@cnhk Looks like it has polynomial complexity, O(n^2). But there're all kinds of DP algorithms, for example the ones working on all subsets of given set (2^n combinations), so I wouldn't say every DP problem can be solved in polynomial time.
Nikita Rybak
+2  A: 

To understand NP-completeness, you have to learn a bit of complexity theory: you ain't gonna get that from SO! However, basically, it's NP-complete because an efficient algorithm for the knapsack problem would also be an efficient algorithm for SAT, TSP and the rest.

As @Nikita points out, the bounded target weight version isn't in NP but in P. That version can't be used to solve any NP-complete problems (efficiently).

Pontus Gagge
everything in P is in NP
sdcvvc
A: 

you can read this short explanation: http://www.derf.net/knapsack/#KnapNP (The NP-Completeness of Knapsack) i hope it will help you

dfens
+7  A: 

The trick is: O(nW) looks like a polynomial time, but it is not, it is pseudo-polynomial. Time complexity measures the time that an algorithm takes as function of the length in bits of its input. The dynamic programming solution is indeed linear in the value of W but exponential in the length of W - and that's what matters.

Further references:

EDIT

The time complexity of the dynamic solution for the Knapsack problem is basically given by a nested loop:

// here goes other stuff we don't care about
for (i = 1 to n)
    for (j = 0 to W)
        // here goes other stuff

Thus, the time complexity is clearly O(nW). What does it mean to increase linearly the size of the input of the algorithm? It means using progressively longer item arrays (so n, n+1, n+2, ...) and progressively longer W (so if W is x bit long, after one step we use x+1 bits, then x+2 bits, ...). But the value of W grows exponentially with x, thus the algorithm is not really polynomial, it's exponential (but it looks like it is polynomial, hence the name: pseudo-polynomial)

Giuseppe Cardone
“but exponential in the size of W” Why?
cnhk
*"Time complexity measures the time that an algorithm takes as function of the size of its input."* Could you give a link, please?
Nikita Rybak
@Nikita: http://en.wikipedia.org/wiki/Computation_time "the time complexity of an algorithm quantifies the amount of time taken by an algorithm to run as a function of the size of the input to the problem", or http://www.ccs.neu.edu/home/rjw/csu390-f06/LectureMaterials/Time-Complexity.pdf
Giuseppe Cardone
@cnhk Follow http://websrv.cs.umt.edu/classes/cs531/index.php/Complexity_of_dynamic_programming_algorithm_for_the_0-1_knapsack_problem_3/27 , there's an handy table that show that as the size of W grows linearly, the time complexity grows exponentially.
Giuseppe Cardone
@Giuseppe Cardone I still can't understand. All integer numbers in computer are represented in binary. Why we say W has exponential complexity in the size of the input? And what about n?
cnhk
@cnhk Think about factorization by trial division. You can factor integer n in O(n) time, but expressing the number n in binary needs only m = log n bytes. So the algorithm is O(2^m), which is not polynomial.
sdcvvc
@cnhk I edited my answer, I hope it shows what it means to make the size of the input grow (i.e.: making the input array longer and the size of W (in bits) longer)
Giuseppe Cardone
There's two ways to measure the size of numbers. Given the numbers 10 and 1000, you can say that 1000 is either twice as big (in number of characters) or one hundred times as big. Since the difference is exponential, you can have an algorithm that's polynomial measured against numeric magnitude and exponential measured against number of bits.
David Thornley
Good answer. It might be slightly clearer to write "length of the input in bits" rather than "size of the input".
Reid Barton
@Reid good point, edited.
Giuseppe Cardone