Vous êtes sur la page 1sur 7

Programmation dynamique

1. Principe gé né ral

Quelquefois, en essayant de ré soudre un probl è me de taille n par l’approche descendante (Diviser pour R é soudre), on s'aper ç oit que la dé composition gé n è re plusieurs sous probl è mes identiques. Si on r é sout chaque sous exemplaire s é par é ment sans tenir compte de cette duplication on obtient un algorithme trè s inefficace. Par contre, si on prend la pré caution de r é soudre chaque sous exemplaire diffé rent une seule fois (en sauvegardant, par exemple, les r é sultats dé jà calcul é s) on obtient un algorithme performant.

Idé e de base :

Eviter de calculer deux fois la mê me chose, normalement en utilisant une table de r é sultats dé j à calcul é s, remplie au fur et à mesure qu'on r é sout les sous probl è mes.

Remarques C'est une m é thode ascendante : On commence d'habitude par les sous probl è mes les plus petits et on remonte vers les sous probl è mes de plus en plus difficiles. La programmation dynamique est souvent employé e pour r é soudre des problè mes d'optimisation satisfaisant le principe d'optimalit é : "Dans une s é quence optimale (de dé cisions ou de choix), chaque sous­sé quence doit aussi ê tre optimale". Un exemple de ce type de probl è me est le plus court chemin entre deux sommets d’un graphe.

2. Applications

Exemple 1:

Calcul de C n

p

Il existe une d é composition connue pour le calcul de C n p :

C n p = C n­1 p­1 + C n­1 p

C 0 0 = C n 0 = C n n = 1

a) On peut donner un algorithme r é cursif (c’est l’approche descendante : Diviser pour R é soudre) utilisant la dé finition de C n p .

Fonction C_rec (n,p) Si (n=p) ou (p=0):

retourner(1)

Sinon

retourner(C_rec(n­1,p­1) + C_rec(n­1,p))

Fsi

Mais cette d é composition va gé né rer un nombre important de sous problè mes identiques. Par exemple pour calculer C 8 5 l’arbre des appels r é cursifs est :

5 C 8 C 7 4 C 7 5 5 C 6 C 6 3
5
C
8
C 7 4
C 7 5
5
C 6
C 6 3
C 6 4
C 6 4
C 5 2
C 5 3
C 5 3
C 5 4
C 5 3
C 5 4
C 5 4

C 5

5

On remarque qu’il existe beaucoup de sous exemplaires qui se r é pè tent. Ceci influence n é gativement la complexité de l’algorithme qui est en (C n p ).

b) On peut aussi faire le calcul par programmation dynamique.(triangle de Pascal)

 

0

1

2

3

4

0

1

1

1

1

2

1

2

1

2 1 2 1 (remplissage de la table)

(remplissage de la table)

3

1

3

3

1

4

1

4

6

4

1

Le calcul se fait ligne par ligne et de gauche à droite, c­a­d que les sous exemplaires les plus simples sont calculé s en premiers et les r é sultats, que l’on sauvegarde dans la table, servent à calculer les exemplaires plus grands.

Fonction C_Dyn (n,p) var

Mat[0

n,0

p]

Pour i=0,n :

Pour j=0,Min(i,p) :

Si i=j ou j=0 :

Mat[i,j] := 1

Sinon

Mat[i,j] := Mat[i­1,j­1] + Mat[i,j]

Fp

Fsi

Fp

retourner(Mat[n,p])

Cet algorithme est en O(np).

Exemple 2: La suite de fibonacci

La dé finition de cette suite est donné e par la dé composition :

f 0 = 1 , f 1 = 1 et

f n = f n­1 + f n­2

pour n > 1

L’approche descendante (Diviser pour Ré soudre) donne l’algorithme suivant:

Fib_Rec(n:Entier) : Entier;

Si n<=1 :

Fib_Rec := 1

Sinon

Fib_Rec := Fib_Rec(n­1) + Fib_Rec(n­2)

Fsi

Comme dans l’exemple pr é c é dent, cet algorithme a un co û t exponentiel car l’arbre des appels r é cursifs gé n é ré contient beaucoup d’appels identiques.

L’approche par Programmation Dynamique suggè re de commencer par les sous­problè mes les plus petits (Fib(0) et Fib(1)) est de calculer les sous­problè mes plus complexes (Fib(2), Fib(3),

Fib(4),

Dans ce probl è me, les ré sultats interm é diaires né cessaires au calcul d’un sous­probl è me donné (Fib(i)) sont les deux sous­problè mes pr é c é dents (Fib(i­1) et Fib(i­2) car Fib(i)=Fib(i­1) + Fib(i­2)), d’o ù l’algorithme suivant:

Fib(n)) en gardant la trace des r é sultats interm é diaires né cessaires au calcul.

