Docsity
Docsity

Prépare tes examens
Prépare tes examens

Étudies grâce aux nombreuses ressources disponibles sur Docsity


Obtiens des points à télécharger
Obtiens des points à télécharger

Gagnz des points en aidant d'autres étudiants ou achete-les avec un plan Premium


Guides et conseils
Guides et conseils


Notes sur l'initiation à l’algorithmique - 3° partie, Notes de Mathématiques pour l'informatique

Exercices d’informatique sur l'initiation à l’algorithmique - 3° partie. Les principaux thèmes abordés sont les suivants: Algorithme Glouton, Quelques algorithmes de tri,

Typologie: Notes

2013/2014

Téléchargé le 03/03/2014

Christophe
Christophe 🇫🇷

4.1

(104)

760 documents

1 / 35

Toggle sidebar

Cette page n'est pas visible dans l'aperçu

Ne manques pas les parties importantes!

bg1
5.8. ´
ETUDE DU PROBL `
EME DE PUISSANCE 71
En fait deux cas principaux se pr´esentent selon que le esultat du produit
de deux ´el´ements conserve la taille des ´el´ements initiaux ou prend pour taille la
somme des tailles de ces ´el´ements initiaux.
Si conservation de la taille, puissance1 est exponentiel, puissance3 est quadra-
tique.
Si il y a conservation de taille, tous les produits ont la eme complexit´e,
celle not´ee taille(x), du premier ´el´ement xpass´e en argument. Ainsi, la
complexit´e en temps dans le pire des cas de :
puissance1 est Θ(k·taille(x)).
En clair, cet algorithme est exponentiel puisque kest une fonction expo-
nentielle de la taille log(k) de k.
puissance3 est Θ(log (k)·taille(x)).
En clair, cet algorithme est quadratique puisque log(k) est la taille de k.
Voir exemples ci dessous.
Si somme des taille, puissance1 et puissance3 sont exponentiels.
Si la taille du produit est la somme des tailles des op´erandes, la complexit´e
en temps dans le pire des cas de :
puissance1 est Θ(k2·taille(x)).
En effet, l’algorithme ealise kproduits sur une op´erande droite de taille
taille(x) et une op´erande gauche de taille successivement ´egal `a 1, taille(x),
2.taille(x), . . .(k-1)taille(x). La somme fournit tr`es exactement (k(k+
1)/21)taille(x) que l’on approche selon k2taille(x).
puissance3 est Θ(k·taille(x)).
En effet, l’algorithme ealise log(k) carr´es sur une op´erande de taille suc-
cessivement ´egal `a 1 ·taille(x), 2 ·taille(x), 4 ·taille(x), . . .2l og(k)taille(x).
Sachant que P0ilog(k)2i= 2log(k)+1 1 = Θ(k), on en eduit que la
complexit´e en temps de l’algorithme est celle du dernier produit ex´ecut´e
c’est `a dire Θ(k·taille(x)).
Nous pr´esentons ici diff´erents types element et interpretons le esultat dans
le contexte de ce choix.
le type entierLong : augmentation de la taille
Un entier xest ici de taille log(x). Les deux algorithmes sont exponentiels.
eme en supposant qu’un produit sur des entiers de 8 bits se fasse en 109seconde,
le calcul de puissance1(10,10000000000000000000) ecessite (1020)2= 1040
op´erations ´el´ementaires c’est `a dire 1023 ann´ees de calculs, ce qui fait beaucoup.
Le second plus rapide ecessite tout de eme 1020 op´erations ´el´ementaires soit
100 ann´ees de calcul, ce qui n’est pas rien !
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23

Aperçu partiel du texte

Télécharge Notes sur l'initiation à l’algorithmique - 3° partie et plus Notes au format PDF de Mathématiques pour l'informatique sur Docsity uniquement!

