BCPST2
9 5
0 3 Récursion
Dénition :
Une fonction est dite récursive lorsqu'elle s'appelle elle-même (directement ou indirectement) dans sa dénition.
Très souvent, une fonction récursive est liée à une relation de récurrence permettant de calculer la valeur de cette fonction pour un argumentn à l'aide des valeurs pour des arguments inférieurs àn.
Exemple :n!
©
Utilisons les relations :
0! = 1, ∀n∈N∗, n! =n×(n−1)!
Ceci suggère de dénir la fonction factorielle en fonction d'elle-même , c'est-à-dire récursivement. Ceci peut s'écrire de la façon suivante :
def factorielle ( n ) : i f n==0:
return ( 1 ) e l s e :
return ( n ∗ factorielle ( n − 1) )
©Exercice 1: Calcul de puissances
1◦) Écrire une fonction récursive puissance(x,n) qui calcule la valeur dexn, avecn∈N, en utilisant la formule suivante : x0= 1 et ∀n∈N∗, xn=x×xn−1.
Solution:
def puissance ( x , n ) : i f n == 0 :
return 1 e l s e :
return x∗ puissance ( x , n −1)
Cet algorithme naïf n'est toutefois pas très performant. Par exemple, pour calculer220, il nécessite 19 multiplications. La remarque qui suit donne l'idée d'une meilleure méthode :
220= (210)2= (25)2)2= (2×24)2)2=
2×(22)222
L'évaluation de la dernière expression écrite ne requiert plus que 5 multiplications.
2◦) Écrire une autre fonction récursive puissance2(x,n) qui calcule la valeur dexn, avecn∈N, en utilisant la formule suivante : x0= 1 et ∀n∈N∗, xn=
(xn/2)2 sinest pair x×(x(n−1)/2)2 sinest impair .
Solution:
def puissance2 ( x , n ) : i f n ==0:
return 1 e l i f n%2 == 0 :
return ( puissance2 ( x , n //2) ) ∗∗2 e l s e :
return x ∗( puissance2 ( x , ( n−1) //2) ) ∗∗2
©Exercice 2: Maximum d'une liste
1◦) Écrire une fonction récursive qui retourne le maximum des éléments d'une liste.
2014-2015 page 1 sur 4 TSVP
BCPST 951/952/953 Lycée du Parc TD 3
Solution:
def maxi ( L ) :
i f len ( L ) == 0 : return " e r r o r "
e l i f len ( L ) == 1 : return L [ 0 ] e l i f len ( L )== 2 :
i f L [ 0 ] > L [ 1 ] : return L [ 0 ] e l s e :
return L [ 1 ] e l s e :
p =len ( L ) //2
return maxi ( [ maxi ( L [ : p ] ) , maxi ( L [ p : ] ) ] )
©Exercice 3: Miroir
1◦) Ecrire une fonction récursive qui renvoie le miroir d'une chaîne de caractères (par exemple, le miroir de "abcde" est "edcba").
Solution:
def miroir ( L ) : i f len ( L )<2 :
return L e l s e :
p = len ( L ) //2
return miroir ( L [ p : ] )+miroir ( L [ : p ] ) Remarque:
Ici, l'utilisation de la récursion est plutôt maladroit. En eet, il est bien plus ecace de faire :
def miroir2 ( L ) :
return ' ' . join ( [ L [ i ] f o r i in range ( len ( L ) −1,−1,−1) ] )
©Exercice 4: Recherche dans une liste triée
1◦) Soit L une liste de réels triée par ordre croissant et soit x∈R. La recherche par dichotomie de x dans la liste L est assez simple. On procède comme suit :
â on compare x à l'élément du milieu de la liste L[med] : H si x est égal à L[med], alors on a terminé notre recherche
H si x<L[med], alors on cherche l'élément x dans la première moitié de la liste H si x>L[med], alors on cherche l'élément x dans la seconde moitié de la liste ; â puis on réitère ce procédé.
Écrire une fonction recherche_dicho(L,x) qui recherche l'élément x dans la liste L triée par ordre croissant selon la méthode de recherche par dichotomie.
2014-2015 page 2 sur 4 TSVP
BCPST 951/952/953 Lycée du Parc TD 3
Solution:
def recherche ( L , x ) :
""" on suppose l a l i s t e t r i é e par ordre c r o i s s a n t """
i f len ( L ) == 0 :
return "non p r e s e n t "
e l i f len ( L ) == 1 and L [ 0 ] == x : return " p r e s e n t "
e l i f len ( L )== 1 and L [ 0 ] != x : return "non pr é sent "
e l s e :
p = len ( L ) //2 i f L [ p ] == x :
return " p r e s e n t "
e l i f L [ p ] < x :
return recherche ( L [ p + 1 :] , x ) e l s e :
return recherche ( L [ : p ] , x )
©Exercice 5: Coecients binomiaux
1◦) Écrire une fonction récursive binomial(n,p) qui calcule la valeur de np
, en utilisant la formule suivante :
∀(n, p)∈N2tel que1≤p≤n, pn p
=nn−1 p−1
Solution:
def binomial ( n , p ) : i f p<0 or p>n :
return 0 e l i f p == 0 : return 1 e l s e :
return n∗ binomial ( n −1, p−1)/p
2◦) Écrire une fonction récursive binomial2(n,p) qui calcule la valeur de pn
, en utilisant la formule de Pascal.
Solution:
def binomial2 ( n , p ) : i f p<0 or p>n :
return 0
e l i f p == 0 or n == p : return 1
e l s e :
return binomial2 ( n−1, p−1)+ binomial2 ( n−1,p ) Remarque:
Bien que séduisante, cette méthode est en fait mauvaise car la plupart des coecients binomiaux intermédiaires nécessaires au calcul sont calculés en double
©Exercice 6: Tours de Hanoï
1◦) Récupérer sur http ://bcpst.parc.free.fr (rubrique 952, maths, info) le chier qui permettra de faire l'achage graphique du problème.
2014-2015 page 3 sur 4 TSVP
BCPST 951/952/953 Lycée du Parc TD 3
Le problème des tours de Hanoï est un jeu de réexion qui consiste à déplacer des disques de diamètres diérents d'une tour de départ à une tour d' arrivée en passant par une tour intermédiaire et ceci en un minimum de coups, tout en respectant les règles suivantes :
â On ne peut déplacer plus d'un disque à la fois.
â On ne peut placer un disque que sur un autre disque plus grand que lui ou sur un emplacement vide.
â On suppose que cette dernière règle est également respectée dans la conguration de départ.
On peut résoudre ce problème de façon récursive de la façon suivante :
¬ On suppose qu'on andisques sur la tour de départ.
On déplace la tour desn−1premiers disques sur la tour intermédiaire
® On déplace le dernier disque (le plus grand) sur la tour d'arrivée.
¯ On déplace les disques de la tour intermédiaire sur la tour d'arrivée.
2◦) Écrire une fonction récursive resout_hanoi(n, D, I, A,N,T) où :
H Chaque disque est représenté par un numéro entre1etndonnant son diamètre.
H T est la liste contenant l'état : c'est une liste contenant 3 listes représentant les 3 tours. Chaque sous liste contient le numéro des disques qu'elle contient, ordonnée de bas en haut.
H N est le nombre total de disques (c'est juste pour l'achage) H D, I, A c'est le numéro des tours (numérotées 0,1,2) H n le nombre de disques à déplacer
3◦) Compléter la fonction hanoi et vérier votre programme en lançant l'éxecution de hanoi(3) par exemple.
4◦) Modier ce qui est nécessaire pour pouvoir compter le nombre de déplacements nécessaires.
Solution:
def resout_hanoi ( n , D , I , A , N , T ) :
#l a proc é dure r é c u r s i v e
#T e s t l a l i s t e contenant l ' é t a t
# N e s t l e nombre t o t a l de disque ( c ' e s t j u s t e pour l ' a f f i c h a g e )
# D, A, I c ' e s t l e numé ro des t o u r s
# n l e nombre de d i s q u e s à dé p l a c e r i f n != 0 :
nb1 = resout_hanoi ( n −1, D , A , I , N , T ) x = T [ D ] . pop ( )
T [ A ] . append ( x ) affiche_tour ( N ) affiche_hanoi ( T )
nb2 = resout_hanoi ( n −1, I , D , A , N , T )
return nb1+1+nb2 # C ' e s t l e nombre de dé placements e f f e c t u é s e l s e :
return 0
def hanoi ( n ) :
T=[list ( range ( n ,0 , −1) ) , [ ] , [ ] ] plt . ion ( )
affiche_tour ( n ) affiche_hanoi ( T )
nb = resout_hanoi ( n , 0 , 1 , 2 , n , T ) p r i n t ( nb )
plt . ioff ( ) plt . show ( )
5◦) Proposer une formule pour ce nombre de déplacements et la démontrer.