REVITRON.FREE.FR I INTRODUCTION `A LA R ´ECURSIVIT ´E
I. Introduction ` a la r´ ecursivit´ e
1 - Pr´ esentation
En informatique, les fonctions r´ecursives sont des fonctions dont le calcul n´ecessite d’invoquer la fonction elle-mˆeme.
D´ efinition :
Cela permet de traduire informatiquement l’id´ee de r´ecurrence en math´ematiques.
Par exemple, la d´efinition par r´ecurrence de la factorielle est : n! = 1 sin= 0
n×(n−1)! sinon.
Exemple 1 :
´Ecrire une fonction r´ecursive, c’est ´ecrire :
• Une condition d’arrˆet , tr`es importante, correspondant `a l’initialisation de la r´ecurrence,
• Un ou plusieurs appels r´ecursifs, correspondant `a l’h´er´edit´e.
D´ efinition :
Ecriture r´ecursive de la fonction factorielle :
Exemple 2 :
1 d e f f a c t ( n ):
2 " R e n v o i e la f a c t o r i e l l e de n " " "
3 if n == 0:
4 r e t u r n 1
5 e l s e:
6 r e t u r n n * f a c t ( n -1)
2 - Pile de r´ ecursion
L’interpr´eteur g`ere une pile dite de r´ecursion pour les appels successifs puis les calculs
`a effectuer.
Pour sch´ematiser, l’appel de fact(4) correspond `a la situation d´ecrite sur la figure suivante. La commande fact(4) demande l’ex´ecution de fact(3) puis defact(2), puis defact(1), puis defact(0)qui renvoie la valeur 1. L’ex´ecution du programme impose alors le calcul `a partir du haut de la pile d’information `a traiter.
Figure 1: Exemple de pile de r´ecursion
En python, la pile de r´ecursion est limit´ee `a 1 000 appels environ. Il est possible de modifier cette limite : import sys
sys.setrecursionlimit( nb )
Remarque 1 :
Ecrire une fonction r´ecursive donnant le nieme, terme de la suite de H´eron d´efinie avecu0= 1 et
un+1=u2n+ 2 2un
Exemple 3 :
Il existe des probl`emes Python due `a la programmation objet de python. Les listes utilisent ´egalement la r´ecursivit´e et des modification de listes peuvent conduire `a des r´esultats surprenants au premier abord :
1 > > > L = [1 ,2]
2 > > > L [0] = L 3 > > > L 4 [[...] , 2]
5 > > > L [0]
6 [[...] , 2]
7 > > > L [ 0 ] [ 0 ] 8 [[...] , 2]
II. Exemples d’Algorithmes
1 - Parcours d’une liste sans forme...
Dans certains cas, l’´ecriture r´ecursive d’un algorithme est beaucoup plus facile que son homologue non-r´ecursif :
D’apr`es Centrale 2019
On d´esire fare la somme de d’´el´ements dans une liste d’entier dont les
´el´ements sont des listes de diff´erentes tailles : L = [1,5,[23,12],[0],[
[ 0,3] , [1] , 4] ] . On utilisera la fonction isinstance(a,int) qui renvoie Truesiaest un entier etFalsesinon
Exemple 4 :
2 - Une suite d´ efinie par r´ ecurrence
D’apr`es Concours blanc 2022 On note S(n, k) la suite d´efinie par :
• S(0,0) = 1
• ∀n∈N∗,S(n,0) = S(0,n) = 0
• ∀(n,k)∈N∗×N∗; S(n,k) = S(n−1,k−1) +kS(n−1,k)
On v´erifiera la fonction en ´etablissant le tableau de valeur suivant : k= 0 k= 1 k= 2 k= 3 k= 4 k= 5 k= 6
n=0 1 0 0 0 0 0 0
n=1 0 1 0 0 0 0 0
n=2 0 1 1 0 0 0 0
n=3 0 1 3 1 0 0 0
n=4 0 1 7 6 1 0 0
Exemple 5 :
3 - Recherche de z´ ero d’une fonction par dichotomie
a) Ecriture non r´´ ecursive
REVITRON.FREE.FR III CALCUL DE COMPLEXIT ´E
1 d e f d i c h o ( f , a , b , e r r e u r ):
2 ’ ’ ’
3 R e c h e r c h e de f ( x )=0 par d i c h o t o m i e 4 f : f u n c t i o n
5 a , b , e r r r e u r : f l o a t
6 r e t o u r : m e i l l e u r a p p r o x de x a e r r e u r p r e s
7 ’ ’ ’
8 w h i l e ( b - a ) > e r r e u r :
9 c =( a + b )/2
10 if f ( a )* f ( c ) <0:
11 b = c
12 e l s e :
13 a = c
14 r e t u r n a
b) Ecriture r´´ ecursive
Proposer une fonction dicho(f,a,b,erreur)permettant d’obtenir z´ero de f de fa¸con r´ecursive par dichotomie. On testera le r´esultat pour une fonction f(x) =x2−2 aveca= 1 etb= 2. On rappelle que√
2≈1,44.
Exemple 6 :
4 - Recherche de z´ ero par m´ ethode de Newton
a) Ecriture non r´´ ecursive
1 d e f N e w t o n ( f , fprime , x , e r r e u r ):
2 ’ ’ ’
3 R e c h e r c h e de f ( x )=0 par N e w t o n 4 f , f p r i m e : f u n c t i o n
5 x , e r r r e u r : f l o a t
6 r e t o u r : m e i l l e u r a p p r o x de f ( x )=0 a e r r e u r p r e s
7 ’ ’ ’
8
9 w h i l e a b s( f ( x )/ f p r i m e ( x )) > e r r e u r : 10 x -= f ( x )/ f p r i m e ( x )
11 r e t u r n x
Ce code est beaucoup plus performant que la m´ethode par dichotomie mais la con- vergence n’est pas assur´ee. En particulier, sif′(x) = 0, la valeur dexdiverge.
b) Ecriture r´´ ecursive
Ecrire une fonctionNewton(f,fprim,x0,erreur)permettant d’obtenir z´ero de f de fa¸con r´ecursive par la m´ethode de Newton. On testera le r´esultat pour une fonction f(x) = x2−2 avec a = 1 et b = 2. On rappelle que
√2≈1,44.
Exemple 7 :
5 - Recherche d’un indice dans une liste tri´ ee
Proposer deux fonctionsindice NR(x,Ltri)etindice R(x,Ltri,a,b)per- mettant d’obtenir la position dexdans une liste tri´eeLtri. Les param`etres aet bsont des curseurs pointant intialement vers 0 etlen(Ltri)-1. On testera la fonction avec la position de l’´el´ement 4 dans la liste L = [0,1,3,4,8,10] .
Exemple 8 :
6 - (Facultatif) Maximum d’une liste
´Ecrire les fonctions de mani`eres r´ecursives suivantes : Max(L) permettant d’obtenir le maximum d’une liste de fa¸con r´ecursive
Exemple 9 :
III. Calcul de complexit´ e
1 - Rappels sur la complexit´ e
´Evaluer la complexit´e en temps d’une fonction consiste `a donner un ordre de grandeur du nombre d’op´erations ´el´ementaires effectu´ees lors de l’ex´ecution de cette fonction. On
admettra comme op´eration ´el´ementaire une op´eration arithm´etique, une affectation, une comparaison (´evaluation d’une expression bool´eenne), l’affichage d’un r´esultat, l’acc`es `a un ´el´ement d’une liste, l’ajout ou la suppression d’un ´el´ement `a une liste, le calcul de la longueur d’une liste.
Soitf une fonction admettant un entier ncomme param`etre. On note C(n) la complexit´e en temps de la fonction f par rapport `a n. Soit ( n)n2N une suite de r´eels positifs. On dit que la complexit´e C(n) de f est en O(γ(n)) s’il existe (a;b) etn0 tel que
∀n⩾n0, a×γ(n)⩽C(n)⩽b×γ(n)
D´ efinition :
On parle de complexit´e :
• en temps constant si C(n) = O(1) ;
• logarithmique si C(n) = O(ln(n)) ;
• lin´eaire si C(n) = O(n) ;
• quadratique si C(n) = O(n2) ;
• polynomiale de degr´epsi C(n) = O(np) ;
• exponentielle s’il existeatel que C(n) = O(an).
D´ efinition :
Si une op´eration ´el´em´entaire s’effectue en 1mus, pour 100 op´erations le tableau suivant donne une id´ee des temps de calcul
Complexit´e O(n) O(n2) O(2n) temps 0,1 ms 0,01 s 1,3.1030s Pour conversion : 1030s= 4.1022ans
a) Pour des fonctions non-r´ecursives
Pour des fonctions non-r´ecursives le calcul de complexit´e s’effectue en comptant le nombre d’op´erations effectu´ees :
• pour une boucle, la complexit´e est en O(n), ex :
1 d e f m a x( L ):
2 m = L [0]
3 f o r x in L :
4 if x > m :
5 m = x
6 r e t u r n m
• pour deux boucles imbriqu´ees, elle devient en O(n2).
1 d e f m a x _ 2 D ( t a b l e a u ):
2 m , n = t a b l e a u . s h a p e
3 m a x= L [0 ,0]
4 f o r i in r a n g e(1 , m ):
5 f o r j in r a n g e(1 , n )
6 if x > m :
7 m a x = x
8 r e t u r n m a x
b) Calcul de factoriel
La complexit´e temporelle s’obtient sous forme de suite r´ecurrente. L’obtention de la suite s’´ecrit en ´evaluant le nombre d’appel de la fonction r´ecursive et le nombre d’op´eration effectu´e dans la fonction :
1 d e f f a c t ( n ):
2 " R e n v o i e la f a c t o r i e l l e de n " " "
3 if n == 0:
4 r e t u r n 1
5 e l s e:
6 r e t u r n n * f a c t ( n -1)
La fonction est appel´ee une seule fois : fact(n-1), il y a une op´eration (*), on obtient :
T(n) = 1×T(n−1) + 1 .
On reconnaˆıt l’´ecriture d’une suite arithm´etique, on en d´eduit que T(n) =a×n+b= O(n)
REVITRON.FREE.FR III CALCUL DE COMPLEXIT ´E
c) Suite de h´eron
1 d e f H e r o n 1 ( n ):
2 " r e t o u r n e le t e r m e d ’ i n d i c e n de la s u i t e de H e r o n "
3 if n == 0: r e t u r n 1
4 e l s e:
5 u = H e r o n 1 ( n - 1)
6 r e t u r n ( u **2 + 2) / (2* u )
Notonsαle nombre d’op´eration ´el´ementaires. La fonction est appel´ee une seule fois, la formule de r´ecurrence est ici :
T(n) = 1×T(n−1) +α On obtient une suite arithm´etique de raison 1. Ainsi :
T(n) = O(n) Consid´erons maitenant le code suivant :
1 d e f h e r o n ( n , u ):
2 if n = = 0 : r e t u r n u
3 r e t u r n h e r o n ( n -1 , u )/2 + 1 / h e r o n ( n -1 , u )
Notonsαle nombre d’op´eration ´el´ementaires, la formule de r´ecurrence est ici : T(n) = 2×T(n−1) +α
Le facteur 2 provient du double appel de la fonction heron. On obtient une suite arithm´etico-g´eom´etrique de raison 2. Ainsi :
T(n) = O(2n) La complexit´e de la fonction ´ecrite est exponentielle !