TD d’algorithmique avanc´ee Corrig´e du TD 2 : r´ecursivit´e
Jean-Michel Dischler et Fr´ ed´ eric Vivien
Suite de Fibonacci
La suite de Fibonacci est d´efinie comme suit :
Fib(n) =
1 sin= 0
1 sin= 1
Fib(n−1) + Fib(n−2) sinon.
1. ´Ecrivez un algorithme r´ecursif calculant Fib(n).
Fibonacci(n)
sin= 0 oun= 1alors renvoyer1
sinon renvoyerFibonacci(n−1) +Fibonacci(n−2) 2. Montrez que la complexit´e (en nombre d’additions) de cet algorithme est en Ω(2n2).
On proc`ede par r´ecurrence. On veut montrer qu’il existe une constante c strictement positive telle que T(n)≥c.2n2, pour des valeurs den sup´erieures `a une certaine borne n0 (`a d´eterminer). Supposons le r´esultat d´emontr´e jusqu’au rang n−1. Alors :
T(n) =T(n−1) +T(n−2) + 1≥c.2n−12 +c2n−22 + 1≥c.2n−22 +c.2n−22 + 1≥2×c.2n−22 =c.2n2 Il nous reste juste `a montrer que cette ´equation est vraie « au d´epart ». Nous ne pouvons bien
´
evidemment pas partir des cas n = 0 et n = 1, puisque pour ces valeurs T(n) = 0. Nous partons donc des casn= 2etn= 3 (la r´ecurrence n´ecessite deuxvaleurs de d´epart) :
– Cas n= 2 : Fibonacci(2) = Fibonacci(1) +Fibonacci(0), etT(2) = 1. Pour que la propri´et´e d´esir´ee soit vraie,c doit donc v´erifier :
1≥c.222 = 2c ⇔ c≤ 1 2
– Cas n= 3 : Fibonacci(3) = Fibonacci(2) +Fibonacci(1), etT(3) = 2. Pour que la propri´et´e d´esir´ee soit vraie,c doit donc v´erifier :
2≥c.232 = 2√
2c ⇔c≤
√2 2 Donc si c=12, pourn≥2, on a T(n)≥c2n2 et doncT(n) = Ω(2n2).
3. ´Ecrire un algorithme r´ecursif qui calcule, pourn >0, le couple (Fibonacci(n),Fibonacci(n−1)).
Fib-Paire(n)
sin= 1alors renvoyer(1, 1)
sinon(x,y) =Fib-Paire(n−1) renvoyer(x+y,x)
4. Utilisez l’algorithme pr´ec´edent pour ´ecrire un nouvel algorithme calculantFibonacci(n).
Fibonacci(n)
sin= 0alors renvoyer1
sinon(x,y) =Fib-Paire(n) renvoyerx
5. Qu’elle est la complexit´e (en nombre d’additions) de cet algorithme ?
La complexit´e de l’algorithme Fib-Paire, en nombre d’additions, est donn´ee par la r´ecurrenceT(n) = 1 +T(n−1). On a donc T(n) =n−1 pour Fib-Paire, et par extension pour la nouvelle version de Fibonacci.
Op´ erations ensemblistes
Dans cette partie on consid`ere des ensembles repr´esent´es par des tableaux, certains ensembles seront tri´es et d’autres pas.Toutes les solutions propos´ees doivent ˆetre r´ecursives.
1. Nous voulons un algorithme Appartenance(A, x) qui recherche si un ´el´ement x appartient `a l’en- sembleA. Sixappartient effectivement `a A, l’algorithme renverraVrai, etFauxsinon.
(a) Cas des ensembles non tri´es : i. ´Ecrivez un tel algorithme.
Recherche(A,rang, x)
sirang >longueur(A)alors renvoyerFaux siA[rang] =xalors renvoyerVrai
sinon renvoyerRecherche(A,rang + 1,x) L’appel initial de l’algorithme est alorsRecherche(A, 1,x).
ii. Quelle est sa complexit´e en nombre de comparaisons ?
Dans le pire cas, l’´el´ement n’appartient pas `a l’ensemble et tout le tableau est parcouru. La complexit´e au pire est donc en Θ(n), o`u n est la longueur du tableau (et donc la taille de l’ensemble).
(b) Cas des ensembles tri´es (dans l’ordre croissant) : i. ´Ecrivez un tel algorithme.
Recherche(A,rang, x)
sirang >longueur(A) ouA[rang]> x alors renvoyerFaux
sinon siA[rang] =x alors renvoyerVrai
sinon renvoyerRecherche(A, rang + 1,x) L’appel initial de l’algorithme est alorsRecherche(A, 1,x).
ii. Quelle est sa complexit´e en nombre de comparaisons ?
Le pire cas est aussi en Θ(n) : il intervient quand l’´el´ement recherch´e n’appartient pas `a l’ensemble mais est plus grand que tous les ´el´ements de l’ensemble.
iii. Utilisez une recherche dichotomique pour am´eliorer votre algorithme.
Recherche(A,x, inf,sup) milieu ←jinf+sup
2
k siA[milieu] =x
alors renvoyerVrai
sinon siA[milieu]> xalors renvoyerRecherche(A, x,inf,milieu - 1) sinon renvoyerRecherche(A,x,milieu + 1,sup)
iv. Quelle est la complexit´e de votre nouvel algorithme ?
Posonsn=sup−inf+1le nombre d’´el´ements dans la partie du tableau `a ´etudier. Consid´erons la taille du tableau lors de l’´eventuel appel r´ecursif. Nous avons deux cas `a consid´erer : – L’appel effectu´e est : Recherche(A,x, inf, milieu - 1). Le nombre d’´el´ements concern´es
est alors : milieu−1−inf + 1 =jsup
−inf 2
k
=n−1 2
≤n2.
– L’appel effectu´e est : Recherche(A,x, milieu + 1, sup). Le nombre d’´el´ements concern´es est alors : sup−(milieu+ 1) + 1 =lsup
−inf 2
m
=n−1 2
≤ n2.
On passe donc d’un ensemble de taille n `a un ensemble de taille au plus n2. D’o`u T(n) ≤ 2 ×T(n2) (la fonction T(n) ´etant croissante, on peut se permettre l’approximation). Par cons´equent : T(n)≤2×log2(n)T(2log2n n)etT(n) =O(log2n).
2. Nous voulons maintenant un algorithmeUnion(A,B) qui nous renvoie l’union des deux ensembles qui lui sont pass´es en argument.
(a) Cas des ensembles non tri´es : i. ´Ecrivez un tel algorithme.
Union(A,B,rang,C)
siRecherche(A,B[rang]) =Faux alorslongueur(C)←longueur(C) + 1
C[longueur(C)]←B[rang]
Union(A, B,rang+ 1,C)
L’appel initial est alors Union(A, B, 1, C) o`u C est un tableau de taille longueur(A) + longueur(B), et dont leslongueur(A) premi`eres cases contiennent les ´el´ements de A.
ii. Quelle est sa complexit´e ?
La recopie deA dansC est de coˆut longueur(A).
L’algorithme Unionest appel´e longueur(B) fois, chacun de ces appels effectuant un appel `a RecherchesurA, dont le coˆut au pire est en longueur(A). La complexit´e au pire de Union est donc en Θ(longueur(A)×longueur(B)) ou Θ(nm), n et m d´enotant la taille des deux tableaux. Ce pire cas apparaˆıt quand les tableauxA etB sont disjoints.
(b) Cas des ensembles tri´es (dans l’ordre croissant) : i. ´Ecrivez un tel algorithme.
Union(A,a,B,b,C)
sia >longueur(A) etb >longueur(B)alors renvoyerC sib >longueur(B) ouB[b]> A[a]
alorslongueur(C)←longueur(C) + 1 C[longueur(C)]←A[a]
Union(A,a+ 1,B,b,C) sinonlongueur(C)←longueur(C) + 1
C[longueur(C)]←B[b]
sia≤longueur(A) etA[a] =B[b]alorsUnion(A,a+ 1,B,b+ 1,C) sinonUnion(A,a,B,b+ 1,C) L’appel initial estUnion(A, 1,B, 1,C).
ii. Quelle est sa complexit´e ?
La complexit´e de cet algorithme est au pire enΘ(longueur(A) +longueur(B))ouΘ(n+m):
`
a chaque appel on d´ecr´emente au moins de un l’ensemble des valeurs `a consid´erer.
3. Nous voulons maintenant un algorithmeIntersection(A,B) qui nous renvoie l’intersection des deux ensembles qui lui sont pass´es en argument.
(a) Cas des ensembles non tri´es : i. ´Ecrivez un tel algorithme.
Intersection(A,B,rang, C)
siRecherche(A,B[rang]) =Vrai alorslongueur(C)←longueur(C) + 1
C[longueur(C)]←B[rang]
Intersection(A, B,rang+ 1,C)
L’appel initial est alors Intersection(A, B, 1, C) o`u C est un nouveau tableau, de taille min(longueur(A),longueur(B)), et ne contenant initialement aucun ´el´ement (longueur(C) = 0).
ii. Quelle est sa complexit´e ?
L’algorithme Intersection est appel´e longueur(B)fois, chacun de ces appels effectuant un appel `a Recherche sur A, dont le coˆut au pire est en longueur(A). La complexit´e au pire de Intersectionest donc enΘ(longueur(A)×longueur(B))ouΘ(nm),netmd´enotant la taille des deux tableaux. Ce pire cas apparaˆıt quand les tableauxA etB sont disjoints.
(b) Cas des ensembles tri´es (dans l’ordre croissant) : i. ´Ecrivez un tel algorithme.
Intersection(A,a,B,b, C)
sia >longueur(A) oub >longueur(B)alors renvoyerC siA[a] =B[b] alorslongueur(C)←longueur(C) + 1
C[longueur(C)]←A[a]
renvoyerIntersection(A,a+ 1,B,b+ 1,C)
sinon siB[b]> A[a]alors renvoyerIntersection(A,a+ 1,B,b,C) sinon renvoyerIntersection(A,a,B,b+ 1,C) L’appel initial estIntersection(A, 1,B, 1,C, 0).
ii. Quelle est sa complexit´e ?
La complexit´e de cet algorithme est au pire enΘ(longueur(A) +longueur(B))ouΘ(n+m):
`
a chaque appel on d´ecr´emente au moins de un l’ensemble des valeurs `a consid´erer.
4. Nous voulons maintenant un algorithme Diff´erence(A, B) qui nous renvoie la diff´erence des deux ensembles qui lui sont pass´es en argument (La diff´erence de Aet deB, not´ee A\B est l’ensemble des
´
el´ements deA n’appartenant pas `aB).
(a) Cas des ensembles non tri´es : i. ´Ecrivez un tel algorithme.
Diff´erence(A,rang,B,C)
siRecherche(B,A[rang]) =Faux alorslongueur(C)←longueur(C) + 1
C[longueur(C)]←A[rang]
Diff´erence(A,rang+ 1,B, C)
L’appel initial est alorsDiff´erence(A, 1,B,C) o`uCest un tableau de taillelongueur(A), ne contenant initialement aucun ´el´ement (longueur(C) = 0).
ii. Quelle est sa complexit´e ?
L’algorithme Diff´erence est appel´e longueur(A) fois, chacun de ces appels effectuant un appel `a Recherchesur B, dont le coˆut au pire est en longueur(B). La complexit´e au pire de Diff´erenceest donc en Θ(longueur(A)×longueur(B)) ouΘ(nm), n etm d´enotant la taille des deux tableaux. Ce pire cas apparaˆıt quand les tableauxA etB sont disjoints.
(b) Cas des ensembles tri´es (dans l’ordre croissant) : i. ´Ecrivez un tel algorithme.
Diff´erence(A,a,B,b,C)
sia >longueur(A)alors renvoyerC
siA[a] =B[b] alors renvoyerDiff´erence(A,a+ 1,B,b+ 1,C) sinon siA[a]< B[b]alorslongueur(C)←longueur(C) + 1
C[longueur(C)]←A[a]
renvoyerDiff´erence(A,a+ 1,B,b,C) sinon renvoyerDiff´erence(A, a, B,b+ 1,C) L’appel initial estDiff´erence(A, 1,B, 1,C, 0).
ii. Quelle est sa complexit´e ?
La complexit´e de cet algorithme est au pire enΘ(longueur(A) +longueur(B))ouΘ(n+m):
`
a chaque appel on d´ecr´emente au moins de un l’ensemble des valeurs `a consid´erer.