5.8. ETUDE DU PROBL ´ EME DE PUISSANCE` 71

En fait deux cas principaux se pr´esentent selon que le r´esultat du produit de deux ´el´ements conserve la taille des ´el´ements initiaux ou prend pour taille la somme des tailles de ces ´el´ements initiaux.

Si conservation de la taille, puissance1 est exponentiel, puissance3 est quadra- tique. Si il y a conservation de taille, tous les produits ont la mˆeme complexit´e, celle not´ee taille(x), du premier ´el´ement x pass´e en argument. Ainsi, la complexit´e en temps dans le pire des cas de :

  • puissance1 est Θ(k · taille(x)). En clair, cet algorithme est exponentiel puisque k est une fonction expo- nentielle de la taille log(k) de k.
  • puissance3 est Θ(log (k) · taille(x)). En clair, cet algorithme est quadratique puisque log(k) est la taille de k. Voir exemples ci dessous.

Si somme des taille, puissance1 et puissance3 sont exponentiels. Si la taille du produit est la somme des tailles des op´erandes, la complexit´e en temps dans le pire des cas de :

  • puissance1 est Θ(k^2 · taille(x)). En effet, l’algorithme r´ealise k produits sur une op´erande droite de taille taille(x) et une op´erande gauche de taille successivement ´egal a 1, taille(x), 2.taille(x),.. .(k-1)taille(x). La somme fournit tres exactement (k(k + 1)/ 2 − 1)taille(x) que l’on approche selon k^2 taille(x).
  • puissance3 est Θ(k · taille(x)). En effet, l’algorithme r´ealise log(k) carr´es sur une op´erande de taille suc- cessivement ´egal `a 1 · taille(x), 2 · taille(x), 4 · taille(x),.. .2log(k)taille(x). Sachant que

0 ≤i≤log(k) 2

i (^) = 2log(k)+1 (^) − 1 = Θ(k), on en d´eduit que la complexit´e en temps de l’algorithme est celle du dernier produit ex´ecut´e c’est `a dire Θ(k · taille(x)).

Nous pr´esentons ici diff´erents types element et interpretons le r´esultat dans le contexte de ce choix.

le type entierLong : augmentation de la taille

Un entier x est ici de taille log(x). Les deux algorithmes sont exponentiels. Mˆeme en supposant qu’un produit sur des entiers de 8 bits se fasse en 10^9 seconde, le calcul de puissance1(10,10000000000000000000) n´ecessite (10^20 )^2 = 10^40 op´erations ´el´ementaires c’est `a dire 10^23 ann´ees de calculs, ce qui fait beaucoup. Le second plus rapide n´ecessite tout de mˆeme 10^20 op´erations ´el´ementaires soit 100 ann´ees de calcul, ce qui n’est pas rien!

72 CHAPITRE 5. TERMINAISON ET COMPLEXIT ES´

Le type int : conservation de la taille

Le type int est de taille constante, souvent 4 octets. Le produit est de com- plexit´e constante et ne modifie pas la taille des entiers multipli´es. En fait, l’analyse et th´eorique et pratique de la complexit´e n’a aucun sens puisque pour de tres tres petits entiers, on d´epasse la quantit´e maximale autoris´e : 1010 est d´eja sup´erieura 2^32 et donc n´ecessite plus de 4 octets.

Le type float : conservation de la taille

