web-dev-qa-db-fra.com

Comment comprendre que le problème du sac à dos est NP-complet?

Nous savons que le problème du sac à dos peut être résolu en complexité O(nW) par programmation dynamique. Mais nous disons que c'est un problème NP-complet. Je pense qu'il est difficile à comprendre ici.

(n est le nombre d'éléments. W est le volume maximum.)

70
cnhk

O(n*W) ressemble à un temps polynomial, mais ce n'est pas , c'est pseudo-polynôme .

La complexité temporelle mesure le temps qu'un algorithme prend en fonction de la longueur en bits de son entrée. La solution de programmation dynamique est en effet linéaire dans la valeur de W, mais exponentielle dans la longueur de W - et c'est ce qui compte!

Plus précisément, la complexité temporelle de la solution dynamique pour le problème de sac à dos est essentiellement donnée par une boucle imbriquée:

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

Ainsi, la complexité temporelle est clairement O(n*W).

Que signifie augmenter linéairement la taille de l'entrée de l'algorithme? Cela signifie utiliser des tableaux d'éléments progressivement plus longs (donc n, n+1, n+2, ...) et progressivement plus longs W (donc, si W fait x bits de long, après une étape nous utilisons x+1 bits, puis x+2 bits, ...). Mais la valeur de W croît de façon exponentielle avec x, donc l'algorithme n'est pas vraiment polynomial, il est exponentiel (mais il lui ressemble est polynomiale, d'où le nom: "pseudo-polynôme").


Références complémentaires

41
Giuseppe Cardone

Dans le problème du sac à dos 0/1, nous avons besoin de 2 entrées (1 tableau et 1 entier) pour résoudre ce problème:

  1. un tableau de n articles: [n1, n2, n3, ...], chaque article avec son indice de valeur et son indice de poids.
  2. entier W comme poids maximum acceptable

Supposons que n = 10 et W = 8:

  1. n = [n1, n2, n3, ..., n10]
  2. W = 1000 en terme binaire (4 bits de long)

donc la complexité temporelle T(n) = O(nW) = O (10 * 8) = O (80)


Si vous doublez la taille de n:

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

donc complexité du temps T(n) = O(nW) = O (20 * 8) = O (160)


mais comme vous doublez la taille de W, cela ne signifie pas W = 16, mais la longueur sera deux fois plus longue:

W = 1000 -> W = 10000000 en terme binaire (8 bits de long)

donc T(n) = O(nW) = O (10 * 128) = O (1280)

le temps nécessaire augmente en terme exponentiel, c'est donc un problème NPC.

20
YoEugene

Tout dépend des paramètres que vous mettez dans O(...).

Si le poids cible est limité par le nombre W, alors le problème a une complexité O(n*W), comme vous l'avez mentionné.

Mais si les poids sont beaucoup trop grands et que vous avez besoin d'un algorithme avec une complexité indépendante de W, alors le problème est NP-complet. (O(2^n*n) dans la plupart des implémentations naïves).

6
Nikita Rybak

C'est parce que le problème de sac à dos a une solution pseudo-polynomiale et est donc appelé faiblement NP-Complete (et non fortement NP-Complete).

4
Manav Kataria

La taille de l'entrée est log(W) bits pour le poids (et O(n) pour les tableaux "valeur" et "poids").

Ainsi, la taille d'entrée du poids est j = log(W) (et non pas simplement W). Donc, W = 2ʲ (Car le binaire est utilisé).

La complexité finale est O(n * W)

Cette O(n * W) peut être réécrite en O(n * 2ʲ), dont la taille de l'entrée est exponentielle.

Donc, cette solution n'est pas polynomiale.

3
kaushalpranav

Vous pouvez lire cette courte explication: The NP-Completeness of Knapsack .

2
dfens

Pour comprendre NP-exhausteness , vous devez apprendre un peu de théorie de la complexité. Cependant, fondamentalement, il est NP-complet car un algorithme efficace pour le problème du sac à dos serait également un algorithme efficace pour SAT , TSP et le reste.

0
Pontus Gagge