Fib­Dyn(n:Entier) : Entier;

var

j := 0;

i,j,k : Entier; i := 1;

Pour k=1,n :

j := i+j;

i := j­i

Fp; Fib_Dyn := j Cet algorithme est en o(n).

Exemple 3: Sé rie mondiale

A et B disputent une s é rie de matchs (au maximum 2n­1). L'é quipe gagnante est celle qui remporte n victoires. La probabilit é que A remporte une victoire, lors d’un match, est : q1 La probabilit é que B remporte une victoire est : q2 = 1­q1 Il n’y a pas de match nul.

On dé finit P(i, j) comme la probabilit é que A remporte la s é rie, sachant qu'elle doit encore gagner ‘i’ victoires alors qu’il reste ‘j’ victoires à B pour gagner.

On a ainsi :

P(0, j) = 1 ( A a dé j à gagné la s é rie et j > 0) P(i, 0) = 0 ( A a dé jà perdu la s é rie et i > 0) P(0, 0) indé fini

P(i, j) = q1*P(i­1, j) + q2*P(i, j­1)

i, j > 0

Algorithme r é cursif :

P(i, j) :

Si i = 0 et j > 0 :

 

P := 1

Sinon

 

Si i > 0 et j = 0 :

P := 0

Sinon

Si i > 0 et j > 0 :

P := q1*P(i­1,j) + q2*P(i, j­1)

Fsi

Fsi

Fsi

T(k) = temps d’exé cution de P(i, j) avec k = i+j

Equation de r é currence :

Solution :

donc T(k) est en O(2 k ) ou encore en O(2 i+j ) P(n, n) prend un temps dans l’ordre de O(4 n ) (car 2 2n = 4 n )

T(k) = 2T(k­1) + b

T(k) = C 1 2 k + C 2

Programmation dynamique

Utilisation d'une table remplie diagonale par diagonale:

0

1

2

3

4

 

1

1

1

1

 
  1/2 1/4 1/8 1/16 3/4 1/2 5/16 3/16 7/8 11/16 1/2 11/32 15/16 13/16 21/32
  1/2 1/4 1/8 1/16 3/4 1/2 5/16 3/16 7/8 11/16 1/2 11/32 15/16 13/16 21/32
  1/2 1/4 1/8 1/16 3/4 1/2 5/16 3/16 7/8 11/16 1/2 11/32 15/16 13/16 21/32
1/2 1/4 1/8 1/16

1/2

1/4

1/8

1/16

3/4 1/2 5/16 3/16
3/4 1/2 5/16 3/16

3/4

1/2

5/16

3/16

7/8 11/16 1/2 11/32

7/8

11/16

1/2

11/32

15/16

13/16

21/32

1/2

0 1

1 0

2 0

3 0

4 0

L’algorithme pour remplir la table jusqu’à la position P[i,j] :

Pour S = 1, i+j P[0, S] := 1 P[S, 0] := 0 Pour k=1, S­1 P[k, S­k] := q 1 P[k­1, S­k] + q 2 P[k, S­k­1] Finpour Finpour

Le temps d’ex é cution est en O(n 2 ) pour le calcul de P(n,n).

Exemple 4: Les plus courts chemins

Il s’agit de trouver les plus courts chemins entre chaque pair de sommets d’un graphe valu é

(Algorithme de Floyd).

C’est un probl è me d’optimisation qui vé rifie le principe d’optimalit é : Si le plus courts chemin (chemin optimal) entre deux sommets A et B passe par un sommet interm é diaire C, alors les portions du chemin entre A et C et entre C et B doivent forcé ment ê tre optimales.

Dans un graphe form é par n sommets, l’algorithme consiste à calculer les plus courts chemins entre chaque pair de sommets en utilisant comme sommets interm é diaires, dans l’ordre et de

faç on successives les sommets 1, 2, 3

A l’é tat initial aucun sommet interm é diaire n’est utilis é , les plus courts chemins sont donné s

D0[i,j]=+dé signera l’inexistence

directement par la matrice des poids des arcs D0[1 d’un arc entre les sommets i et j.

n.

n,1

n].

A l’é tape 1 les nouveaux chemins sont calcul é s par :

D 1 [i,j] = Min (D 0 [i,j] , D 0 [i,1] + D 0 [1,j])

A l’é tape k les nouveaux chemins sont calcul é s en prenant en considé ration tous les sommets

entre 1 et k :

D k [i,j] = Min (D k­1 [i,j] , D k­1 [i,k] + D k­1 [k,j])

Apr è s l’ é tape n, la matrice D n contiendra les longueurs des plus courts chemins entre chaque couple de sommets (i,j).

Exemple 5: Multiplication cha îné e de matrices

