La partition équilibrée
Exercice · informatique (tronc commun des prépas scientifiques), chapitre 18 — La programmation dynamique
Énoncé
On souhaite diviser un ensemble d'entiers positifs, par exemple , en deux sous-ensembles dont les sommes sont les plus proches possibles. (a) Formuler la récurrence booléenne définissant si une somme peut être formée par un sous-ensemble d'éléments. (b) Implémenter cet algorithme en Python, identifier la meilleure somme (où est la somme totale) et reconstruire le sous-ensemble correspondant. (c) Exprimer sa complexité et préciser le terme "pseudo-polynomial".
Corrigé
(a) Pour chaque élément du tableau, la somme est atteignable si elle l'était déjà avant de considérer , ou si la somme était atteignable (en choisissant d'intégrer ). (b)
def partition_equilibree(t: list) -> tuple:
S = sum(t)
atteignable = [True] + [False] * (S // 2)
temoin = [None] * (S // 2 + 1) # Stocke l'élément ayant permis d'atteindre la somme s
for x in t:
# Parcours à rebours pour éviter de réutiliser le même élément plusieurs fois
for s in range(S // 2, x - 1, -1):
if not atteignable[s] and atteignable[s - x]:
atteignable[s] = True
temoin[s] = x
# Trouver la plus grande somme atteignable inférieure ou égale à S/2
meilleur = max(s for s in range(S // 2 + 1) if atteignable[s])
# Reconstruction
paquet, s = [], meilleur
while s > 0:
paquet.append(temoin[s])
s -= temoin[s]
return (paquet, meilleur, S - meilleur)
Pour , la somme totale est (cible ). L'algorithme renvoie le paquet [13, 5] (somme ) contre les éléments restants [8, 4, 6] (somme ), réalisant un équilibre parfait. (c) Complexité temporelle : , mémoire : . La complexité est polynomiale par rapport à la valeur de , mais exponentielle par rapport à son nombre de bits. C'est un algorithme pseudo-polynomial : très rapide pour des valeurs de sommes modérées, mais inefficace si les entiers contiennent un très grand nombre de chiffres.
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.