J'ajouterais une petite chose à la réponse de DW:
J'ai vu des gens qui pensent que parce que Knapsack unaire est en P, nous pouvons donc l'utiliser à la place de Knapsack dont les meilleurs algorithmes actuels ont un temps exponentiel.
Soit l'entrée = et k et considérons l'algorithme de programmation dynamique pour Knapsack et unary Knapsack. Le temps d'exécution pour les deux est O ( n k ) . C'est le même temps d'exécution. C'est-à-dire que si vous avez une entrée, peu importe si vous utilisez la programmation dynamique pour Knapsack unaire ou la programmation dynamique pour Knapsack. Les deux prendront (à peu près) le même temps pour résoudre l'instance problématique. Théoriquement, partout où vous en utilisez un, vous pouvez également utiliser l'autre. Vous avez juste besoin de convertir des nombres de unaire en binaire et vice versa.W={w1,…,wn}kO(nk)
Quel est donc l'intérêt de définir la complexité des algorithmes par rapport à la taille des entrées? Pourquoi ne pas toujours les énoncer en termes de paramètres comme ?O(nk)
Si vous vous souciez d'un problème isolément, vous pouvez le faire. En fait, c'est ce que font souvent les utilisateurs d'algorithmes. La complexité des algorithmes de graphe est souvent exprimée en termes de nombre de sommets et de nombre d'arêtes, et non de la taille de la chaîne qui les code.
Mais ce n'est que lorsque nous avons affaire à un problème isolé. Il n'est pas utile lorsque nous traitons des problèmes avec différents types d'entrées. Pour les graphiques, nous pouvons parler du temps d'exécution par rapport au nombre de sommets et d'arêtes. Pour Knapsack, nous pouvons parler du nombre d'articles et de la taille du Knapsack. Mais que faire si nous voulons parler des deux? Par exemple, lorsque nous voulons réduire les problèmes ou discuter d'une classe de problèmes qui inclut des problèmes arbitraires, pas seulement ceux avec un graphique en entrée. Nous avons besoin d'un paramètre universel d'entrées. Une entrée en général n'est qu'une chaîne, c'est nous qui interprétons ses symboles comme des nombres unaires, des nombres binaires, des graphiques, etc. Pour développer une théorie générale de la complexité de l'algorithme et des problèmes, nous avons besoin d'un paramètre général des entrées. La taille de l'entrée est un choix évident et elle s'avère suffisamment robuste pour que nous puissions construire une théorie raisonnable par-dessus. Ce n'est pas la seule possibilité. Pour un artificiel, nous pouvons construire une théorie basée sur à la taille de l'entrée. Cela fonctionnera bien.2
Maintenant, nous décidons d'utiliser la taille comme paramètre universel des entrées, cela nous oblige à penser au codage des objets en termes de chaînes. Il existe différentes manières de les coder et elles peuvent avoir différentes tailles. (Ils rendent également différentes choses faciles / difficiles.) En termes de théorie générale des algorithmes, que nous codions le nombre d'entrée en unaire ou binaire devient important. Si nous utilisons unaire et que la taille de est 100, le plus grand nombre que nous obtiendrons est 100 . Si nous utilisons le binaire, k peut être aussi grand que 2 100 - 1 . Donc, quand nous parlons du temps d'exécution de la résolution des problèmes de sac à dos où la taille de kk100100k2100−1kk2100−1
nnp(n)kp(n)k2p(n)−1kk
nk