Le type float est de taille constante, 4 octets. Le produit est de complexit´e constante et ne modifie pas la taille des entiers multipli´es. Contrairement aux int, un float ´etant repr´esent´e grace notamment `a un exposant prenant 256 valeurs. On peut calculer la puissance d’un float selon un petit entier char. D’un point de vue pratique, le d´ebut ( ?) d’un comportement assymptotique peut ˆetre observ´e pour ces 256 valeurs.

Le type matrice carr´ee de r´eels : conservation de la taille

Si l’on considere une matrice n · n carr´ee de r´eels, ces derniers ´etant suppos´es de taille constante. Le produit clairement conserve la taille, toujours ´egalea n · n. L’algorithme puissance1 est de complexit´e exponentielle Θ(k · n^2 ). L’algorithme puissance3 est de complexit´e Θ(log(k) · n^2 ).

Remarque 12 Cette complexit´e peut ˆetre qualifi´ee de quadratique puisque la taille de l’entr´ee est log(k) + n^2. La complexit´e log(k) · n^2 est major´ee par le carr´e (log(k) + n^2 )^2. On peut atteindre cette complexit´e quadratique, il suffit de choisir un entier k de taille log(k) = n^2 , et obtenir une complexit´e log(k) · n^2 ´egale au carr´e (log(k) + n^2 )^2 de la taille de l’entr´ee (a la constante multiplicative 14 pres).

Exercice 36 Poursuivre l’´etude de complexit´e en consid´erant au choix :

  1. les autres algorithmes puissances puissance2, puissance4, puissance5, produit1, produit3.
  2. la complexit´e en espace.
  3. la complexit´e en moyenne, dans le meilleur des cas.
  4. en choisissant la puissance d´efinie par le produit modulo un entier n. Le produit modulo un entier n de deux entiers a et b est l’entier not´e a ·n b ´egal au reste du produit a · b par la division euclidienne par n. Exemple : 7 · 9 5 = 8.

Exercice 37 Evaluer la complexit´´ e en espace des diff´erents algorithmes dans chacune des deux nouvelles hypoth`eses.

74 CHAPITRE 5. TERMINAISON ET COMPLEXIT ES´

Chapitre 6

Algorithmes “Diviser Pour

r´egner”

L’approche “Diviser Pour R´egner” (Divide and Conquer) est une m´ethode qui permet de r´esoudre un probleme en fournissant un algorithme r´ecursif. Cette m´ethode n’offre naturellement aucune garantie : il n’existe pas de m´ethode (ou algorithme) permettanta partir d’un probleme d’obtenira coup sˆur une solution algorithmique. La structure g´en´erale d’un algorithme “Diviser Pour R´egner” A et permettant d’associer `a une entr´ee x une solution s comporte 3 parties :

  1. la d´ecomposition. Celle-ci consiste `a d´ecomposer l’entr´ee x en a nouvelles entr´ees x 1 ,... , xa.
  2. a appels r´ecursifs. Ceux-ci consistent a appliquer r´ecursivement la fonction A sur chacune des nouvelles entr´ees x,... , xa eta retourner les a solutions s 1 ,... , sa.
  3. la recomposition. Celle-ci consiste a recomposera partir des solutions par- tielles s 1 ,... , sa la solution s associ´ee `a x.

6.1 Un premier exemple : la multiplication de

deux entiers

Supposons que nous manipulions des entiers de tr`es grande taille (plusieurs centaines d’octets) et que nous souhaitions les multiplier :

Probl`eme ProduitEntiers Entr´ee : a, b : entier Sortie : a·b

La taille n d´esigne la taille max(log(a), log(b)) maximale des entiers a et b.

6.1. UN PREMIER EXEMPLE : LA MULTIPLICATION DE DEUX ENTIERS 77

L’algorithme peut s’´ecrire :

fonction produit(a,b: entier):entier

n ← taille(a,b) ;

si n= 1 si (a=1 ET b=1) retourner 1 sinon retourner 0

p ← n >> 1 ; % p=⌊n 2 ⌋

(a 1 ,a 2 ) ← d´ecomposition(a,n) ; (b 1 ,b 2 ) ← d´ecomposition(b,n) ;

s 1 ← produit(addition(a 1 ,a 2 ),addition(b 1 ,b 2 )) ; s 2 ← produit(a 1 ,b 1 ) ; s 3 ← produit(a 2 ,b 2 ) ;

res ← s 1 <<p ; % signifie : res ← s· 2 p res ← addition(res, s 2 <<n) ; res ← soustraction(res, s 2 <<p) ; res ← addition(res, s 3 ) ; res ← soustraction(res, s 3 <<p) ;

retourner res

Evaluation de la complexit´^ ´ e

Notons f : N → N∗^ la fonction de complexit´e en temps. Pour simplifier l’expos´e, la taille d’un couple est consid´er´ee comme le maximum des tailles des deux entiers. Observant que pour multiplier deux entiers a et b de taille chacun au max n, il est n´ecessaire de :

  1. d´ecomposer ces entiers et produire les trois couples d’entiers. Chacune des op´erations (d´ecomposition, taille, addition, d´ecalage, affectation) est de complexit´e O(n). La complexit´e de la d´ecomposition est Θ(n).
  2. r´ealiser trois appels r´ecursifs sur ces trois couples de taille chacun n 2.
  3. recomposer la solution finale `a partir des trois solutions partielles. Cette recomposition n´ecessite 2 additions, 2 soustractions, 4 d´ecalages droits : chacune de ces op´erations est de complexit´e en temps O(n). La complexit´e de la recomposition est Θ(n).

