Chapitre 1 Algorithmes gloutons Les algorithmes qui résolvent les problèmes d’optimisation parcourent en général une série d’étapes, au cours desquelles ils sont confrontés à un ensemble d’options. Pour de nombreux problèmes d’optimisation la programmation dynamique est une approche trop lourde pour déterminer les meilleures solutions ; d’autres algorithmes plus simples et efficaces y arriveront. Un algorithme glouton fait toujours le choix qui semble le meilleur sur le moment. Autrement dit, il fait un choix optimal localement, dans l’espoir que ce choix mènera à la solution optimale globalement. Les algorithmes gloutons n’aboutissent pas toujours à des solutions optimales, mais la méthode gloutonne est très puissante et fonctionne correctement pour des problèmes variés. 1.1 Location d’une voiture On considère le problème de la location d’une unique voiture. Des clients formulent un ensemble de demandes de location avec, pour chaque demande, le jour du début de la location et le jour de restitution du véhicule. Notre but ici est d’affecter le véhicule de manière à satisfaire le maximum de clients possible (et non pas de maximiser la somme des durées des locations). Nous disposons donc d’un ensemble E des demandes de location avec, pour chaque élément e de E, la date d(e) du début de la location et la date f (e) de la fin de cette location. Nous voulons obtenir un ensemble F maximal de demandes satisfaites. Cet ensemble F doit vérifier une unique contrainte : deux demandes ne doivent pas se chevaucher dans le temps, autrement dit une location doit se terminer avant que la suivante ne commence. Cette contrainte s’écrit mathématiquement : ∀e1 ∈ F, ∀e2 ∈ F, d(e1 ) ≤ d(e2 ) ⇒ f (e1 ) ≤ d(e2 ). Algorithme L OCATION DU NE VOITURE(E) Tri des éléments de E par date de fin croissante. On obtient donc une suite e1 , e2 , ..., en telle que f (e1 ) ≤ f (e2 ) ≤ ... ≤ f (en ). F[1] ← e1 j←1 pour i ← 1 à n faire si d(ei ) ≥ f (F[ j]) alors j ← j + 1 F[ j] ← e j renvoyer F Cet algorithme est glouton car à chaque étape il prend la location « la moins coûteuse » : celle qui finit le plus tôt parmi celles qui sont satisfiables. Preuve de l’optimalité de l’algorithme Soit F = {x1 , x2 , ..., x p } la solution obtenue par l’algorithme glouton, et soit G = {y1 , y2 , ..., yq }, q ≥ p, une solution optimale. Nous voulons montrer que F est optimal, et donc que q = p. 1 Nous supposons que les ensembles F et G sont classés par dates de fins de location croissantes. Si G ne contient pas F, il existe un entier k tel que : ∀i < k, xi = yi et xk 6= yk . Par construction de F, xk est une demande de location qui à la date de fin minimale et dont la date de début soit postérieure à la date de fin de xk−1 = yk−1 . Par conséquent, f (yk ) ≥ f (xk ). On peut alors remplacer G par G0 = {y1 , y2 , ..., yk−1 , xk , yk+1 , ..., yq } tout en satisfaisant la contrainte de non chevauchement des demandes. G0 est une autre solution optimale mais ayant strictement plus d’éléments en commun avec F que G. En répétant autant que faire se peut ce procédé, on obtient un ensemble H de même cardinalité que G et qui contient F. Cet ensemble H ne peut contenir d’autres éléments que ceux de F car ceux-ci, débutants après la fin de x p , auraient été ajoutés à F par l’algorithme glouton. Donc H = F, et F et G ont le même nombre d’éléments. Limites de l’algorithme Il est primordial, ici, que les demandes soit classées par dates de fin croissantes. Le tableau 1.1 présente trois demandes de location classées par dates de début croissantes pour lesquelles l’algorithme glouton présenté ci-dessus n’est pas optimal. Pour d’évidentes raisons de symétries, classer les demandes par dates de début décroissantes donne par contre un résultat optimal. d F e1 2 8 e2 3 4 e3 5 8 d F TAB . 1.1 – Demandes classées par dates de début croissantes. e1 3 6 e2 5 7 e3 3 5 TAB . 1.2 – Demandes classées par durées décroissantes. L’algorithme glouton ne donne pas l’optimum si notre but est de maximiser la durée totale de location du véhicule. Même si on classe les demandes de location par durées décroissantes, un algorithme glouton ne donnera pas une solution optimale, le tableau 1.2 présentant un contre-exemple. En fait, le problème de la maximisation de cette durée totale est NP-complet (cf. chapitre sur la NP-complétude) et on ne connaît pas d’algorithme de complexité polynomiale pour le résoudre. Si nous disposons de deux voitures et non plus d’une seule, l’algorithme précédent ne donne plus l’optimum. 1.2 Éléments de la stratégie gloutonne Un algorithme glouton détermine une solution après avoir effectué une série de choix. Pour chaque point de décision, le choix qui semble le meilleur à cet instant est retenu. Cette stratégie ne produit pas toujours une solution optimale. Il existe cependant deux caractéristiques qui indiquent qu’un problème se prête à une stratégie gloutonne : la propriété du choix glouton et une sous-structure optimale. 1.2.1 Propriété du choix glouton Propriété du choix glouton : on peut arriver à une solution globalement optimale en effectuant un choix localement optimal (ou choix glouton). En programmation dynamique on fait un choix à chaque étape, mais ce choix dépend de la solution de sous-problèmes, au contraire, dans un algorithme glouton, on fait le choix qui semble le meilleur sur le moment puis on résout les sous-problèmes qui surviennent une fois le choix fait. Une stratégie gloutonne progresse en général de manière descendante en faisant se succéder les choix gloutons pour ramener itérativement chaque instance du problème à une instance « plus petite ». 1.2.2 Sous-structure optimale Montrer qu’un choix glouton aboutit à un problème similaire mais « plus petit » ramène la démonstration de l’optimalité à prouver qu’une solution optimale doit faire apparaître une sous-structure optimale. Un problème fait apparaître une sous-structure optimale si une solution optimale contient la solution optimale de sous-problèmes. Cette propriété est un indice important de l’applicabilité de la programmation dynamique comme des algorithmes gloutons. Le sujet du TD 6 montre un exemple de problème qui peut être résolu par programmation dynamique mais pas par un algorithme glouton. 2 1.3 Fondements théoriques des méthodes gloutonnes La théorie des matroïdes ne couvre pas tous les cas d’applications de la méthode gloutonne, mais elle couvre de nombreux cas intéressants en pratique. 1.3.1 Matroïdes Définition 1 (Matroïde). Un matroïde est un couple M = (E, I) vérifiant les conditions suivantes : 1. E est un ensemble fini non vide. 2. I est une famille non vide de sous-ensembles de E, appelés sous-ensembles indépendants de E, telle que si H ∈ I et si F ⊂ H alors F ∈ I (on dit que I est héréditaire). Autrement dit, si I contient un sous-ensemble H de E, I contient tous les sous-ensembles de H. On remarque que l’ensemble vide est obligatoirement membre de I. 3. Si F et H sont deux éléments de I, avec |F| < |H|, alors il existe (au moins) un élément x ∈ H \ F tel que F ∪ {x} ∈ I (propriété d’échange). Un premier résultat sur les matroïdes : Théorème 1. Tous les sous-ensembles indépendants maximaux d’un matroïde ont la même taille. Ce résultat est une conséquence directe de la propriété d’échange : si un de ces ensembles, H, est strictement plus petit que les autres, la propriété d’échange nous garantit que I contient un sur-ensemble strict H 0 de H, ce qui contredit la maximalité de H. Définition 2 (Matroïde pondéré). Un matroïde M = (E, I) est dit pondéré si l’on dispose d’une fonction de pondération w qui affecte un poids strictement positif w(x) à chaque élément x de E. La fonction de pondération w s’étend aux sous-ensembles de E. Soit F un sous-ensemble quelconque de E : w(F) = ∑ w(x). x∈F 1.3.2 Algorithmes gloutons sur un matroïde pondéré De nombreux problèmes pour lesquels une approche gloutonne donne les solutions optimales peuvent être ramenés à une recherche d’un sous-ensemble indépendant de pondération maximale dans un matroïde pondéré. Autrement dit, on dispose d’un matroïde pondéré M = (E, I) et on souhaite trouver un ensemble indépendant F ∈ I pour lequel w(F) est maximisé. Un tel sous-ensemble indépendant et qui possède la plus grande pondération possible est appelé sous-ensemble optimal du matroïde. Comme la pondération est strictement positive par définition, un sous-ensemble optimal est toujours un sous-ensemble indépendant maximal. L’algorithme ci-dessous prend en entrée un matroïde pondéré M = (E, I) et sa fonction de pondération w et retourne un sous-ensemble optimal F. G LOUTON(M = (E, I), w) F ← 0/ Trier E par ordre de poids décroissant pour x ∈ E par ordre de poids décroissant faire si F ∪ {x} ∈ I alors F ← F ∪ {x} renvoyer F Cet algorithme est glouton parce qu’il considère les éléments de E par ordre de poids décroissant et qu’il ajoute immédiatement un élément x à F si F ∪ {x} est indépendant. Si E contient n éléments et si la vérification de l’indépendance de F ∪ {x} prend un temps O( f (n), l’algorithme tout entier s’exécute en O(n log n + n f (n)) —rappel : le tri d’un ensemble de n éléments coûte O(n log n). Le sous-ensemble F de E est indépendant par construction. Nous allons maintenant établir l’optimalité de F. Théorème 2 (Les matroïdes satisfont à la propriété du choix glouton). Soit M = (E, I) un matroïde pondéré de fonction de pondération w. Supposons que E soit trié par ordre de poids décroissant. Soit x le premier élément de E tel que {x} soit indépendant, s’il existe. Si x existe, il existe un sous-ensemble optimal F de E contenant x. 3 Si x n’existe pas, le seul élément de I est l’ensemble vide. Soit H un sous-ensemble optimal. On utilise H pour construire, au moyen de la propriété d’échange, un ensemble F maximal (de même cardinalité que H) et contenant x. Par construction, F et H ne diffèrent que d’un élément et il existe donc un élément y tel que : F = (H \{y})∪{x}. Par maximalité du poids de x, w(y) ≤ w(x), w(H) ≤ w(F) et F est optimal. Théorème 3. Soit M = (E, I) un matroïde quelconque. Si x est un élément de E tel que {x} n’est pas élément de I, alors x n’appartient à aucun sous-ensemble indépendant F de E. Autrement dit, un élément qui n’est pas utilisable immédiatement ne pourra jamais être utilisé : l’algorithme / G LOUTON ne fait donc pas d’erreur en ne considérant pas les éléments de E qui ne sont pas extension de 0. Théorème 4 (Les matroïdes satisfont la propriété de sous-structure optimale). Soit x le premier élément de E choisi par G LOUTON pour le matroïde pondéré M = (E, I). Le reste du problème —trouver un sous-ensemble indépendant contenant x et de poids maximal— se réduit à trouver un sous-ensemble indépendant et de poids maximal du matroïde pondéré M 0 = (E 0 , I 0 ), où : E 0 = {y ∈ E : {x, y} ∈ I}, I 0 = {H ⊂ E \ {x} : H ∪ {x} ∈ I}, et où la fonction de pondération de M 0 est celle de M restreinte à E 0 . Une solution de poids maximum sur M contenant x engendre une solution de poids maximum sur M 0 , et vice versa. Théorème 5 (Validité de l’algorithme glouton sur les matroïdes). Si M = (E, I) est un matroïde pondéré de fonction de pondération w, alors l’appel G LOUTON(M = (E, I), w) renvoie un sous-ensemble optimal. 4