Lycée Sainte Geneviève PC1
Récursivité - Corrections
Factorielle
Exercice 1
Python
def factorielle(n):
if n==1:
return 1
else:
return n*factorielle(n-1)
Lorsqu’il y a appel récursif, la fonction
factorielle
eectue en plus 2 opérations :
un test et une multiplication. La complexité au rang 𝑛peut donc s’exprimer en fonc-
tion de la complexité au rang 𝑛−1:
𝐶𝑛= 𝐶𝑛−1 + 2
Avec 𝐶(1) = 1, on obtient :
𝐶𝑛= 2(𝑛 − 1) + 1
La complexité de la fonction est donc linéaire.
Une fonction mystère
Exercice 2
Cette fonction calcule la somme des chires du nombre
n
. La complexité est linéaire
par rapport au nombre de chires de 𝑛.
Suite de Syracuse
Exercice 3
Python
def syracuse(N,k):
if k>1:
print(N)
if N%2==0:
syracuse(N/2,k-1)
else:
syracuse(3*N+1,k-1)
else:
print(N)
Python
def temps_de_vol(N,k):
if N!=1:
print('u',k,'=',N)
if N%2==0:
temps_de_vol(N/2,k+1)
else:
temps_de_vol(3*N+1,k+1)
else:
print('k=',k)
print('u',k,'=',N)
1
Lycée Sainte Geneviève PC1
Flocon de von Koch
Exercice 4
1.
Au rang
0
, la courbe de Koch est constituée d’un unique segment. L’axiome est
donc 𝐴.
On doit ensuite remplacer le segment central d’une ligne droite par un triangle
équilatéral :
𝐴 → 𝐴𝐺𝐴𝐷𝐴𝐺𝐴
2.
Pour obtenir la courbe de Koch au rang
𝑛
, on appelle la fonction
chaine_rec('A',n).
Python
def chaine_rec(chaine,n):
if n==1:
return chaine
else:
res=[]
for lettre in chaine:
if lettre == 'A':
res+='AGADAGA'
else:
res+=lettre
return chaine_rec(res,n-1)
3.
Pour éviter d’avoir un ocon immense aux ordres élevés, on divise la distance
parcourue lorsque la tortue avance par la longueur de la chaine de caractères.
Python
def trace(sequence):
L=len(sequence)
speed(1000)
up()
goto(-250,0)
down()
for lettre in sequence:
if lettre=='A':
forward(10000/L)
elif lettre=='G':
left(60)
elif lettre=='D':
right(120)
mainloop()
4.
Pour le ocon, la règle de remplacement est la même que pour la courbe, seul
l’axiome est diérent. La fonction
chaine_rec
est inchangée mais est appelée
avec : chaine_rec('ADADA',n)
Tours de Hanoi
Exercice 5
L’hypothèse de récurrence est la suivante :
𝐻𝑛: On peut déplacer 𝑛disques du premier vers le dernier piquet.
Pour les gures, on note 𝐴, 𝐵 et 𝐶les trois piquets de la gauche vers la droite.
L’hypothèse 𝐻1est vraie :
𝐴𝐵𝐶𝐴𝐵𝐶
2
Lycée Sainte Geneviève PC1
Il ny a besoin que d’un seul mouvement :
𝐴 → 𝐶
On suppose maintenant que
𝐻𝑛−1
est vraie (on peut déplacer
𝑛 − 1
disques de
𝐴
vers
𝐶) et on cherche à montrer que 𝐻𝑛est vraie.
𝐴𝐵𝐶
𝑛−1
𝐴𝐵𝐶
𝐴𝐵𝐶𝐴𝐵𝐶
Les mouvements nécessaires sont les suivants :
𝑛 − 1 disques 𝐴 𝐵 ;
1 disque 𝐴 𝐶 ;
𝑛 − 1 disques 𝐵 → 𝐶.
Python
def hanoi(n,A,B,C):
if n==1:
print(A,'->',C)
else:
hanoi(n-1,A,C,B)
print(A,'->',C)
hanoi(n-1,B,A,C)
Méthode de Karatsuba
Exercice 6
1. Le polynôme résultant du produit est de degré 𝑝+𝑞:
Python
def produit(P,Q):
p,q=len(P),len(Q)
res=[0]*(p+q)
for iin range(p):
for jin range(q):
res[i+j] += P[i]*Q[j]
return res
Du fait de la double boucle
for
, la complexité de cette fonction est quadratique.
2. On a :
𝑃𝑄 = (𝑃bas + 𝑋𝑛𝑃haut)(𝑄bas + 𝑋𝑛𝑄haut)
= 𝑃bas𝑄bas + 𝑋𝑛(𝑃bas𝑄haut + 𝑄bas𝑃haut)+𝑋2𝑛𝑃haut𝑄haut
= 𝐴 + 𝑋𝑛(𝐶 − 𝐴 − 𝐵)𝑃bas + 𝑋2𝑛𝐵
3.
La méthode récursive consiste à couper les polynômes en deux puis d’utiliser
la fonction pour calculer les produits
𝐴, 𝐵
et
𝐶
sur des polynômes deux fois
plus petit.
La condition d’arrêt est obtenue lorsquon fait le produit de deux polynômes de
degré 0 : il sut de faire le produit des deux coecients.
4.
Pour calculer
𝐶
et
𝐶−𝐴−𝐵
, on utilise deux fonctions annexes
somme
et
différence. On considère que les deux polynômes sont de même longueur.
Python
def somme(P,Q):
for idx,elmt in enumerate(Q):
P[idx]+=elmt
return P
3
Lycée Sainte Geneviève PC1
Python
def difference(P,Q):
for idx,elmt in enumerate(Q):
P[idx]-=elmt
return P
Pour assurer un découpage au même degré, il faut s’assurer que les listes
P
et
Q
ont la même longueur (quitte à remplir avec des 0).
Python
def karatsuba(P,Q):
p,q=len(P),len(Q)
n=max(p,q)
n=n//2+n%2
if p==1 and q==1:
return [P[0]*Q[0]]
else:
#Remplissage des deux listes pour contenir
#le même nombre pair d'éléments
P+=[0]*(2*n-p)
Q+=[0]*(2*n-q)
#Division en 2 des listes P et Q:
P_bas,P_haut=P[:len(P)//2],P[len(P)//2:]
Q_bas,Q_haut=Q[:len(Q)//2],Q[len(Q)//2:]
#Calculs de A, B et C
A=karatsuba(P_bas,Q_bas)
B=karatsuba(P_haut,Q_haut)
C=karatsuba(somme(P_bas,P_haut),
somme(Q_bas,Q_haut))
C=difference(difference(C,A),B)
#Placement des coefficients à la bonne
#position dans B et C
B,C=[0]*2*(n)+B,[0]*(n)+C
return somme(somme(A,C),B)
5. Pour évaluer la complexité, la récurrence va porter sur 𝑝et non pas sur 𝑛:
{𝐶(1) = 1𝐶(𝑝) = 3𝐶(𝑝 − 1) + 𝛼
On obtient une suite arithmético-géométrique et donc une complexité en
𝑂(3𝑝)
.
Or 𝑝 = log2(𝑛), donc la complexité est en 𝑂(3log2(𝑛)).
La courbe ci-dessous compare le nombre de multiplications pour les deux mé-
thodes :
Ce document est sous licence Creative Commons BY-NC-SA
(attribution, usage non commercial, partage dans les mêmes conditions).
Plus de détails sur http ://creativecommons.org/licenses/by-nc-sa/3.0/fr/
cbna
4
1 / 4 100%
La catégorie de ce document est-elle correcte?
Merci pour votre participation!

Faire une suggestion

Avez-vous trouvé des erreurs dans linterface ou les textes ? Ou savez-vous comment améliorer linterface utilisateur de StudyLib ? Nhésitez pas à envoyer vos suggestions. Cest très important pour nous !