Somme d'un sous-ensemble, et un mot sur « polynomial »
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 17 — Programmation dynamique
Énoncé
Le programme cite « le problème de la somme d'un sous-ensemble ». Étant donnés entiers positifs et une cible , décider s'il existe un sous-ensemble de somme exactement . Écrire l'algorithme, sa complexité, et dire pourquoi elle n'est pas polynomiale.
Corrigé
Sous-problème : vaut vrai si l'on peut atteindre la somme avec les premiers éléments.
En une seule ligne, avec la boucle décroissante de l'exercice précédent :
/* Vrai ssi un sous-ensemble de t[0..n-1] a pour somme S.
Preconditions : t[i] >= 1, n >= 0, S >= 0.
Complexite : Theta(nS) en temps, Theta(S) en memoire. */
bool sous_ensemble(const int t[], int n, int S) {
assert(n >= 0 && S >= 0);
bool a[S + 1];
a[0] = true;
for (int s = 1; s <= S; s = s + 1) { a[s] = false; }
for (int i = 0; i < n; i = i + 1) {
/* DECROISSANT : chaque element au plus une fois (exercice precedent). */
for (int s = S; s >= t[i]; s = s - 1) {
if (a[s - t[i]]) { a[s] = true; }
}
}
return a[S];
}
Mesure sur : les sommes atteignables sont
soit valeurs distinctes pour sous-ensembles : plusieurs sous-ensembles partagent donc la même somme. Les sommes non atteignables entre et sont .
Pourquoi n'est pas polynomial. C'est l'avertissement du chapitre sur , au même endroit. La taille de l'entrée est le nombre de bits nécessaires pour l'écrire, soit environ bits. Doubler le nombre de chiffres de élève au carré, donc élève le temps au carré aussi : le coût est exponentiel en la taille de l'écriture. Concrètement, et tiennent en une ligne de texte et sont hors de portée. On dit que l'algorithme est pseudo-polynomial. Le problème lui-même est np-complet (chapitre chap:decidabilite), et la programmation dynamique ne le rend pas facile : elle le rend faisable quand les nombres sont petits.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.