78 CHAPITRE 6. ALGORITHMES “DIVISER POUR R EGNER”´

En clair, la fonction complexit´e f (n) est d´efinie r´ecursivement par f (1) = 1 et f (n) = n + 3f (

n 2

Nous verrons comment r´esoudre un tel systeme d’´equations. Nous pouvons ici le r´esoudrea la main. La solution est f (n) = n + 3(n 2 + 3( 2 n 2 +.. .)) = n((^32 )^0 + (^32 )^1 +

.. .) ≈ n.(^32 )ln^2 (n)) qui est ´egal a n · nln(^ (^32) )/ ln(2) . Observant que 1 + ln(^32 )/ ln(2) est ´egala ln(3)/ ln(2) = ln 2 (3), nous avons :

f (n) = nln^2 (3)^ ≈ n^1 ,^58

6.1.4 Conclusion

Cet algorithme est donc meilleur que le premier algorithme de complexit´e Θ(n^2 ). De nouvelles am´eliorations “Divide and conquer” sont possibles qui per- mettent pour tout r´eel ǫ > 0 de fournir un algorithme solution de Produit de complexit´e en temps Θ(n1+ǫ). D’autre part des techniques utilisant les transform´ees de Fourier permettent en temps lin´eaire Θ(n) de r´esoudre ce mˆeme probl`eme. Ainsi, le produit est de mˆeme complexit´e qu’une addition ou qu’une comparaison.

6.2 Evaluation de la complexit´´ e

Evaluer la complexit´^ ´ e d’un algorithme se fait en deux temps.

6.2.1 D´efinition r´ecursive de la fonction

Cette premi`ere peut ˆetre imm´ediate. Il est n´ecessaire de “projeter” la d´efinition r´ecursive de l’algorithme en une d´efinition r´ecursive de la fonction complexit´e en temps. Nous pouvons alors obtenir par exemple l’´equation :

f (n) = f (

n − 3 4

) + 6 · f (

2 n − 1 8

) + 3 · n +

n + 879

Cette ´equation doit ˆetre d´ebarrass´ee des termes marginaux, des constantes multiplicatives n’apparaissant pas dans le terme r´ecursif. Nous obtenons alors pour ´equation : g(n) = 7 · g(

n 4

) + g

Exercice 40 D´emontrer que les fonctions f et g v´erifiant les deux syst`emes d’´equations pr´ec´edents v´erifient f = Θ(g) et donc g = Θ(f ).

80 CHAPITRE 6. ALGORITHMES “DIVISER POUR R EGNER”´

  1. si a < bk^ , g(n) = Θ(nk).

Exercice 43 Pour r´ealiser le produit de deux entiers, une autre ´equation v´erifi´ee par a · b est :

a · b = (a 1 · b 1 ) · 2 n^ + (a 1 · b 2 + a 2 · b 1 ) · 2

n 2

  • a 2 · b 2

Cette ´equation fournit un algorithme r´ecursif.

  1. Ecrire cet algorithme en utilisant les fonctions utilis´´ ees dans produit2.
  2. Ecrire la d´´ efinition r´ecursive de la fonction complexit´e en temps.
  3. R´esoudre cette ´equation et calculer de fait cette fonction complexit´e.
  4. Calculer la fonction complexit´e en espace.
  5. Comparer ces diff´erentes complexit´es avec celles des algorithmes solution de Produit.
  6. Conclure en comparant cet algorithme aux autres solutions.

6.3 Un deuxi`eme exemple : la multiplication de

