Cours d’Algorithmique Parcours d’arbres. Induction sur la structure. Back-track. Minimax. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Présentation générale Les grandes lignes du cours Trier et chercher Listes et arbres Le back-track Arbres équilibrés Récursivité et induction sur la structure Divide and conquer Minimax Dérécursion NP-complétude Logique de Hoare Programmation dynamique Complexité et calculabilité 13 novembre 2006 Cours d'algorithmique 3 - Intranet Cours d'algorithmique
Cours d'algorithmique 3 - Intranet Fibonnacci et les arbres ----------------------------------------------------------------- ptr_arbre arbre_fibo (int n) {if ( n == 0 ) return( cree_feuille(0) ); else if ( n == 1 ) return( cree_feuille(1) ); return( cree_noeud( arbre_fibo(n-1), arbre_fibo(n-2) ) ) ; } 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Fibonnacci et les arbres ----------------------------------------------------------------- On observe que de nombreux calculs sont répétés ! arbre_fibo(5) 1 2 3 4 5 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Calcul de la somme des feuilles ----------------------------------------------------------------- int somme_arbre_fibo (ptr_arbre arbre) {if ( est_feuille(arbre) ) return( valeur_feuille(arbre) ); else return( somme_arbre_fibo(fils_gauche(arbre)) + somme_arbre_fibo(fils_droit(arbre)) ) ; } 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Calcul de la somme des feuilles ----------------------------------------------------------------- somme_arbre_fibo(5) = 5 5 1 2 3 4 5 3 2 2 1 1 1 1 1 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Calcul de la somme des feuilles ----------------------------------------------------------------- int somme_arbre_fibo (ptr_arbre arbre) {return( somme_acc(arbre , 0) ) ; } int somme_acc(ptr_arbre arbre , int accumule) {if ( est_feuille(arbre) ) return( accumule + valeur_feuille(arbre) ); else return( somme_acc(fils_droit(arbre) , somme_acc(fils_gauche(arbre) , accumule)) ) ; } 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Calcul de la somme des feuilles ----------------------------------------------------------------- accumule = 5 somme_arbre_fibo(5) = 5 1 2 3 4 5 accumule = 0 . . . 2 1 1 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Types de parcours ----------------------------------------------------------------- Ou encore : ... appel ( fg(a) ) / appel ( fd(a) ) ... Parcours préfixe res_fg = appel ( fg(a) ); res_fd = appel ( fd(a) ); return( ... res_fg ... res_fd ... ); 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Types de parcours ----------------------------------------------------------------- Ou encore : ... appel ( fd(a) ) / appel ( fg(a) ) ... Parcours suffixe ou postfixe res_fg = appel ( fd(a) ); res_fd = appel ( fg(a) ); return( ... res_fg ... res_fd ... ); 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Types de parcours ----------------------------------------------------------------- Parcours avec opérateur commutatif : l’ordre de parcours est sans importance ! ... oper_commute ( fg(a) , fd(a) ) ... ... oper_commute ( fd(a) , fg(a) ) ... Exemple : notre calcul de la somme de Fibonnacci. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Types de parcours avec étiquettes ----------------------------------------------------------------- Traitement de l’étiquette, soit avant, soit après, soit pendant ! Impression préfixe de l’arbre : * + 1 5 3 Impression postfixe de l’arbre : 1 5 + 3 * Impression infixe parenthésée : ( ( 1 + 5 ) * 3 ) * + 3 1 5 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Modification d’un arbre ----------------------------------------------------------------- En reconstruisant : Partie qui doit être reconstruite. 3 5 7 2 4 6 cree_noeud( fg(arbre) , cree_noeud( fg(fd(arbre)) , cree_noeud( cree_noeud(cree_feuille(4) , cree_feuille(6)) , fd(fd(fd(arbre))) ) ) ) ; 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Modification d’un arbre ----------------------------------------------------------------- En modifiant : Pointeur qui est modifié. 3 5 7 2 4 6 modifie_fg_noeud( fd(fd(arbre)) , cree_noeud( cree_feuille(4) , cree_feuille(6) ) ) ; 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Modification d’un arbre ----------------------------------------------------------------- Attention aux partages de structure avec modifications physiques ! sous_arbre = cree_noeud( cree_feuille(3) , cree_feuille(5) ); arbre = cree_noeud( sous_arbre , sous_arbre ); Pas pareil ! ! ! Représentation physique ! L’arbre logique ! ! ! Modification physique. Reconstruction d’arbre. 3 5 9 5 9 5 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Induction sur les structures ----------------------------------------------------------------- Induction simple sur les entiers naturels : On démontre la propriété pour 0, le premier entier naturel. On démontre que la propriété reste vraie pour i+1, si elle est vraie pour i . C’est le pas d’induction ! Donc, elle est vraie pour tout entier naturel. Induction totale sur les entiers naturels : On démontre que la propriété reste vraie pour i+1, si elle est vraie pour tous les entiers de 0 à i . C’est le pas d’induction ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Induction sur les listes ----------------------------------------------------------------- Induction sur les listes : On démontre la propriété pour la liste vide (ceci ne marche donc pas pour les listes circulaires !). On suppose la propriété vraie pour une liste de longueur i et on démontre qu’elle reste vraie pour la liste de longueur i+1 que l’on obtient en ajoutant un élément (bien choisi) en tête de liste. Variantes : éventuellement, une propriété n’est vraie que pour une liste de longueur au moins k : On démontre pour k et on démontre qu’elle reste vraie pour les listes plus longues. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Induction sur les arbres ----------------------------------------------------------------- Induction sur les arbres : On démontre la propriété pour une feuille quelconque. On suppose la propriété vraie pour les sous-arbres et on démontre qu’elle reste vraie pour l’arbre que l’on obtient en ajoutant un nœud père au-dessus des différents sous-arbres (bien choisis). Remarque : Le raisonnement de correction d’une fonction récursive sur arbres, listes, etc, se fait de la même manière : On démontre la correction du cas de base, on suppose les appels récursifs corrects et on démontre la correction de l’appel courant. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Correction d’une fonction récursive ----------------------------------------------------------------- La fonction ci-dessous calcule la profondeur d’un arbre ! La profondeur d’un nœud ou d’une feuille dans un arbre correspond au nombre de fois où l’on doit « descendre » vers un fils avant d’atteindre le nœud ou la feuille en question. La profondeur d’un arbre est la profondeur de la feuille la plus profonde. Donc, c'est correct ! ! ! int profond (ptr_arbre arbre) {if ( est_feuille(arbre) ) return( 0 ); else return( 1 + max( profond(fg(arbre)), profond(fd(arbre)) )); } Les appels récursifs sont corrects par hypothèse ! La plus grande des profondeurs. La profondeur de notre arbre ! ! ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Preuves par induction sur les arbres ----------------------------------------------------------------- Soient F ( A ) le nombre de feuilles et N ( A ) le nombre de nœuds internes d’un arbre A. Si A est binaire, alors : F ( A ) = N ( A ) + 1 Preuve : A est une feuille : F ( A ) = 1 = 0 + 1 = N ( A ) + 1 ! A est un nœud interne ayant les deux fils B et C : Hypothèse sur B : F ( B ) = N ( B ) + 1 ! Hypothèse sur C : F ( C ) = N ( C ) + 1 ! Donc, pour A : F ( A ) = F ( B ) + F ( C ) = N ( B ) + N ( C ) + 1 + 1 = N ( A ) + 1 ! ! ! N ( A ) 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Preuves par induction sur les arbres ----------------------------------------------------------------- On considère un arbre A qui vérifie pour tous ses nœuds internes la propriété qui dit que : soit, les deux sous-arbres sont de profondeur 0, soit, la profondeur du fils droit dépasse la profondeur du fils gauche d’une unité. Montrer que, pour une profondeur p fixée, l’arbre A est unique ! Preuve : p = 1 : L’arbre est unique, car les deux fils sont des feuilles ! p > 1 : Le fils droit C doit être de profondeur p-1 et le fils gauche B doit être de profondeur p-2 : Hypothèse sur B : B est unique ! Hypothèse sur C : C est unique ! Donc, A sera unique ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Preuves par induction sur les arbres ----------------------------------------------------------------- Les voici : Le prochain. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Un exemple archi-classique : Soient des variables v , … , v logiques, soit une formule F construite à partir de ces variables et des connectives et , ou et not , trouver un n-uplet de valeurs pour les v de façon à rendre vraie la formule F . Solution : Nous construisons la table de vérité ! C’est simple ! ! ! Mais, c’est très coûteux ! Jusqu’à 2 cas à inspecter ! ! ! Pouvons-nous faire mieux ? Probablement non ! ! ! 1 n i n 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- F = x et not(y) et z x y z F 0 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 1 0 0 0 1 0 1 1 1 1 0 1 1 1 Au pire, nous parcourons tout le tableau avant de constater qu’il n’y a aucune solution. Parfois, nous avons une idée où chercher la solution, mais ce n’est pas toujours le cas. Nous pouvons nous arrêter ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Sous-arbres en attente! L'alternative ! x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 Echec ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Sous-arbres en attente! Exploré sans succès ! x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Sous-arbres en attente! Exploré sans succès ! x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 Echec ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Sous-arbres en attente! Exploré sans succès ! L'alternative ! x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 Echec ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Explorés sans succès ! Un peu plus tard … Sous-arbre en attente! x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track ----------------------------------------------------------------- Chemin actuel. Explorés sans succès ! Sous-arbre en attente! Abandonné x 0 0 0 0 1 1 1 1 y 0 0 1 1 0 0 1 1 z 0 1 0 1 0 1 0 1 F 0 0 0 0 0 1 Succès ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Situation générale du Back-track ----------------------------------------------------------------- Dynamique : Chemin actuel. Sous-arbres en attente de traitement. Nous abandonnons les points de back-track ! Sous-arbres explorés sans succès. Succès ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
On dit que l'on back-track ! Situation générale du Back-track ----------------------------------------------------------------- Dynamique : Chemin actuel. Sous-arbres en attente de traitement. Dernière alternative ! ! ! Sous-arbres explorés sans succès. Echec ! On dit que l'on back-track ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Back-track, code générique ----------------------------------------------------------------- int back_track (un_type situation) {if ( decidable(situation) ) return( ca_vaut_tant(situation) ); else {dabord = back_track( premiere_alternative(situation) ); if ( suffisant(dabord) ) return( dabord ); /* les points de back-track sont abandonnés */ return( seconde_alternative(situation) ); } Comme pour Fibonnacci, nous parcourons un arbre imaginaire, qui ne sera jamais construit en tant que tel ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Back-track, toutes les solutions ----------------------------------------------------------------- set_un_type back_track_toutes (un_type situation) {if ( decidable(situation) ) if ( est_satisfaisant(situation) ) return( { situation } ); else return( {} ); return( back_track_toutes(premiere_alternative(situation)) union back_track_toutes(seconde_alternative(situation)) ); } 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Considérons un arbre dont : les feuilles valent Vrai ou Faux et les nœuds internes portent alternativement (depuis la racine vers les feuilles) les connectives et et ou. Par réduction nous calculons une valeur pour la racine : V et V V ou F V et F et F V V V 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Ces sous-arbres n’ont aucune incidence sur le résultat ! ! ! Minimax ----------------------------------------------------------------- Nous n’avons pas toujours besoin de parcourir tout l’arbre. V et V V ou V et ??? ??? Ces sous-arbres n’ont aucune incidence sur le résultat ! ! ! V V 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Règles pour le et : et et ? F donne donne V ? F ? Règles pour le ou : ou ou V ? donne donne V ? F ? On dit que l’on fait des coupes dans l’arbre. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Règles pour le min : min min ? donne donne 1 ? ? Règles pour le max : max max 1 ? donne donne 1 ? ? 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Définition générale d’un arbre Minimax : les feuilles ont des valeurs entières (ou réelles) et les nœuds internes portent alternativement (depuis la racine vers les feuilles) les connectives max et min. La valeur Minimax d’un arbre A vaut : si A est une feuille, alors la valeur de cette feuille, si A est un nœud interne de type max ayant des fils B et C, alors le maximum des valeurs minimax de B et C, si A est un nœud interne de type min ayant des fils B et C, alors le minimum des valeurs minimax de B et C. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- int mini_max (un_type situation , int max_ou_pas ) {if ( feuille(situation) ) return( valeur(situation) ); else if ( max_ou_pas ) return( max( minimax( genere_fils_gauche(situation) , not(max_ou_pas) ) , minimax( genere_fils_droit(situation) , not(max_ou_pas) ) ) ) ; return( min( minimax( genere_fils_gauche(situation) , not(max_ou_pas) ) ) ) ; } C’est assez logique ! Cas symétrique ! 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Les arbres Minimax servent dans les jeux : Je suis MAX et je veux maximiser mon bénéfice ! Mon adversaire est MIN et veut minimiser mon bénéfice ! 3 max 3 1 min min 5 3 7 1 Le chemin du minimax correspond à la fois à : - la meilleure attaque de MAX - et à la meilleure riposte de MIN. 13 novembre 2006 Cours d'algorithmique 3 - Intranet
Cours d'algorithmique 3 - Intranet Minimax ----------------------------------------------------------------- Minimax s’applique aux jeux : de somme nulle, déterministes, et d’information parfaite. Mon avantage est un inconvénient pour mon adversaire, et vice-versa. Pas d’élément de chance pour le résultat d’un lancer de dé. Tous voient toute l’information, contrairement aux jeux de carte où la main est cachée. Exemples : les échecs, les dames, le go, … 13 novembre 2006 Cours d'algorithmique 3 - Intranet