Sachant que la multiplication de matrices est associative :

M 1 (M 2 M 3 ) = (M 1 M 2 ) M 3 et sachant que pour multiplier une matrice de p lignes et q colonnes M 1 (p,q) par une autre

matrice de q lignes et r colonnes M 2 (q,r) il faut p*q*r multiplications é lé mentaires, le probl è me est de trouver le nombre minimal de multiplications é l é mentaires né cessaire pour

multiplier une s é rie de n matrices : M 1 M 2 M 3

M n . Appelant ce nombre m(1,n).

Avec cette dé finition, m(i,j) dé signera le nombre minimal de multiplications é l é mentaires

n é cessaires pour faire le produit de matrices suivant : M i * M i+1 * M i+2 toujours é gal à 0.

* M j et m(i,i) sera

n] de sorte

que les dimensions d’une matrice M i soient donn é es par D[i­1] (nb de lignes) et D[i] (nb de colonnes).

Supposons que les dimensions des matrices M soient stocké es dans un vecteur D[0

On pourra alors é crire que m(i,i+1) = D[i­1]*D[i]*D[i+1]. C’est le nombre de multiplications

é l é mentaires n é cessaire au produit : M i M i+1

C’est un probl è me d’optimisation vé rifiant le principe d’optimalit é :

« Si pour faire le produit de n matrices avec un nombre minimal d’opé rations é lé mentaires on dé coupe le produit des n matrices en deux sous­produits au niveau de la i ième matrice :

(M 1 * M 2 *

alors chacun des deux sous­produits doit aussi ê tre optimal :

Le sous­produit P1 : (M 1 * M 2 *

é l é mentaires), le r é sultat est une matrice X de dimensions : D[0] x D[i].

Le sous­produit P2 : (M i+1 * M i+2 *

opé rations é l é mentaires), le r é sultat est une matrice Y de dimensions : D[i] x D[n]. Le produit final : X * Y n é cessitera alors D[0]*D[i]*D[n] multiplications é l é mentaires. »

M n ) doit aussi ê tre calcul é de faç on optimal (soit m(i+1,n)

M i ) doit ê tre calculé de faç on optimal (soit m(1,i) opé ration

M i ) * (M i+1 * M i+2 *

M

n )

Donc si on dé coupe le produit initial au niveau de la i ième matrice, on pourra é crire :

m(1,n) = m(1,i) + m(i+1,n) + D[0]*D[i]*D[n]

En procé dant par dé composition r é cursive pour calculer m(1,n) les sous­produits P1 et P2 on aboutira à un algorithme r é cursif (du type Diviser pour Ré soudre) trè s inefficace à cause du nombre é levé de sous probl è mes identiques gé né r é s par la d é composition.

L’algorithme r é cursif est :

fonction m(i,j:entier) : entier; var

k, x : entier; Si i=j : retourner(0) Sinon

x := + Pour k:=i , j­1:

x := min { x , D[i­1]*D[k]*D[j] + m(i,k) + m(k+1,j) }

Fsi

c­a­d :

m(1,n)=Min

Fp

Retourner(x)

m(1,1)+m(2,n)+D[0]*D[1]*D[n]

m(1,2)+m(3,n)+D[0]*D[2]*D[n]

m(1,k)+m(k+1,n)+D[0]*D[k]*D[n]

m(1,n­1)+m(n,n)+D[0]*D[n­1]*D[n]

pour: M 1 (M 2 M 3 pour: (M 1 M 2 )(M 3

)

M

M

n

n

)

pour: (M 1

M

k

pour: (M 1 M 2

)(M k+1

M

M

n­1 )M n

n

)

En appliquant la programmation dynamique on proc é dera de fa çon ascendante pour é viter de

calculer plusieurs fois le m ê me sous­probl è me, en sauvegardant les r é sultats calculé s dans

une table m[1

n,1

n]

qu’on remplit au fur et à mesure qu’on progresse dans la r é solution.

Le remplissage de la table se fera en diagonal à l’aide de l’algorithme suivant :

Pour i:=1,n m[i,i] = 0

Fp;

/* la 1ere diagonale */ /* car il n’y a pas de produit de matrice */

Pour i:=1,n­1 m[i,i+1] = D[i­1]*D[i]*D[i+1]

Fp;

/* la 2e diagonale */ /* Pour le produit : M i * M i+1 */

Pour s:=2,n­1 Pour i:=1,n­s m(i,i+s) =

Fp

Fp Retourner( m[1,n] )

i

/* les autres diagonales */

min { m(i,k) + m(k+1,i+s) + D[i­1]*D[k]*D[i+s] } k i+s­1

i

j m[1,n] diagonale 2 diagonale 1
j
m[1,n]
diagonale 2
diagonale 1