Vous êtes sur la page 1sur 4

NOM : Prénom : Classe :

Activité algorithmes gloutons


On considère un ensemble d’activités, chacune possédant une date de début et une date de fin. Pour des
raisons logistiques, on ne peut pas programmer des activités se déroulant en même temps.

La question est la suivante : quel est le nombre maximal d’activités que l’on va pouvoir planifier ?

Formalisation :
• L’ensemble de n activités peut être modélisé par un n -uplet de couples S = ((b 1 , e 1 ), (b 2 , e 2 ), · · · , (b n , e n )), où
b i représente la date de début de l’activité i et e i sa date de fin.
• On suppose que ∀i , 1 ⩽ i ⩽ n, b i < e i et que l’activité i se déroule pendant l’intervalle [b i ; e i [.
• Deux activités i et j sont dites compatibles si b i ⩾ e j ou alors b j ⩾ e i . On peut dans ce cas les programmer
toutes les deux.
On cherche alors un sous-ensemble d’activités compatibles dont le cardinal est le plus grand possible.

Exercice 1 : Tri par durée

Une première méthode consiste à prendre les activités par ordre croissant de leur durée. C’est bien un méthode
gloutonne puisqu’on peut en effet raisonnablement penser que planifier d’abord les activités les plus courtes
laissera plus de temps pour les autres.

Cela donne :
• Trier les activités par ordre croissant de leur durée.
• Initialiser la liste C des activités choisies avec l’ensemble vide.
• Parcourir dans l’ordre la liste S des activités, et rajouter l’activité courante à C si elle n’est pas incompatible
avec celles déjà présentes dans C .
Implémentation en Python :

def choix_duree(S):
S.sort(key = lambda x : (x[1] - x[0]))
C = []
for x in S:
compatible = True
for y in C:
if not ((y[0] >= x[1]) or (x[0] >= y[1])):
compatible = False
if compatible:
C.append(x)
return C

Remarques :
• Le tri des activités selon leur durée a été effectué en utilisant sort, procédure native du langage Python
permettant de trier des listes.
• Il faut spécifier un critère de tri (ou un clé de triage) car il n’y a pas de relation d’ordre sur des couples de
nombres. En effet, un couple de nombre peut représenter les coordonnées d’un point dans un plan muni
d’un repère et que voudrait dire qu’un point est plus petit qu’un autre ?
• Pour spécifier le critère de tri, on a passé une fonction lambda au paramètre key. Il s’agit d’une fonction
anonyme, c’est-à-dire une fonction sans nom, que l’on ne souhaite pas réutiliser et que l’on définit donc
à la volée quand le besoin s’en fait sentir.
• Ici, à une activité x cette fonction associe x[1] − x[0], qui est bien sa durée puisque x[1] est la date de fin
de x et x[0] sa date de début.
1. Ajouter des commentaires sur le programme Python permettant de faire le lien avec l’algorithme écrit
en langage naturel.
2. On considère la liste d’activités suivante :
activites = [(1, 4), (0, 6), (3, 5), (12, 13), (8, 11), (8, 12),(2, 13), (6, 10), (5,
,→ 9), (3, 8), (5, 7), (13, 16),(15, 17), (16, 19)]

(a) Pour plus de facilité, on peut représenter cette liste d’activités comme ci-dessous où chaque activité
est représentée par un segment dont les extrémités représente le début et la fin de l’activité :

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

(b) Surligner les activités qui seront sélectionnées avec l’algorithme précédent.
(Si lors du tri, plusieurs activités ont la même durée, la première apparaissant dans la liste non triée
lors de l’appel sera aussi la première une fois la liste triée).
(c) Donner alors dans la liste des activités sélectionnées dans l’ordre de leur sélection.

3. On considère à présent la liste d’activités suivantes :


activites = [(1,6), (5,7), (6,10)]

(a) Donner la liste des activités sélectionnées avec la méthode.

(b) La méthode donne-t-elle la solution optimale ? Justifier.

Exercice 2 : Tri par date de début


Une autre approche est de considérer les activités par ordre croissant de leur date de début.
1. Expliquer en quoi cette méthode est gloutonne.

2. Voici un algorithme de résolution :


• Trier les activités par ordre croissant de leur date de début.
• Initialiser la liste C des activités choisies avec l’ensemble vide.
• Parcourir dans l’ordre la liste S des activités, et rajouter l’activité courante à C si elle n’est pas
incompatible avec celles déjà présentes dans C .
(a) Implémenter cette algorithme en python (il suffit de changer la clé de triage de l’exercice précédent)
def choix_debut(S):

return C

(b) Surligner les activités qui seront sélectionnées avec l’algorithme précédent.
(Si lors du tri, plusieurs activités ont la même durée, la première apparaissant dans la liste non triée
lors de l’appel sera aussi la première une fois la liste triée).

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

(c) Donner alors dans la liste des activités sélectionnées dans l’ordre de leur sélection.

3. Proposer un contre-exemple pour prouver que cette méthode n’est pas optimale.

Exercice 3 : Tri par nombre d’incompatibilités


Une autre approche est de prendre les activités par ordre croissant de leurs incompatibilités. Procéder ainsi
permet de privilégier les activités qui « gênent » le moins, et donc avoir moins de contrainte pour planifier les
autres.

Avant de pouvoir trier la liste des activités par ordre croissant de leurs incompatibilités, il faut connaître ce
nombre d’incompatibilités pour chaque activité.
1. Compléter la fonction ajoute_incomp qui permet de remplacer chaque couple (date de début, date de
fin) d’une activité par un triplet (date de début, date de fin, nombre d’incompatibilités).
def ajoute_incomp(S):
P = []
for x in S:
i = 0
for y in S:
if x != y and not ( or ):
i = i + 1
z = ( , , )
P.append(z)
return P
2. Implémenter ensuite la méthode gloutonne.
def choix_incomp(S):
S = ajoute_incomp(S)

return C

3. Proposer un contre-exemple pour prouver que cette méthode n’est pas optimale.

Exercice 4
Proposer une dernière méthode gloutonne en justifiant le fait que ce soit bien une méthode gloutonne.

Vous aimerez peut-être aussi