Adloun

Algorithmes probabilistes, approximation, séparation et évaluation

Cours complet · informatique (MP2I/MPI), chapitre 25 · MP2I et MPI

Travailler ce chapitre sur Adloun Exercices corrigés de ce chapitre

25.1 Trois façons de renoncer

Le chapitre chap:exploration s'achevait sur un constat : le retour sur trace reste exponentiel, et sur certains problèmes personne ne connaît mieux. Le chapitre chap:decidabilite dira pourquoi. Entre les deux, celui-ci répond à la question pratique : que fait-on quand l'exact est hors de portée ?

Trois renoncements, et chacun garde quelque chose :

On renonce à…On garde…Nom
la certitude du résultatun temps bornéMonte-Carlo
un temps bornéla certitude du résultatLas Vegas
l'optimalitéune garantie sur l'écartapproximation
rien (on reste exact)un élagage plus fortséparation et évaluation

25.2 Algorithmes probabilistes

Définition 25.1Déterministe, Las Vegas, Monte-Carlo

Un algorithme déterministe produit toujours le même résultat en le même temps sur la même entrée. Un algorithme probabiliste consulte une source d'aléa. On en distingue deux familles, et le programme les nomme toutes deux :

  • Las Vegas : le résultat est toujours correct, le temps d'exécution est aléatoire ;
  • Monte-Carlo : le temps est borné, le résultat peut être faux avec une probabilité contrôlée.

Le programme borne l'exigence : « on s'en tient aux définitions et à des exemples choisis par le professeur ».

Exemple 25.2Las Vegas : les huit reines, revisitées

Le programme cite ce problème ici, après l'avoir cité au chapitre chap:exploration pour le retour sur trace. La version Las Vegas est brutale :


(* Renvoie un placement valide de n reines. Précondition : n >= 4.
   TOUJOURS correct ; temps aléatoire. *)
let rec reines_las_vegas n =
  let pos = Array.init n (fun i -> i) in
  melanger pos;                       (* une permutation au hasard *)
  if valide pos then pos else reines_las_vegas n

Une permutation garantit déjà qu'aucune reine ne partage sa ligne ni sa colonne : il ne reste à vérifier que les diagonales. Le résultat rendu est toujours valide ; c'est le nombre d'essais qui est aléatoire.

ImportantÀ quoi sert Las Vegas : construire ce qu'on ne sait pas fabriquer

