Cours d’Algorithmique Programmation dynamique : Problème du sac à dos. Négociant en sardines au port de Marseille. Problème de la plus longue sous-chaîne commune. Problème du plus court chemin. 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Présentation générale Les grandes lignes du cours Trier et chercher, recherche textuelle Listes et arbres Le back-track Arbres équilibrés Récursivité et induction sur la structure Divide and conquer Minimax, alpha-beta Dérécursion Divers problèmes particuliers. Logique de Hoare Programmation dynamique Complexité et calculabilité 23 novembre 2006 Cours d'algorithmique 6 - Intranet Cours d'algorithmique
Nous explicitons le TEMPS qui sera linéaire, bi-dimensionnel, . . . Dynamic Programming ----------------------------------------------------------------- En français : Programmation dynamique ! Abréviation classique : DP Notion introduite par Richard Bellman en 1957. Principe : Nous explicitons le TEMPS qui sera linéaire, bi-dimensionnel, . . . 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- Introduction à la problématique. Considérons à nouveau la fonction Fibonacci : Le programme récursif est exponentiel en temps ! C’est dû aux répétitions de calculs ! fib ( n ) = n si n = 0 ou n = 1, fib ( n-2 ) + fib ( n-1 ) sinon. { 4 2 3 1 1 2 23 novembre 2006 Cours d'algorithmique 6 - Intranet 1
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- Principe de la programmation dynamique : Dites à quel moment vous ferez quel calcul ? Respectons le temps : fib ( t ) = t si t = 0 ou t = 1, fib ( t-2 ) + fib ( t-1 ) sinon. { 1 2 3 4 5 6 t fib 1 1 2 3 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- Principe de la programmation dynamique : Dites à quel moment vous ferez quel calcul ? Respectons le temps : Nous avons une complexité en temps linéaire ! ! ! fib ( t ) = t si t = 0 ou t = 1, fib ( t-2 ) + fib ( t-1 ) sinon. { 1 2 3 4 5 6 t fib 1 1 2 3 5 8 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- Quelle fonction de temps ? C’est quoi ? Une fonction qui dit, en termes de l’état du problème, à quel moment il va être résolu ! Exemples : fib ( t ) au temps « t », prog( x , y ) au temps « 2 *x + y -5 ». N’importe laquelle pour peu que nous ne répétions pas les calculs Ce n’est pas interdit, mais fortement déconseillé ! et que la fonction soit compatible avec les dépendances. 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Le respect des dépendances est obligatoire ! Dynamic Programming ----------------------------------------------------------------- Dépendances entre problèmes : On parle aussi de « flot de données ou de contrôle». Le calcul « B » dépend du calcul « A » s’il faut que « A » soit calculé avant « B » ! Soit, parce que « A » a besoin de données produites par « B » --- flot de données ! Soit, parce qu’il faut respecter un ordre (par exemple imprimer « A » avant « B »). Soit, parce que « A » conditionne « B » ( si A alors B ) --- flot de contrôle ! Le respect des dépendances est obligatoire ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- En fait, les dépendances comportent une notion de temporalité sous la forme de : AVANT --- APRES D’ABORD --- ENSUITE La fonction de temps « f » dit de manière plus précise : QUAND La contrainte sur « f » dit que : dès que « A » doit être avant « B » pour des raisons de dépendances, alors f ( A ) < f ( B ) « f » est alors dite « compatible avec les dépendances ». 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Dynamic Programming ----------------------------------------------------------------- L’arbre de dépendances de Fibonacci : Sa projection sur un axe de temps : t 4 4 Compatibilité ! 3 3 2 2 2 1 1 1 1 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Problème du « sac à dos » ! Ingrédients : 1 sac à dos de capacité « C » (par exemple en kilos), n objets de O , … , O de poids strictement positifs respectifs p et de bénéfices strictement positifs respectifs b . Recette : Trouvez, sans dépasser la capacité, l’ensemble d’objets qui maximise le bénéfice. 1 n i i 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Trouvez l’ensemble « I » inclus dans { 1 , … , n } tel que : P ( I ) = S p £ C B ( I ) = S b = max ( B ( J ) ) A priori, il faut se comparer à un grand nombre d’autres ensembles candidats à être optimal. i i e I i i e I J { 1 , … , n } et P ( J ) £ C v 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Correct, mais … Toutes les tailles possibles pour les sous-ensembles. {int max_benefice = 0 ; pour k allant de 1 à n faire pour chaque ensemble I, de taille k et sous-ensemble de { 1 , ... , n } faire si ( P ( I ) <= C ) max_benefice = max ( B ( I ) , max_benefice ) ; } Tous les sous-ensembles de cette taille … Retenez le bénéfice s’il est meilleur et que la contrainte sur la capacité est respectée. Seule ombre au tableau : le nombre des ensembles considérés est en Q ( 2^n ). 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Solution Divide and Conquer ? ? ? Mais oui ! ! ! Considérez les ensembles qui contiennent l’objet O et ceux qui ne le contiennent pas ! Soit « i » l’indice de l’objet que nous allons considérer, soit « R » la capacité résiduelle, soit « B » le bénéfice des objets pris jusque-là. Etat initial. I = 1 , R = C , B = 0 MAX O est pris ! O n’est pas pris ! 1 1 I = 2 , R = C - p , B = b I = 2 , R = C , B = 0 1 1 23 novembre 2006 Cours d'algorithmique 6 - Intranet Optimum local : B_avec Optimum local : B_sans
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- int D&C_sac ( int objet , int residuelle , int benefice ) {if ( objet > n ) return( benefice ) ; else {int memoire ; memoire = D&C_sac ( objet + 1 , residuelle , benefice ) ; if ( p[ objet ] > residuelle ) return( memoire ) ; return( max( D&C_sac( objet + 1 , residuelle – p[ objet ] , benefice + b[ objet ] ) , memoire ) ) ; } } 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Malheureusement, nous répétons des calculs ! Considérons p[ 1 ] = 1 , p[ 2 ] = 2 , p[ 3 ] = 3 et b[ 1 ] = 2 , b[ 2 ] = 4 , b[ 3 ] = 6 . Si nous sélectionnons 1 et 2 mais pas 3 , l’appel suivant sera D&C_sac ( 4 , C – 3 , 6 ). Si nous ne sélectionnons ni 1 , ni 2 , mais 3 , l’appel suivant sera 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- Organisons notre emploi du temps ! Au temps « t », nous nous occupons de O . Nous avons donc déjà considéré O , … , O . Avec une capacité résiduelle « R », la meilleure solution sur les « t » premiers objets est obtenue par : Opt ( t – 1 , R ) si p > R ! Opt ( t , R ) = max ( Opt ( t – 1 , R ) , b + Opt ( t - 1 , R – p ) ) t 1 t-1 { t t t Nous respectons l’écoulement du temps ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- C … Opt ( t-1 , R ) Opt ( t , R ) R Si l’objet n’est pas trop lourd ! … R – p[ t ] La fonction de temps est compatible avec les dépendances ! ! ! Opt ( t-1 , R – p[ t ] ) t-1 t n Sans objets, il n’y a aucun bénéfice. 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Sac à dos --- Knapsack ----------------------------------------------------------------- {for ( R = 0 ; R <= C ; R++ ) Opt[ 0 , R ] = 0 ; for ( t = 1 ; t <= n ; t++ ) for ( R = 0 ; R <= C ; R++ ) if ( p[ t ] > R ) Opt[ t , R ] = Opt[ t-1 , R ] ; else Opt[ t , R ] = max( b[ t ] + Opt[ t-1 , R–p[ t ] , Opt[ t-1 , R ] ) ; } 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Marine marchande ----------------------------------------------------------------- L’énoncé : Vous êtes acheteur au port de Marseille, « n » bateaux vont arriver et vous connaissez cette valeur, la qualité de la marchandise des différents bateaux « Q( i ) » varie de 1 à 1000, de manière aléatoire uniforme, et vous savez la juger, vous achetez une et une seule cargaison ! Laquelle ? 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Marine marchande ----------------------------------------------------------------- A l’arrivée du premier bateau : Vous achetez ? Vous attendez mieux ? OUI Achat du premier ? OUI NON – Achat du second NON En fait, nous achetons si la qualité du bateau courant est meilleure que la qualité moyenne espérée des bateaux qui vont venir ! etc, etc ... 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Marine marchande ----------------------------------------------------------------- A l’arrivée du bateau « i » : Nous achetons si Q( i ) est supérieure à E ( i+1 ) où E ( i+1 ) est la qualité moyenne des bateaux i+1 à n et nous en déduisons E( i ) ! Donc, avec une probabilité de ( 1000 – E( i+1 ) ) / 1000 nous achetons le bateau « i » dont la qualité moyenne vaut ( 1000 + E( i+1 ) ) / 2 . E ( i ) = ( 1000 – E( i+1 ) ) / 1000 * ( 1000 + E( i+ 1 ) ) / 2 + ( 1 - ( 1000 – E( i+1 ) ) / 1000 ) * E( i+1 ) = ( 1000^2 + E^2( i+1 ) ) / 2000 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Marine marchande ----------------------------------------------------------------- Ce qui nous donne : E( n ) = 500 E( n-1 ) = ½ * 750 + ½ * 500 = 625 E( n-2 ) = ( 1000 – 625 ) / 1000 * ( 1000 + 625 ) / 2 + 625 / 1000 * 625 / 2 = 695 n-10 n-9 n-8 n-7 n-6 n-5 n-4 n-3 n-2 n-1 n 879 871 861 850 836 820 775 741 695 625 500 L’axe de temps ! x E( x ) Pour tout bateau i , i < n : Nous achetons si Q( i ) >= E( i+1 ) ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- En français : Plus longue sous-chaîne commune ! On obtient une sous-chaîne en supprimant des caractères d’une chaîne. A B C D E F G B A C D D B E F Une sous-chaîne : A B Une autre sous-chaîne : B D E La sous-chaîne la plus longue : A C D E F 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- Le programme récursif s’arrête, CAR : e , si u = e ou v = e , a . LCSS ( u’ , v’ ) , si u = a . u’ et v = a . v’ , LCSS ( u , v ) = maxstr ( LCSS ( u , v’ ) , LCSS ( u’ , v ) ) si u = a . u’ , v = b . v’ et a <> b. { C’est fini dès que u ou v est réduite à la chaîne vide ! A chaque appel récursif, l’une au moins des chaînes raccourcit ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) LCSS est donc calculé pour les suffixes de u et v . v e LCSS ( a . u’ , a . v’ ) = a . LCSS ( u’ , v’ ) w a.w LCSS( e , ? ) w e e e LCSS( ? , e ) e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
maxstr ( LCSS ( u , v’ ) , LCSS ( u’ , v) ) Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) LCSS est donc calculé pour les suffixes de u et v . v e LCSS( e , ? ) LCSS ( a . u’ , b . v’ ) = maxstr ( LCSS ( u , v’ ) , LCSS ( u’ , v) ) e e e LCSS( ? , e ) e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) LCSS est donc calculé pour les suffixes de u et v . Deuxième axe de temps ! v e Premier axe de temps ! LCSS( e , ? ) Les calculs sont indépendants, car ils sont portés par le premier axe ! ! ! e e e LCSS( ? , e ) e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Colonne par colonne, depuis le bas ! Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) LCSS est donc calculé pour les suffixes de u et v . v e Projection ! Deuxième axe de temps ! De gauche à droite, de bas en haut ! LCSS( e , ? ) Projection ! Premier axe de temps ! . e e e Colonne par colonne, depuis le bas ! LCSS( ? , e ) e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Ligne par ligne, de gauche à droite ! Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) LCSS est donc calculé pour les suffixes de u et v . Projection ! Premier v e Ou alors . . . Deuxième axe de temps ! De bas en haut, de gauche à droite ! . LCSS( e , ? ) Deuxième Projection ! Premier axe de temps ! e e e Ligne par ligne, de gauche à droite ! LCSS( ? , e ) e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- suffixe( v ) Temps multi-dimensionnel, ici bi-dimensionnel. v Minutes Deuxième axe de temps ! Heure ( u+1 , v+1 ) Heures Premier axe de temps ! Heure ( u , v ) e e u suffixe( u ) 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Longest Common Sub-String ----------------------------------------------------------------- {T[ e , ? ] = e ; T[ ? , e ] = e ; pour x suffixe de u , suivant de e jusqua u pour y suffixe de v , suivant de e jusqua v si ( tete( x ) == tete( y ) ) T[ x , y ] = tete( x ) . T[ reste( x ) , reste( y ) ] ; sinon T[ x , y ] = maxstr( T[ x , reste( y ) ] , T[ reste( x ) , y ] ) ; } 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Il s’agit d’aller d’une ville de départ vers une ville d’arrivée, par le plus court chemin, dans un réseau de villes avec routes en sens unique, à distances connues et sans cycles (retour au point de départ). 9 B D 41 11 15 Les plus courts chemins ! A F 37 13 37 C E 12 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Notations : Désignons par V( x ) l’ensemble des voisines d’une ville x , Soit d( x , y ) la distance entre deux villes voisines, Soit f( x ) le plus court chemin pour aller de x à F . f ( x ) = min d ( x , y ) + f ( y ) et f( F ) = 0 y e V( x ) 9 B D f( F ) = 0 f( D ) = 11 + f( F ) f( E ) = 37 + f( F ) f( B ) = min{ 9 + f( D ) , 15 + f( E ) } f( C ) = min{ 37 + f( D ) , 12 + f( E ) } f( A ) = min{ 41 + f( B ) , 13 + f( C ) } 41 11 15 A F 37 13 37 C E 12 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Nous résolvons ces contraintes par substitution : Mais aussi : f( F ) = 0 f( D ) = 11 f( E ) = 37 f( B ) = 20 f( C ) = 48 f( A ) = 61 f( A ) = 61 = 41 + f( B ) = 41 + 9 + f( D ) = 41 + 9 + 11 f( A ) = 61 = 13 + f( C ) = 13 + 37 + f( D ) = 13 + 37 + 11 9 B D 41 11 15 A F 37 13 37 C E 12 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Principe de la résolution par programmation dynamique : Nous allons supposer que les plus courts chemins sont connus pour un sous-ensemble des villes. Ce seront des « voisines » de la ville d’arrivée. Pour les autres villes, nous ne connaissons qu’un majorant de la longueur du plus court chemin ! 20 11 9 B D 41 11 15 +inf A F 37 13 37 Majorant du plus court chemin ! C E Plus court chemin connu ! 48 12 37 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Parmi les villes non définitives, nous choisissons celle qui est à la plus petite distance. Cette distance est en fait exacte, et la ville passe dans le camp de droite ! 20 11 9 B D 41 11 15 +inf A F 37 13 37 Majorant du plus court chemin ! C E Plus court chemin connu ! 48 12 37 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Parmi les villes non définitives, nous choisissons celle qui est à la plus petite distance. Cette distance est en fait exacte, et la ville passe dans le camp de droite ! Les villes qui la précèdent, et non définitives, sont mises à jour par rapport à leur plus court chemin. 20 11 9 B D min( 20 + 41 , +inf ) = 61 41 11 15 A F 37 13 37 Majorant du plus court chemin ! C E Plus court chemin connu ! 48 12 37 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Exemple complet. +inf +inf 9 B D 41 15 11 +inf A 20 F 37 13 37 Majorant du plus court chemin ! C E 12 +inf +inf 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Exemple complet, c’est fini. 20 11 9 B D 41 15 11 53 A 20 F 37 13 37 C E 12 40 37 Plus court chemin connu ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- pour toutes les villes v : f[ v ] = +inf ; f[ arrivee ] = 0 ; V = « l’ensemble de toutes les villes » ; tantque V <> {} {choisir dans V la ville x tq f[ x ] soit minimale sur V /* Si ex aequo, on choisit une ville optimale au hasard */ V = V – { x } ; pour toute ville v dans V et tq d( v , x ) est finie f[ v ] = min( f[ v ] , d( v , x ) + f[ x ] ) ; } f[ x ] est la longueur du plus court chemin issu de x ! x est retirée de l’ensemble ! Les villes qui précèdent x sont mises à jour ! 23 novembre 2006 Cours d'algorithmique 6 - Intranet
Cours d'algorithmique 6 - Intranet Shortest Path Problem ----------------------------------------------------------------- Ceci est l’algorithme des plus courts chemins de Dijkstra. Sa complexité est de O ( n^2 ) où « n » est le nombre de villes. Plus précisément, il est en Q ( m ) où « m » est le nombre d’arcs. L’algorithme est optimal, car le problème ne peut pas être résolu avec une complexité plus petite. 23 novembre 2006 Cours d'algorithmique 6 - Intranet