Chapitre 2 : Récursivité⚓︎
Carnet Jupyter à télécharger ici
Le but de ce chapitre est d'introduire le concept de fonction récursive.
Notion de fonction récursive⚓︎
Il s'agit d'une fonction qui fait appel à elle-même lors de son exécution.
Premier exemple : calcul de la somme des entiers compris entre a
et b
⚓︎
On suppose que a
est inférieur à b
et on souhaite définir une fonction
somme
qui calcule la somme des entiers compris entre a
et b
.
Fonction somme
Détermine la somme des entiers compris entre a
et b
.
Entrées
a
: entierb
: entier supérieur ou égal àa
Sortie
total
: entier
Implémentation
Une première façon de faire est d'utiliser une boucle pour : on obtient une version itérative de la fonction.
1 2 3 4 5 |
|
Une autre façon de faire est de constater qu'il y a deux cas à envisager :
- Si
a == b
, cela signifie qu'il y a un seul nombre dans la liste des nombres à additionner : le nombrea
. On renvoie donc sa valeur. - Si
a < b
, on calcule récursivement la somme des entiers compris entrea+1
etb
, on y ajoute la valeur dea
et on renvoie le total.
1 2 3 4 5 6 |
|
Ainsi définie, la fonction est une fonction récursive parce
qu'elle s'appelle elle-même dans le cas où a
est différent de b
.
On distingue deux parties dans l'écriture d'une fonction récursive :
- un ou plusieurs cas résursif(s), dans lesquels la fonction fait appel à elle-même avec de nouveaux arguments,
- un ou plusieurs cas de base, qui permettent de mettre un terme aux appels récursifs successifs.
Deuxième exemple : calcul du produit des entiers compris entre 1 et n
⚓︎
On suppose que n
est un entier strictement positif et on souhaite définir
une fonction factorielle
qui calcule le produit des entiers compris entre
1 et n
.
Fonction factorielle
Détermine le produit des entiers compris entre 1 et n
.
Entrée
n
: entier strictement positif
Sortie
fac
: entier
Implémentation
1 2 3 4 5 |
|
Pour l'écriture de la fonction récursive, deux cas à sont envisager :
- Si
n == 1
, cela signifie qu'il y a un seul nombre dans la liste des nombres à multiplier : le nombre 1. On renvoie donc sa valeur. C'est le cas de base. - Si
n > 1
, on calcule récursivement le produit des entiers compris entre 1 etn-1
, on multiplie le résultat par la valeur den
et on renvoie le total. C'est le cas récursif.
1 2 3 4 5 6 |
|
Troisième exemple : calcul de x
puissance n
⚓︎
On suppose que x
est un nombre et que n
est un entier positif et on
souhaite définir une fonction puissance
qui calcule x
puissance n
.
Fonction puissance
Détermine la valeur de x
puissance n
.
Entrées
x
: entier ou flottantn
: entier positif
Sortie
val
: même type que le paramètre d'entréex
Implémentation
1 2 3 4 5 |
|
Pour l'écriture de la fonction récursive, deux cas à sont envisager :
- Si
n == 0
, on utilise la propriété \(x^0 = 1\) : on renvoie la valeur 1. C'est le cas de base. - Si
n > 0
, on utilise la propriété \(x^n = x \times x^{n-1}\) : on calcule récursivement \(x^{n-1}\), on multiplie le résultat par la valeur dex
et on renvoie le total. C'est le cas récursif.
1 2 3 4 5 |
|
Pile d'appels récursifs⚓︎
Si on effectue l'appel puissance(2, 3)
, on peut représenter la pile des quatre appels
de la fonction puissance
, et les paramètres correspondant à chaque appel, sous la forme d'un arbre.
1 2 3 4 5 6 7 8 9 |
|
Le nombre d'appels simultanés de fonctions est limité. On peut en connaître le nombre maximal
grâce à la fonction getrecursionlimit
du module sys
.
1 2 |
|
Une erreur apparaît si on essaie de réaliser plus d'appels récursifs que la limite autorisée.
1 |
|
La limite du nombre d'appels simultanés de fonctions peut être modifiée grâce à la fonction
setrecursionlimit
du module sys
.
1 2 |
|
Il faut néanmoins être raisonnable en cas de modification de cette limite, car un nombre excessif de récursions provoque le plantage du programme à cause d'une erreur de débordement de pile d'exécution (stack overflow).
Tours de Hanoï⚓︎
Les tours de Hanoï sont un jeu de réflexion consistant à déplacer des disques de diamètres différents d'une tour gauche à une tour droite en passant par une tour centrale, et ceci en un minimum de coups, tout en respectant les règles suivantes :
- on ne peut pas déplacer plus d'un disque à la fois,
- on ne peut placer un disque que sur un autre disque plus grand ou sur un emplacement vide.
Ce jeu est un exemple de problème qui peut être résolu par une approche récursive.
Procédure solution_hanoi
Affiche les mouvements à effectuer pour résoudre le problème des tours de Hanoï à n
disques.
Entrées
n
: entier positif (nombre de disques)depart
: chaîne de caractères (nom de la tour de départ)intermediaire
: chaîne de caractères (nom de la tour intermédiaire)arrivee
: chaîne de caractères (nom de la tour d'arrivée)
Effet de bord : affichage de texte à l'écran
Implémentation
1 2 3 4 5 |
|
Le cas de base est celui où il n'y a aucun disque : on ne fait rien du tout.
Pour déplacer n
disques de la tour depart
vers la tour arrivee
, on procède en trois temps :
- on déplace récursivement
n-1
disques de la tourdepart
vers la tourintermediaire
, - on déplace un disque (le plus grand) de la tour
depart
vers la tourarrivee
, - on déplace récursivement
n-1
disques de la tourintermediaire
vers la tourarrivee
.
L'appel hanoi(3, 'GAUCHE', 'CENTRE', 'DROITE')
entraîne les sept affichages suivants :
1 2 3 4 5 6 7 |
|
Ce qu'il faut savoir et savoir faire⚓︎
- Écrire une fonction récursive, en identifiant le(s) cas de base et le(s) cas récursif(s).
- Dessiner un arbre d'appels récursifs.
Exercices et activités⚓︎
Exercices
Activités
L'objectif de l'activité d'écrire des procédures récursives pour dessiner des figures géométriques avec le module turtle
.
Carnet Jupyter à télécharger ici
Corrigé disponible ici
L'exposition d'estampes de M. C. Escher est une lithographie de 1956 qui représente un homme dans une gallerie en train de regarder le dessin d'un port à l'intérieur duquel on apperçoit la gallerie où l'homme se trouve.