Le programme donne la vraie motivation : « on mentionne l'intérêt d'une méthode Las Vegas pour construire un objet difficile à produire par une méthode déterministe (par exemple, construction d'un nombre premier de taille cryptographique) ».

Pour engendrer un nombre premier de bits, personne ne sait en construire un directement. On procède donc ainsi : tirer un entier impair au hasard, tester sa primalité, recommencer s'il est composé. Le théorème des nombres premiers assure qu'environ un entier sur est premier ; en ne tirant que des impairs, il en faut environ . C'est immédiat, et aucune méthode déterministe n'approche cette efficacité.

Le hasard n'est pas ici un pis-aller : c'est le seul procédé connu.

Exemple 25.3Un second Las Vegas : le -ième minimum, exemple cité par le programme

Le quickselect choisit un pivot au hasard et ne récurse que d'un côté :


(* k-ième plus petit élément de t (k à partir de 0).
   Précondition : 0 <= k < longueur. Espérance : Theta(n) ; pire cas : Theta(n²). *)
let rec selection t k =
  let pivot = t.(hasard (Array.length t)) in
  let inf = filtre (fun x -> x < pivot) t
  and egal = filtre (fun x -> x = pivot) t
  and sup = filtre (fun x -> x > pivot) t in
  if k < Array.length inf then selection inf k
  else if k < Array.length inf + Array.length egal then pivot
  else selection sup (k - Array.length inf - Array.length egal)

C'est encore un Las Vegas, et non un Monte-Carlo : le résultat est toujours le bon élément, seul le temps est aléatoire. Le programme cite ce problème sans le classer ; la définition donnée plus haut tranche.

Trier coûterait ; ici l'espérance est , car le pivot aléatoire élimine en moyenne la moitié du tableau. Le pire cas reste — mais il exige une suite de pivots systématiquement extrêmes, dont la probabilité décroît exponentiellement. Aucun adversaire ne peut la provoquer, puisqu'il ne connaît pas les tirages.

iRemarqueRabin-Karp était déjà de cette famille

Le chapitre chap:textes le notait : la recherche par empreintes est un Monte-Carlo — une égalité d'empreintes peut être une collision — rendu exact par une vérification caractère par caractère. C'est un schéma courant : on emploie un test rapide et faillible pour écarter la masse, puis un test lent et sûr sur le peu qui reste.

25.3 Algorithmes d'approximation

Définition 25.4Problème de décision, problème d'optimisation

Le programme demande ces définitions ici.

  • Un problème de décision appelle une réponse par oui ou non : « ce graphe est-il -coloriable ? »
  • Un problème d'optimisation demande la meilleure solution selon une fonction de coût : « quel est le plus petit nombre de couleurs ? »
  • Une instance est une donnée particulière du problème.
Définition 25.5Algorithme d'approximation

Pour un problème de minimisation, un algorithme est une -approximation si, sur toute instance, sa solution coûte au plus fois l'optimum. Le programme précise : « seule la notion d'algorithme d'approximation est au programme. L'étude de techniques générales d'approximation est hors programme. »

ImportantLa garantie porte sur toutes les instances

C'est ce qui distingue une approximation d'une heuristique. Une heuristique marche souvent bien, et personne ne sait dire à quel point elle peut échouer. Une -approximation est accompagnée d'une preuve valable sur toute entrée — c'est ce qui en fait un résultat, et non une observation.

Exemple 25.6La 2-approximation de la couverture des sommets

Construite et démontrée au chapitre chap:gloutons. On en rappelle l'argument, car il est le patron du genre : les arêtes qui déclenchent une prise forment un couplage ; toute couverture doit contenir au moins un sommet par arête de , donc ; l'algorithme prend sommets. D'où .

La structure de toute preuve d'approximation est là : trouver une minoration de l'optimum — ici — puis majorer la solution rendue par un multiple de cette minoration. On ne compare jamais à l'optimum lui-même, qu'on ne sait pas calculer.

Exemple 25.7MAX2SAT par la méthode probabiliste, exemple cité par le programme

Le programme suggère d'indiquer, « par exemple sur le problème MAX2SAT, que la méthode probabiliste peut fournir de bons algorithmes d'approximation ». MAX2SAT : étant donné une fnc à deux littéraux par clause, satisfaire le plus de clauses possible.

L'algorithme : tirer chaque variable à pile ou face, indépendamment.

L'analyse. Une clause à deux littéraux est fausse dans exactement un cas sur quatre — celui où ses deux littéraux sont faux. Chaque clause est donc satisfaite avec probabilité . Par linéarité de l'espérance, sur clauses :

Comme l'optimum ne peut dépasser , cet algorithme trivial est une -approximation en espérance. Et il ne regarde même pas la formule.

Ce que cet exemple enseigne : la linéarité de l'espérance ne demande aucune indépendance entre les clauses, alors qu'elles en partagent les variables. C'est ce qui rend l'argument si court — et c'est exactement ce que le programme appelle « la méthode probabiliste ».

25.4 Séparation et évaluation

Définition 25.8Branch and bound

Le retour sur trace élague quand une solution partielle est impossible. La séparation et évaluation élague plus tôt : quand une solution partielle est sans espoir, c'est-à-dire quand une borne montre qu'elle ne pourra pas battre la meilleure solution déjà trouvée.

Deux ingrédients :

  • la séparation : découper l'ensemble des solutions en sous-ensembles — c'est l'arbre de recherche du chapitre chap:exploration ;
  • l'évaluation : une borne sur le meilleur résultat atteignable dans une branche.

Le résultat reste exact : on n'élague que ce qu'on a prouvé inutile.

ImportantLa borne doit être optimiste, sinon l'algorithme devient faux

Pour un problème de maximisation, la borne doit majorer ce que la branche peut rapporter. Une borne trop basse couperait une branche contenant l'optimum — et l'algorithme rendrait un résultat faux, sans le signaler.

Il y a donc un arbitrage, et il est le cœur de la méthode :

Borne lâcherapide à calculer, élague peu
Borne serréecoûteuse à calculer, élague beaucoup

Une borne parfaite résoudrait le problème et ne servirait à rien.

Exemple 25.9Le sac à dos par séparation et évaluation

La borne classique vient de la relaxation continue — que le programme cite : « on peut évoquer sur des exemples quelques techniques d'évaluation comme les méthodes de relaxation ». On autorise à couper les objets, ce qui rend le problème facile : le glouton par rapport valeur/poids décroissant y est alors optimal.


(* Meilleure valeur atteignable en poursuivant depuis l'objet i avec la
   capacité c ; objets TRIÉS par rapport valeur/poids décroissant.
   Borne SUPÉRIEURE : on autorise à fractionner le dernier objet. *)
let borne p v i c =
  let reste = ref c and total = ref 0.0 and k = ref i in
  while !k < Array.length p && p.(!k) <= !reste do
    reste := !reste - p.(!k);
    total := !total +. float_of_int v.(!k);
    incr k
  done;
  if !k < Array.length p then                      (* la FRACTION du suivant *)
    total := !total +. float_of_int v.(!k)
                       *. float_of_int !reste /. float_of_int p.(!k);
  !total

(* Valeur maximale, exacte. On coupe dès que la borne ne bat pas le record. *)
let sac_bb p v n capacite =
  let record = ref 0 in
  let rec explorer i c acquis =
    if acquis > !record then record := acquis;
    if i < n && float_of_int acquis +. borne p v i c > float_of_int !record then begin
      if p.(i) <= c then explorer (i + 1) (c - p.(i)) (acquis + v.(i));   (* on prend *)
      explorer (i + 1) c acquis                                          (* on laisse *)
    end
  in
  explorer 0 capacite 0;
  !record

Pourquoi la relaxation donne bien une borne supérieure : toute solution entière est une solution fractionnaire particulière, donc l'optimum fractionnaire est au moins égal à l'optimum entier. La branche ne peut pas rapporter davantage.

ImportantTrois méthodes sur le même problème, et ce qu'elles échangent

Le sac à dos aura traversé quatre chapitres. Voici le bilan, et il résume tout le propos.

MéthodeChapitreCoûtRésultat
Retour sur tracechap:explorationexact
Programmation dynamiquechap:dynamique pseudo-poly.exact
Glouton par rapportchap:gloutonsaucune garantie
Séparation et évaluationici au pireexact, rapide en pratique

Aucune ligne ne domine les autres. Le choix dépend de — la programmation dynamique s'effondre si la capacité est grande —, de la taille de , et de ce qu'on accepte de perdre.

25.5 Ce qu'il faut retenir

ImportantQuatre manières de composer avec l'infaisable
  • Las Vegas : toujours juste, temps aléatoire. Son usage propre est de construire ce qu'on ne sait pas fabriquer — le nombre premier cryptographique.
  • Monte-Carlo : temps borné, réponse faillible. Souvent rendu exact par une vérification, comme Rabin-Karp.
  • Approximation : on renonce à l'optimum, on garde une garantie prouvée sur toute instance. Toute preuve d'approximation passe par une minoration de l'optimum.
  • Séparation et évaluation : exact, et élague par une borne qui doit être optimiste — sous peine de couper l'optimum en silence.

Et une remarque qui vaut pour les quatre : le hasard protège du pire cas. Un adversaire qui connaît votre algorithme peut construire son pire cas ; s'il ne connaît pas vos tirages, il ne le peut plus.

Continuer sur Adloun : animation, QCM, fiches, exercices