deux matrices

Nous pouvons nous inspirer du produit de deux entiers, pour r´ealiser le produit de deux matrices carr´ees :

probl`eme ProduitMat Entr´ee : deux matrices X Y carr´ees de m^eme taille Sortie : le produit matriciel de X et Y

Notons Z la matrice produite. D´ecomposant chacune des matrices carr´ees X, Y et Z de mˆeme taille suppos´ee paire en des matrices A, A, B, C, D, E, F, G, H, I, J, K, L, de la fa¸con suivante :

| A B | | E F | | I J | X = | C D | Y= | G H | Z= | K L |

6.3.1 Premi`ere m´ethode

La premi`ere m´ethode d´ecoule des ´equations ´evidentes :

I = AE + BG J = AF + BH K = CE + DG L = CF + DH

Exercice 44 En vous inspirant de la section traitant du produit de deux entiers :

6.3. UN DEUXI EME EXEMPLE : LA MULTIPLICATION DE DEUX MATRICES` 81

  1. Ecrire un algorithme r´´ esolvant ProduitMat utilisant la m´ethode d´ecrite plus haut.
  2. V´erifier que l’´equation v´erifi´ee par la fonction complexit´e en temps est : f (n) = 8f (n 4 ) + n o`u n est taille de la matrice (9 pour une matrice 3 · 3).
  3. V´erifier que la solution de cette ´equation est Θ(n

3 (^2) ).

  1. Calculer la complexit´e en espace.
  2. Conclure en comparant cet algorithme avec d’autres solutions.

6.3.2 Seconde m´ethode dite de Strassen

Reprenant les notations de la section pr´ec´edentes, la seconde m´ethode d´ecoule des ´egalit´es suivantes :

P1 = A(F-H) P5 = (A+D)(E+H) P2 = (A+B)H P6 = (B-D)(G+H) P3 = (C+D)E P7 = (C-A)(E+F) P4 = D(G-E)

I = P5 + P4 - P2 + P

J = P1 + P

K = P3 + P

L = P5 + P1 - P3 + P

Exercice 45 1. V´erifier la correction des ´equations propos´ees.

  1. En vous inspirant de la section traitant du produit de deux entiers, ´ecrire un algorithme r´esolvant ProduitMat utilisant la m´ethode ci-dessus.
  2. V´erifier que l’´equation v´erifi´ee par la fonction complexit´e en temps est : f (n) = 7 · f (n 4 ) + n o`u n est taille de la matrice (9 pour une matrice 3 · 3).
  3. V´erifier que la solution de cette ´equation est Θ(nln^4 7 ) ≈ Θ(n^1 ,^403 ).
  4. Calculer la complexit´e en espace.
  5. Conclure en comparant cet algorithme avec d’autres solutions.

6.3.3 Conclusion

