12 ProgrammationDynamique
12 ProgrammationDynamique
12 ProgrammationDynamique
Nicolas Delestre
1 Introduction
2 Programmation dynamique
4 Conclusion
Combinaison 1 / 4
Exercice
Écrire une fonction cnp, qui pour deux entiers positifs n et p (p ≤ n),
retourne le nombre de combinaisons de p éléments parmi n.
Pour rappel :
(
n p 1 si p = 0 ou n = p
= Cn = p p−1
p Cn−1 + Cn−1
Solution
fonction cnp (n,p : naturel) : NaturelNonNul
bprécondition(s) n≥p
debut
si p=0 ou n=p alors
retourner 1
sinon
retourner cnp(n-1,p)+cnp(n-1,p-1)
finsi
fin
Prog. Dyn. v1.3 3 / 29
Introduction
Combinaison 2 / 4
Code C
1 #include<stdlib.h>
2 #include<stdio.h>
3
4 unsigned int combinaison(unsigned int n,unsigned int p) {
5 if ((p==0) || (n==p))
6 return 1;
7 else
8 return combinaison(n−1,p)+combinaison(n−1,p−1);
9 }
10
11 int main(int argc , char∗∗ argv) {
12 unsigned int a,b;
13 if (argc==3) {
14 a = atoi(argv [1]) ;
15 b = atoi(argv [2]) ;
16 if (a>=b)
17 printf (”%d\n”,combinaison(a,b));
18 }
19 return EXIT SUCCESS;
20 }
Prog. Dyn. v1.3 4 / 29
Introduction
Combinaison 3 / 4
Temps d’exécution
Combinaison 4 / 4
Arbre des appels
Programmation dynamique 1 / 6
Première définition
Paradigme de conception qu’il est possible de voir comme une
Deuxième définition
La programmation dynamique est une technique algorithmique pour
Programmation dynamique 2 / 6
Historique
Principe invité en 1940 par Richard Bellman
Pour la petite histoire, Bellman a choisi le terme programmation
dynamique dans un souci de communication : son supérieur ne
supportait ni le mot recherche ni celui de mathématique .
Alors il lui a semblé que les termes programmation [(au sens de
la planification)] et dynamique donnaient une apparence qui
plairait à son supérieur
Programmation dynamique 3 / 6
0 1 2 3 4 5
debut 0 1
pour i ←0 à n faire 1 1 1
pour j ←0 à min(i,p) faire 2 1 2 1
si i=j ou i=0 ou j=0 alors i 3 1 3 3 1
b[i,j] ← 1 4 1 4 6 4
sinon 5 1 5 10 10
b[i,j] ← b[i-1,j-1]+b[i-1,j]
finsi
finpour
finpour
retourner b[n,p]
fin
Programmation dynamique 4 / 6
Programmation dynamique 5 / 6
Code C
1 #include<stdlib.h>
2 #include<stdio.h>
3
4 unsigned int combinaison(unsigned int n,unsigned int p) {
5 int i , j ;
6 unsigned int b[n+1];
7 b [0] = 1;
8 for ( i =1;i<=n;i++) {
9 b[ i ] = 1;
10 for ( j=i−1;j>0;j−−)
11 b[ j ] = b[j ] + b[j−1];
12 }
13 return b[p ];
14 }
15
16 int main(int argc , char∗∗ argv) {
17 unsigned int a,b;
18 if (argc==3) {
19 a = atoi(argv [1]) ;
20 b = atoi(argv [2]) ;
21 if (a>=b)
22 printf (”%d\n”,combinaison(a,b));
23 }
24 return EXIT SUCCESS;
25 }
Programmation dynamique 6 / 6
Temps d’exécution
Présentation du problème
Soit n objets i d’un certain poids wi et d’une certaine valeur vi
Soit un sac à dos permettant de stocker au maximum des objets
dont la somme des poids est W
Quels objets mettre dans le sac de façon à maximiser la valeur de
l’ensemble ?
Signature de la fonction
fonction resoudreSacADos (tailleDuSac, nbObjets : NaturelNonNul ;
valeurs, poids : Tableau[1..MAX] de Naturel) :
Ensemble<NaturelNonNul>
bprécondition(s) nbObjets ≤ MAX
Exemple [Reb05]
Données du problème :
Taille du sac : 11
Caractéristiques des objets :
objets 1 2 3 4 5
valeurs 1 6 18 22 28
poids 1 2 5 6 7
Solution : {3,4} avec la valeur 40
On suppose posséder :
fonction ensembleNaturels (borneInf, borneSup) : Ensemble<Naturel>
fonction somme (indice : Ensemble<Naturel>, valeurs : Tableau[1..MAX] de Naturel)
: Naturel
procédure obtenirSupprimerUnElement (E/S ens : Ensemble<Naturel>, S el : Naturel)
O(2n )
Prog. Dyn. v1.3 17 / 29
Exemple : Problème du sac à dos
Temps d’exécution
2 2 0 1 6 7 7 7 7 7 7 7 7 7
3 5 0 1 6 7 7 18 19 24 25 25 25 25
4 6 0 1 6 7 7 18 22 24 28 29 29 40
5 7 0 1 6 7 7 18 22 28 29 34 35 40
Cas n°1 : 5 > 3 Cas n°2 : 5 < 7
V3,3 ← V2,3 j – wi = 7 – 5 = 2, on compare donc :
V2,2 + v3 = 24 et V2,7 = 7 donc V3,7 ← 24
2 2 0 1 6 7 7 7 7 7 7 7 7 7
3 5 0 1 6 7 7 18 19 24 25 25 25 25
4 6 0 1 6 7 7 18 22 24 28 29 29 40
5 7 0 1 6 7 7 18 22 28 29 34 35 40
objets retenus = {}
2 2 0 1 6 7 7 7 7 7 7 7 7 7
3 5 0 1 6 7 7 18 19 24 25 25 25 25
4 6 0 1 6 7 7 18 22 24 28 29 29 40
5 7 0 1 6 7 7 18 22 28 29 34 35 40
objets retenus = {4}
2 2 0 1 6 7 7 7 7 7 7 7 7 7
3 5 0 1 6 7 7 18 19 24 25 25 25 25
4 6 0 1 6 7 7 18 22 24 28 29 29 40
5 7 0 1 6 7 7 18 22 28 29 34 35 40
objets retenus = {4,3}
Algorithme
fonction toutesLesValeursPossibles (tailleDuSac, nbObjets : NaturelNonNul ; valeurs, poids : Tableau[1..MAX OBJETS] de
Naturel) : Tableau[0..MAX OBJETS][0..TAILLE MAX SAC] de Naturel
bprécondition(s) nbObjets ≤ MAX OBJETS et tailleDuSac≤TAILLE MAX SAC
Déclaration v : Tableau[0..MAX OBJETS][0..TAILLE MAX SAC] de Naturel
i,j : Naturel
debut
pour i ←0 à nbObjets faire
v[i,0] ← 0
finpour
pour j ←0 à tailleDuSac faire
v[0,j] ← 0
finpour
pour i ←0 à nbObjets faire
pour j ←1 à tailleDuSac faire
si poids[i]≤j alors
v[i,j] ← max(v[i-1,j],valeurs[i]+v[i-1,j-poids[i]])
sinon
v[i,j] ← v[i-1,j]
finsi
finpour
finpour
retourner v
fin
Algorithme
fonction rechercherObjetsARetenir (tailleDuSac, nbObjets : NaturelNonNul ;
v : Tableau[0..MAX OBJETS][0..TAILLE MAX SAC] de Naturel ;
poids : Tableau[1..MAX OBJETS] de Naturel ) : Ensemble<NaturelNonNul>
bprécondition(s) nbObjets ≤ MAX OBJETS et tailleDuSac≤TAILLE MAX SAC
Algorithme
fonction resoudreSacADos (tailleDuSac, nbObjets : NaturelNonNul ;
valeurs, poids : Tableau[1..MAX OBJETS] de Naturel) : Ensemble<NaturelNonNul>
bprécondition(s) nbObjets ≤ MAX OBJETS et tailleDuSac≤TAILLE MAX SAC
debut
retourner rechercherObjetsARetenir(tailleDuSac,
nbObjets,
toutesLesValeursPossibles(tailleDuSac, nbObjets, valeurs, poids),
poids)
fin
Temps d’exécution
Conclusion 1 / 3
Conclusion 2 / 3
Conclusion 3 / 3
Remarques
Martelli a démontré en 1976 que tout algorithme de
Références I