Introduction A La Programmation Dynamique
Introduction A La Programmation Dynamique
Introduction A La Programmation Dynamique
programmation
dynamique
Par yoch
www.openclassrooms.com
Sommaire
Sommaire ........................................................................................................................................... 2
Introduction à la programmation dynamique ...................................................................................... 3
Un exemple simple ............................................................................................................................................................ 3
Problème de partition de nombres .................................................................................................................................... 4
Problème ..................................................................................................................................................................................................................... 4
Méthode ...................................................................................................................................................................................................................... 4
Mise en oeuvre ............................................................................................................................................................................................................ 5
Récupérer la sous-liste ............................................................................................................................................................................................... 7
Problème du sac à dos ..................................................................................................................................................... 7
Problème ..................................................................................................................................................................................................................... 7
Analyse ........................................................................................................................................................................................................................ 8
Mise en oeuvre ............................................................................................................................................................................................................ 8
Récupérer la liste d'objets ........................................................................................................................................................................................... 9
Partager ..................................................................................................................................................................................................................... 10
www.openclassrooms.com
Sommaire 3/11
Par yoch
La « programmation dynamique » est un paradigme de programmation, c'est-à-dire une façon particulière d'appréhender un
problème algorithmique donné.
C'est une méthode utile pour obtenir une solution exacte à un problème algorithmique, là où une solution « classique » se trouve
être trop complexe, c'est-à-dire trop peu efficace. On parle alors d'optimisation combinatoire.
L'efficacité de cette méthode repose sur le principe d'optimalité énoncé par le mathématicien Richard Bellman : « toute politique
optimale est composée de sous-politiques optimales ».
Cette méthode paraît souvent inaccessible au débutant (d'ailleurs, si vous n'avez rien compris à ce qui précède, ne craignez rien :
c'est parfaitement normal ), aussi je vous propose de la découvrir avec moi sur quelques problèmes concrets.
Sommaire du tutoriel :
Un exemple simple
Problème de partition de nombres
Problème du sac à dos
Un exemple simple
Pour commencer, nous allons prendre un problème tiré d'ici :
Voici une pyramide de nombres. En partant du sommet, et en se dirigeant vers le bas à chaque étape, on doit réussir à maximiser
le total des nombres traversés. Sur l'image d'exemple, ce maximum est 23 (le chemin est indiqué en rouge).
Si l'on teste tous les chemins possibles, ça devient impraticable dès que la pyramide est un peu grande. En effet, pour une
pyramide de hauteur N, il y a 2N-1 chemins possibles. Nous allons donc très vite nous retrouver bloqués...
Mais heureusement, il existe une manière de procéder infiniment meilleure (et très intuitive, dans notre cas) :
Chaque case de notre pyramide (sauf le sommet) possède un ou deux parents (parent = case du dessus permettant d'y parvenir).
Les cases situées sur les arêtes (= cotés) n'ont qu'un parent, et les autres en ont deux, l'un à gauche et l'autre droite. A partir de
là, et sachant que l'on parcourt la pyramide de haut en bas, il suffit de déterminer pour chaque case de la pyramide quel est le
maximum possible, et nous trouvons alors facilement la réponse.
www.openclassrooms.com
Introduction à la programmation dynamique 4/11
Code : Autre
LIGNE 1 (sommet) :
- CASE 1 (3) : max = 3 (seule valeur possible)
LIGNE 2
- CASE 1 (7) : max = 7 + 3 = 10
- CASE 2 (4) : max = 4 + 3 = 7
LIGNE 3
- CASE 1 (2) : max = 10 + 2 = 12
- CASE 2 (4) : max = MAX(10+4, 7+4) = 10 + 4 = 14
- CASE 3 (6) : max = 6 + 7 = 13
LIGNE 4 :
- CASE 1 (8) : max = 12 + 8 = 20
- CASE 2 (5) : max = MAX(12+5, 14+5) = 14 + 5 = 19
- CASE 3 (9) : max = MAX(14+9, 13+9) = 14 + 9 = 23
- CASE 4 (3) : max = 13 + 3 = 16
Cette approche en informatique est appelée « programmation dynamique ». Elle se révèle extrêmement efficace pour résoudre
certains problèmes courants (souvent des problèmes de combinatoire). Nous allons maintenant voir comment résoudre certains
problèmes intéressants grâce à la programmation dynamique.
L'approche la plus « simple » serait d'essayer toutes les combinaisons et d'en retenir la meilleure. Néanmoins, après un petit
calcul, on s'aperçoit que cela n'est pas très réaliste. En effet, supposons que nous avons 100 pièces, il existe alors 2100
combinaisons possibles. Il faut donc obligatoirement trouver une meilleure solution.
Méthode
C'est là qu'intervient le concept de programmation dynamique. Pour connaître toutes les combinaisons possibles, il existe un
autre moyen : traiter le problème « à l'envers ».
Code : Autre
PIÈCES : 5, 9, 3, 8, 2, 5
Nous allons rechercher une sous-liste de pièces optimale dont la somme se rapprochera le plus possible de la moitié de la somme
de toutes les pièces. Raisonnons :
Code : Autre
www.openclassrooms.com
Introduction à la programmation dynamique 5/11
ÉTAPE 1. avec 5 :
- COMBINAISONS CONNUES : néant.
- PIÈCE À ÉVALUER : 5.
- NOUVELLES COMBINAISONS : 5.
ÉTAPE 2. avec 5 et 9 :
- COMBINAISONS CONNUES : 5.
- PIÈCE À ÉVALUER : 9.
- NOUVELLES COMBINAISONS : 9, 14 (9+5).
ÉTAPE 3. avec 5, 9 et 3 :
- COMBINAISONS CONNUES : 5, 9, 14.
- PIÈCE À ÉVALUER : 3.
- NOUVELLES COMBINAISONS : 3, 8 (3+5), 12 (3+9)...
ÉTAPE 4. avec 5, 9, 3 et 8 :
- COMBINAISONS CONNUES : 3, 5, 8, 9, 12, 14.
- PIÈCE À ÉVALUER : 8.
- NOUVELLES COMBINAISONS : 11 (3+8), 13 (5+8), 16 (8+8)...
En pratique, on peut connaître les assemblages possibles avec deux pièces à partir des assemblages possibles avec une pièce, et
ainsi de suite. C'est ce que l'on appelle une relation de récurrence : la solution du problème sur n instances est récurrente à la
solution du problème sur n-1 instances.
On constate que, pour travailler, le programme a besoin de connaître les données déjà trouvées. C'est le fondement même de la
programmation dynamique : on élimine les recalculs en mémorisant ce qui a déjà été calculé.
C'est ce qui fait l'efficacité de cette méthode, mais c'est aussi son point faible : la programmation dynamique requiert de la
mémoire et ne sera pas toujours envisageable à cause de cela.
Mise en oeuvre
Passons maintenant à l'implémentation de tout cela.
Nous allons devoir créer une matrice booléenne M de dimensions nombrePieces * (miSommeGlobale+1), que nous appellerons
M[i][j].
Dans le cas où sommeGlobale est paire, miSommeGlobale vaut sommeGlobale/2. Dans le cas inverse, on prendra
(sommeGlobale-1)/2.
Code : Autre
DEFINIT M[nombrePieces][miSommeGlobale+1]
www.openclassrooms.com
Introduction à la programmation dynamique 6/11
Code : Autre
M[0][0] = VRAI
POUR j=1 TANT QUE j < miSommeGlobale
SI piece[0] EGALE j
M[0][j] = VRAI
SINON
M[0][j] = FAUX
incrémente j
i\j 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
1re pièce V F F F F V F F F F F F F F F F F
Ensuite, nous allons remplir les autres lignes du tableau (ligne par ligne) en suivant la condition suivante :
Code : Autre
i\j 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16
1re pièce V F F F F V F F F F F F F F F F F
2 premières pièces V F F F F V F F F V F F F F V F F
3 premières pièces V F F V F V F F V V F F V F V F F
4 premières pièces V F F V F V F F V V F V V V V F V
Chaque ligne représente les combinaisons possibles avec les i premières pièces.
Dans ce cas précis, on s'arrête à la ligne 4 car la solution idéale a été trouvée.
Sinon, on continuera à remplir le tableau jusqu'à la dernière ligne, et nous connaîtrons de ce fait la solution optimale : la valeur
maximale de la dernière ligne du tableau représente l'une des deux sous-sommes optimales (la plus petite), l'autre sous-somme
optimale étant alors la somme globale moins cette valeur.
Code : Autre
www.openclassrooms.com
Introduction à la programmation dynamique 7/11
décrémente j
sousListe1 = j
sousListe2 = sommePieces - j
ecart = sommePieces-(j*2)
Eh bien en fait, si tu as gardé le tableau ci-dessus, je pense qu'il doit y avoir un moyen.
Récupérer la sous-liste
Nous allons récupérer la sous-liste obtenue en suivant le procédé à l'envers.
Analysons le tableau :
Algorithme
Code : Autre
Ce problème est un grand classique en algorithmique et il existe diverses méthodes pour le résoudre.
Je vais vous présenter ici la méthode dite par programmation dynamique.
Code : Autre
MAX CONTENANCE : 12
- OBJET : A| B| C| D| E| F| G| H
- POIDS : 2| 3| 5| 2| 4| 6| 3| 1
- VALUE : 5| 8| 14| 6| 13| 17| 10| 4
www.openclassrooms.com
Introduction à la programmation dynamique 8/11
Analyse
C'est là que la fameuse règle « toute politique optimale est composée de sous-politiques optimales » prend tout son sens. Nous
allons l'appliquer à nouveau et traiter le problème depuis le bas.
On a :
Code : Autre
Et ainsi de suite...
C'est vrai que la récurrence est ici moins évidente à trouver. Voici comment nous allons procéder.
Mise en oeuvre
www.openclassrooms.com
Introduction à la programmation dynamique 9/11
Nous allons créer une matrice d'entiers M de dimensions nombreObjets * (maxContenance+1), que nous appellerons M[i][j].
i\j 00 01 02 03 04 05 06 07 08 09 10 11 12
1er objet 0 0 5 5 5 5 5 5 5 5 5 5 5
Chaque case du tableau représente le bénéfice maximum possible pour les i premiers objets avec un poids j.
Ensuite, nous allons remplir les autres lignes du tableau (ligne par ligne) ainsi :
Code : Autre
SI poidsObjet[i] > j
M[i][j] = M[i-1][j]
SINON
M[i][j] = maximum ( M[i-1][j], M[i-1][j-
poidsObjet[i]] + valeurObjet[i] )
i\j 00 01 02 03 04 05 06 07 08 09 10 11 12
1er objet 0 0 5 5 5 5 5 5 5 5 5 5 5
2 premiers objets 0 0 5 8 8 13 13 13 13 13 13 13 13
3 premiers objets 0 0 5 8 8 14 14 19 22 22 27 27 27
4 premiers objets 0 0 6 8 11 14 14 20 22 25 28 28 33
5 premiers objets 0 0 6 8 13 14 19 21 24 27 28 33 35
6 premiers objets 0 0 6 8 13 14 19 21 24 27 30 33 36
7 premiers objets 0 0 6 10 13 16 19 23 24 29 31 34 37
8 premiers objets 0 4 6 10 14 17 20 23 27 29 33 35 38
Le plus grand bénéfice possible se trouve dans la dernière case du tableau (en bas à droite). Celui-ci est donc de 38.
Le poids nécessaire pour faire un tel bénéfice se retrouve en reculant horizontalement depuis la dernière case du tableau (en bas
à droite) tant que le bénéfice reste le même. Donc ici le poids nécessaire est 12 (car on ne peut pas reculer).
www.openclassrooms.com
Introduction à la programmation dynamique 10/11
Le principe est le même que plus haut. Tout d'abord, on récupère dans la dernière ligne le poids minimal nécessaire pour faire le
bénéfice optimal :
Code : Autre
Voilà, ce (court) tuto touche à sa fin. J'espère que vous avez bien compris et qu'il vous aura donné matière à réflexion.
Pour résumer :
Citation : candide
1°) La programmation dynamique est simplement le fait de construire un tableau dont chaque ligne se déduira d'une ou de
plusieurs lignes précédentes.
2°) La programmation dynamique a ses limites (la taille des instances du problème).
Cette approche permettra (sous certaines conditions) de résoudre nombre de problèmes « difficiles ».
Exemples de problèmes que l'on peut résoudre par programmation dynamique (en anglais) :
http://people.csail.mit.edu/bdean/6.046/dp/
Partager
www.openclassrooms.com