Une solution algorithmique am´eliore l’algorithme de Strassen (Θ(n^1 ,^403 ) et fournit un algorithme de complexit´e Θ(n^1.^138 ) (Coppersmith & Winogend). Pour des raisons ´evidentes, le produit de deux matrices n´ecessite de lire chacun des ´el´ements de la matrice et n´ecessite au moins Θ(n) op´erations. Peut-on `a l’image du produit de deux entiers (ou de deux vecteurs) atteindre cette limite Θ(n) ou sinon, s’en rapprocher davantage? La question est ouverte.

Chapitre 7

Quelques ´el´ements de

Programmation Dynamique

Nous verrons dans ce chapitre comment g´erer efficacement la m´emoire de fa¸con `a ´eviter la r´ep´etition qui peut ˆetre exponentielle de certains mˆemes calculs. Nous traiterons l’exemple d’un algorithme de complexit´e exponentielle trans- form´e en un algorithme polynomial. Consid´erons l’algorithme suivant :

fonction toto(s:s´equence d’entiers):entier

si longueur(s) = 1 alors retourner premierElement(s) sinon retourner toto(extract1(s)) + toto(extract2(s)) ;

ou extract1 et extract2 extraient deux sous-s´equences de s. Notons n la longueur de la s´equence s. Supposons pour simplifier que la complexit´e de extract1 et extract2 est Θ(1). Dans le cas ou extract1(s) et extract2(s) sont syst´ematiquement de longueur ≤ n b avec b > 1, nous nous trouvons face `a un algorithme “Divide and Conquer” de complexit´e en temps polynomial car solution de g(n) = 1 + 2 · g(n b ).

A contrario, supposons par exemple que` extract1(s) (resp. extract2(s) retire un unique ´el´ement de s par exemple le premier (resp. le dernier). La fonction complexit´e en temps v´erifie l’´equation :

g(n) = 1 + 2 · g(n − 1)

et est ´egale a Θ(2n)! L’algorithme est exponentiel et est impraticable (le traite- ment d’une s´equence de 100 ´el´ements n´ecessite un siecle et ce mˆeme si 1 milliard d’op´erations ´el´ementaires sont ex´ecut´ees par seconde).

84 CHAPITRE 7. QUELQUES EL ´ EMENTS DE PROGRAMMATION DYNAMIQUE´

L’observation des calculs effectu´es par toto nous montre que l’appel sur la s´equence (1,2,3,4,5,6) entraine l’ex´ecution de toto sur les s´equences (1,2,3,4,5) et (2,3,4,5,6). Ce qui provoquera r´ecursivement 4 appels sur les s´equences (1,2,3,4), (2,3,4,5), (2,3,4,5) et (3,4,5,6). Nous voyons ici que par deux fois toto est ex´ecut´e sur la s´equence (2,3,4,5). Si on d´etaille le nombre de fois o`u les appels sont ex´ecut´es sur chacune des sous s´equences nous obtenons le dessin suivant :

Il est facile d’observer que le nombre d’appels sur les s´equences de longueur l est exponentiellement proportionnel `a son oppos´e soit 2^6 −l^ : 2^5 appels sur les s´equences de longueurs 1 ont ´et´e ex´ecut´es alors que 6 en tout auraient suffit.

L’id´ee de la programmation dynamique repose sur l’id´ee de r´ealiser un com- promis espace-temps, c’est a dire d’´eviter de r´ep´eter les mˆemes calculs quitte, pour ´eviter ces r´ep´etitions,a utiliser une m´emoire auxiliaire pour se rappeler des calculs effectu´es.

7.1 Une solution en programmation dynamique

Pour m´emoriser les calculs, nous avons besoin de deux informations :

  1. la premiere d´ejaCalc indique pour toute s´equence si le calcul de toto a d´ej`a ´et´e effectu´e.
  2. la seconde valeurs indique pour toute s´equence pour laquelle le calcul de toto a ´et´e effectu´e, la valeur de ce calcul. Supposons que extract1(s) supprime le premier ´el´ement de la s´equence s alors que extract2(s) supprime le dernier. Ici, toute sous-s´equence extraite t d’une s´equence initiale s peut ˆetre repr´esent´e par un couple d’entiers (i, j) form´e du rang du premier ´el´ement de t relativement a s et du rang du dernier ´el´ement de t relativementa s. L’algorithme devient alors :

86 CHAPITRE 7. QUELQUES EL ´ EMENTS DE PROGRAMMATION DYNAMIQUE´

En cons´equence, nous avons un algorithme quadratique Θ(n^2 ) alternative ef- fective `a un algorithme toto impraticable car de complexit´e exponentielle Θ(2n).

7.1.1 Autre alternative

Dans l’exemple pr´ec´edent, nous pouvons abandonner l’´ecriture r´ecursive et dynamique et obtenir un meilleur algorithme qui organise it´erativement le rem- plissage de la matrice valeurs en prenant des couples (i, j) de fa¸con a faire croˆıtre j − i. Cette connaissance nous permet ainsi de faire l’´economie et de la matrice d´ejaCalc et de la pile d’appel induite par tout algorithme r´ecursif. L’algorithme est :

fonction totoIt´eratif(s:s´equence): entier

l ← longueur(s) ; valeurs ← matriceCarr´ee(l,0) ;

pour i de 1 a l faire valeurs[i][i] = iemeEl´ement(s,i) ;

pour d de 1 a l-1 faire pour i de 1a l faire valeurs[i][i+d] ← valeurs[i][i+d-1] + valeurs[i+1][i+d] ;

retourner valeurs[1][n]

7.2 Bien fond´e de l’approche dynamique

L’existence d’un algorithme it´eratif aussi simple que totoIt´eratif est li´ee a notre capacit´ea pr´edire quelles sont les sous-s´equences de s sur lesquelles le calcul doit ˆetre effectu´e (ici toutes les sous-s´equences de la forme (si,... , sj ) avec s = (s 1 ,... , sn)) et dans quel ordre elles doivent ˆetre ´evalu´ees (ici selon j − i croissant). Le caract`ere polynomial de totoIt´eratif ´etait possible car l’ensemble de ces sous-s´equences ´etait de cardinalit´e polynomiale ici Θ(n^2 ). Parfois cette connaissance est absente et seule une approche dynamique il- lustr´ee par totoDynamique est possible. Supposons que extract1 et extract2 extraient de toute s´equence s des sous- s´equences selon des algorithmes complexes. Par exemple :

fonction extract1(s:s´equence):s´equence % notation s = (s 1 ,...,sn)

si s 1 + s 2 < s 3 + 3 alors retourner (s 1 ,s 3 ,...,sn)

7.2. BIEN FOND E DE L’APPROCHE DYNAMIQUE´ 87

sinon si s 2 ≥ s 4 alors retourner (s 2 ,s 4 ,...,sn) sinon si etc

A cause d’une telle complexit´^ e, il est possiblea priori que toute sous-s´equence de s ait une ´evaluation n´ecessaire a celle de s. Or le nombre de sous-s´equences de s est exponentiel Θ(2n) : par exemple la s´equence (1, 2 , 3) de longueur 3 admet exactement 7 = 2^3 − 1 sous-s´equences : (), (1), (2), (3), (1, 2), (1, 3), (2, 3). Il n’est alors pas possible d’´evaluer toutes les sous s´equences de s comme l’a r´ealis´e totoIt´eratif. Il nous faut ´evaluer que les sous-s´equences r´eellement n´ecessaires, c’esta dire celles rencontr´ees lors du calcul r´ecursif. L’approche est celle utilis´ee par totoDynamique a la diff´erence pres qu’il faut reconsid´erer la d´efinition de d´ej`aCalc et de valeurs. Sans rentrer dans les d´etails, nous pouvons supposer :

  • d´ejaCalc est un ensemble de s´equences dans lequel nous pouvons ajouter toute nouvelle s´equence (fonction ajouter) et dans lequel nous pouvons d´ecider de l’appartenance d’une s´equencea cet ensemble (fonction appartient).
  • valeurs est un ensemble de couples (t,v) form´es d’une s´equence t et d’un entier v dans lequel nous pouvons extraire pour une s´equence donn´ee t la valeur enti`ere associ´ee v dans l’ensemble valeurs (fonction calcValeur). L’algorithme devient alors :

fonction totoDynamique2(s:s´equence): entier

(d´ej`aCalc,valeurs) ← totoDynamRec2(ensVide(),ensVide(),s) ;

retourner calcValeur(valeurs,s) ;

fonction totoDynamRecG(d´ej`aCalc,valeurs: ensemble,s : s´equence) : ensemble × ensemble

si appartient(s,d´ej`aCalc) retourner calcValeur(valeurs,s) ;

sinon si longueur(s)= x ← uniqueEl´ement(s) ; sinon t ← extract1(s) ; u ← extract2(s) ;

(d´ejaCalc,valeurs) ← totoDynamRec2(d´ejaCalc,valeurs,t) ; (d´ejaCalc,valeurs) ← totoDynamRec2(d´ejaCalc,valeurs,u) ;

Chapitre 8

Algorithme Glouton

L’approche “Divide and Conquer” construit une solution apres avoir d´ecoup´e l’entr´ee initiale en plusieurs sous-entr´ees et apres avoir calcul´e les solutions par- tielles a chaque nouvelle sous-entr´ee. La construction de la solution se fait en fait apres avoir parcouru toute l’entr´ee. L’approche gloutonne diff`ere de celle-ci en construisant une partie de la solu- tion de fa¸con d´efinitive.

8.1 Un premier exemple : le rendu de monnaie

Soit E l’ensemble des monnaies en euro. Le probleme de la boulangere est de rendre une valeur S en euro en utilisant un nombre minimal de pi`eces.

probl`eme RenduDeMonnaie Entr´ee : S : entier, E : ensemble d’entiers Sortie : une s´equence d’entiers de E de somme S et de longueur minimale

L’algorithme s’´ecrit de fa¸con r´ecursive de la fa¸con suivante :

fonction renduRec(S:entier ; E: ensemble d’entiers): s´equence d’entiers

si S= retourner () sinon calculer x la plus grande valeur de E inf´erieure ou ´egale `a S ;

retourner ajouter(x,renduRec(S-x))

ou ainsi de fa¸con it´erative :

fonction renduIter(S:entier ; E: ensemble d’entiers): s´equence d’entiers

90 CHAPITRE 8. ALGORITHME GLOUTON

solution ← s´equenceVide() ;

tantque S 6 = 0 faire

calculer x la plus grande valeur de E inf´erieure ou ´egale `a S ;

solution ← ajouter(x,solution) ;

S ← S - x ;

retourner solution

Cet exemple illustre ce qu’est un algorithme glouton en ´ebauchant la solution sans prendre connaissance de la totalit´e de l’entr´ee : en effet, pour rendre la valeur de 17 centimes, seul le premier chiffre compte (le chiffre 1) et d´etermine de rendre une pi`ece de 10 centimes si S vaut { 1 , 2 , 5 , 10 , 20 , 50 }.

8.1.1 Correction

La correction de cet algorithme est li´e au choix de l’ensemble E. Si l’ensemble des pieces europ´eennes avait ´et´e { 1 , 4 , 6 } l’algorithme aurait ´et´e incorrect : il associea la valeur 8 la s´equence (6, 1 , 1) qui n’est pas optimale, la solution optimale ´etant (4, 4).

8.1.2 Am´elioration

Pour des raisons de complexit´es en temps et en espace, une autre repr´esentation de la s´equence solution est pr´ef´erable. En effet si E est ´egal a { 1 , 2 , 5 , 10 }, la so- lution associ´eea la valeur 1000000 (resp .10^100 ) est la s´equence compos´ee de 10000 (resp. 10^99 ) ´el´ements ´egaux a 10. Cet algorithme est donc n´ecessairement exponentiel. Une autre repr´esentation peut se faire dans l’exemple E = { 1 , 2 , 4 , 10 } par un tableau indic´e de 1a 4 et indiquant le nombre de pi`eces correspondant. L’algo- rithme est :

fonction rendu(S:entier ; E: tableau d’entiers): tableau d’entiers

solution ← tableau(4)(0) ;

pour i de 1 `a 4 faire

solution[i] ← ⌊ (^) ES[i] ⌋ ;