Académique Documents
Professionnel Documents
Culture Documents
Les algorithmes gloutons sont utilisés dans des problèmes d’optimisation. Un problème
d’optimisation consiste à déterminer le jeu de données d’entrée permettant de minimiser ou
maximiser une fonction objectif, tout en satisfaisant à une ou des fonctions contraintes (il existe des
problèmes avec ou sans contrainte).
On peut citer par exemple le problème du choix d’itinéraire dans un réseau routier : il faut
déterminer le trajet de sorte à minimiser le temps de parcours (ou la distance parcourue, ou la
consommation, ou autre…), tout en respectant un ensemble de contraintes : il faut circuler sur les
routes (on ne coupe pas à travers champs !) et respecter les sens de circulation.
Un algorithme glouton fait toujours le choix glouton : c’est le choix qui lui semble le meilleur
sur le moment, en espérant que cela conduira à la solution optimale. Les méthodes gloutonnes
sont bien plus simples car elles effectuent les choix sans se soucier de la suite de la résolution. Ces
méthodes sont donc adaptées si elles permettent à coup sû r d’atteindre la solution optimale
globale du problème.
Les conférences sont définies par leur heure de début et leur heure de fin. La conférence c i aura
pour heure de début d (ci ) et pour heure de fin f (c i) .
Nous supposerons que les conférences ont été triées dans l’ordre croissant de leurs dates de fin.
Si nous travaillons avec un ensemble C de n conférences, on a :
f (c 1)< f (c 2 )< …< f (c n−1)< f (cn )
Pour notre application : le premier choix glouton consiste à choisir la conférence qui termine le plus
tô t possible, préservant ainsi la disponibilité de la salle pour les conférences ultérieures.
Lorsqu’un choix de conférence a été fait, on procède de la même manière pour le choix suivant,
mais il y a la contrainte de compatibilité : il faut choisir une conférence compatible avec celles qui ont
déjà été choisies : on ne peut choisir qu’une conférence qui débute après la fin de la dernière
conférence choisie.
Q1. Exécutez à la main cette méthode en utilisant l’ensemble de conférences illustré sur la figure
donnée en page 2.
La solution à la main est :
[C1, C4, C5, C8]
1.4. Implémentation
On modélise l’ensemble C des conférences par une liste dont chaque élément modélise une
conférence. Chaque conférence est modélisée par une liste qui comporte la date de début, la date de
fin, et l’intitulé de la conférence. Cette liste est ordonnée par ordre croissant de la date de fin des
conférences. Ainsi, l’exemple représenté pourrait être modélisé par la liste :
L=[ [8,9,"C1"] , [8.45,10.3,"C2"] , [8.1,11.3,"C3"] , [11.15,11.45,"C4"] , [12,12.45,"C5"] , [11,13,"C6"] ,
[12.3,14,"C7"] , [16,17,"C8"] , [15,18,"C9"] ,[16.3,18.1,"C10"]]
Q2. Créer une fonction Choix_conférence(C) qui prend en argument une liste de conférences C, et
applique la méthode décrite précédemment. Le résultat est une liste de conférences mutuellement
compatibles, de longueur maximale.
def choix_conferences( C ) :
planning = [C[0]]
fin=C[0][1]
for i in range(1,len(C)):
if C[i][0] >= fin:
planning.append(C[i])
fin = C[i][1]
return planning
Q3. Tapez la ligne de code permettant d’utiliser la fonction choix conferences( ) pour déterminer la
liste des conférences retenues parmi les conférences listées dans L. Comparez le résultat avec celui
obtenu en Q1.
resultat = choix_conferences(L)
On retrouve bien le résultat [[8,9,"C1"], [11.15, 11.45,"C4"], [12,12.45,"C5"], [16,17,"C8"]] trouvé
à la main à la question Q1.
On observe que le résultat obtenu est bien un optimal. Cependant, il existe d’autres solutions,
toutes autant optimales, par exemple C2, C4, C7, C10 ou encore C1, C4, C5, C9.
Pour notre application : S={s1 , s 2 , … , s k } est le résultat de notre algorithme. On montre par
récurrence que pour tout j ≤ k , le sous-ensemble S j={s1 , s 2 ,… , s j } de S est un sous ensemble d’une
solution optimale :
- pour j=0, l’ensemble S j est un ensemble vide, et est donc un sous-ensemble d’une solution
optimale ;
- pour j > 0 : soit T une solution optimale telle que pour j< k , S j ⊂ T (T contient les activités
s1 , s 2 , … , s j ). On note b l’élément suivant s j dans T ;
- on a f ( s j +1 ) ≤ f (b) (en raison du choix glouton, on choisit l’activité qui finit les plus
tô t) ;
- les éléments de T sont tous compatibles, ainsi chaque élément succédant à b débute
après la fin de b et de s j+1 ,
Ainsi T −{ b } ∪ {s j +1 } est une solution optimale, de même cardinal que S, et elle contient
s1 , s 2 , … , s j+1.
S est donc une solution optimale. On a bien démontré que l’algorithme du choix d’activité est
correct, présente la propriété de sous-structure optimale, et que le choix glouton permet d’arriver à
une solution optimale globalement.
Q4. Ecrivez la fonction sac_a_dos(L, capacite) qui prend en arguments une liste L modélisant la
cueillette et la capacité du sac-à -dos, et appliquant la méthode décrite précédemment. Le résultat est
la liste des fruits contenus dans le sac-à -dos, correspondant au chargement de valeur maximale.
def sac_a_dos( L , capacite ):
masse_sac = 0
sac=[]
N = L.copy()
i=0
valeur = 0
while masse_sac < capacite and i < len(N):
fruit = N[i]
capacite_restante = capacite - masse_sac
if fruit[1] > capacite_restante :
fruit[1] = capacite_restante
sac.append(fruit)
valeur = valeur + fruit[1]*fruit[0]
masse_sac = masse_sac + fruit[1]
i=i+1
return sac
Q5. Tapez la ligne de code permettant d’utiliser la fonction sac_a_dos() pour déterminer les quantités
de fruits à choisir pour remplir le sac-à -dos, à partir de la liste cueillette. Exécutez votre programme
et vérifiez le résultat.
fruits_ramenes = sac_a_dos(cueillette,5)
L’objectif est toujours de placer dans le sac à dos le chargement de valeur maximale, de masse
totale inférieure à 5kg. Par contre, les éléments n’étant pas fractionnables, il est possible que les
choix successifs mènent à un chargement qui ne remplit pas complètement le sac à dos.
Q7. Le résultat obtenu est-il optimal ? Comparer avec la solution Pastèque, melon jaune. Quelle est la
solution dont la valeur est maximale ?
Le résultat obtenu est [[3, 1, 'melon de cavaillon'], [2.5, 2, 'melon jaune']].
Ce chargement a pour valeur 1*3+2*2.5=8€. Cette solution n'est pas optimale puisque la solution
[[2.5,2,"melon jaune"], [2,3,"pastèque"]] a une valeur de 2*2.5+3*2=11€
Q8. De la propriété du choix glouton et de la sous-structure optimale, laquelle n’est pas respectée
dans cette formulation du problème ? En quoi l’autre propriété l’est ?
Cette version du problème présente bien la propriété de sous-structure optimale:
- Si on considère le sous-ensemble Sk, constitué de k-1 éléments de la solution optimale S, l'ensemble
C des fruits disponibles est alors ô té des éléments de Sk, ce qui amène à l'ensemble appelé Ck.
- Ck est le sous problème, et la solution optimale pour ce sous problème fait partie de la solution
optimale du problème global.
En revanche, la propriété du choix glouton n'est pas respectée. On a bien vu que le choix glouton du fruit
de plus grande valeur massique nous a éloigné de la solution optimale {melon jaune, pastèque}.
Nous disposons d’une quantité illimitée de pièces ou billets pour chacune des valeurs de s.
Si on note x la valeur à rendre, on peut la représenter par le n-uplet K = (k1, k2, . . . , kn) tel que
n
x=∑ k i . si. Les ki représentent le nombre de pièces de valeur si. Par exemple, la valeur 63 sera
i=1
représentée par le n-uplet (0,0,0,1,0,1,0,1,1) car :
63 = (0 ∗ 500 + 0 ∗ 200 + 0 ∗ 100 + 1 ∗ 50 + 0 ∗ 20 + 1 ∗ 10 + 0 ∗ 5 + 1 ∗ 2 + 1 ∗ 1)
La solution optimale est celle qui permet de rendre la monnaie en utilisant un minimum de
n
pièces. On cherche donc à déterminer les valeurs des ki telles que la somme ∑ k i soit minimale.
i=1
S[i] > v :
Passer à la valeur suivante de S
Q10. Testez l’algorithme en complétant le tableau ci-dessous, décrivant l’évolution des variables
d’itération en itération pour une valeur à rendre de 14 €. Vous remarquerez que les itérations 1 à 4
ont été éludées. En effet pour ces itérations là , les variables n’évoluent pas.
2 [10,2]
8 2 2 2 [10,2,2]
Q11. Créer la fonction rendu_monnaie(valeur , systeme) qui prend en argument la valeur à rendre et la
liste systeme des valeurs du système monétaire utilisé, et appliquant la méthode décrite
précédemment. Le résultat est une liste des pièces et billets utilisés pour le rendu de monnaie.
def rendu_monnaie(valeur,systeme):
i=0
K=[0]*len(systeme)
a_rendre= []
while valeur >0 :
if valeur < systeme[i]:
i=i+1
else:
K[i]=K[i]+1
valeur=valeur-systeme[i]
a_rendre.append(systeme[i])
return a_rendre
Un algorithme glouton ne mène pas toujours à une solution optimale. C’est aussi vrai pour
l’algorithme de rendu de monnaie. Nous avons obtenu dans les questions précédentes une solution
optimale parce que le système monétaire utilisé était adapté. On dit que le système est canonique.
Pour d’autres systèmes monétaires, la méthode n’apporte pas une solution optimale.
Q13. Exécutez la fonction rendu_monnaie( ) pour déterminer les pièces à utiliser pour rendre 14 €
dans le système monétaire (9,7,3,1). Le résultat obtenu est-il optimal ?
S2=[9,7,3,1]
resultat=rendu_monnaie(14,S2)
[9, 3, 1, 1]
Il est difficile de définir un système canonique, par contre, il existe des méthodes permettant de
tester si un système existant est canonique.
De manière générale, il est difficile de déterminer si un algorithme glouton amènera à une
solution optimale pour un problème donné. Une théorie basée sur les « matroïdes » permet
d’identifier des problèmes pouvant être résolus de manière optimale par une méthode gloutonne,
mais certains problèmes non-identifiés par cette théorie sont toutefois adaptés à la résolution par un
algorithme glouton.
Q14. Comment mettre en forme les données pour appliquer la méthode gloutonne ainsi formulée ?
Les conférences doivent être ordonnées par ordre décroissant des dates de début.
def choix_conferences( C ) :
planning = [C[0]]
debut=C[0][0]
CPGE - Lycée de Bellevue Page 10 / 10 Informatique – Seq 7
for i in range(1,len(C)):
if C[i][1] <= debut:
planning = [C[i]] + planning
debut = C[i][0]
PCSI