La présentation est en train de télécharger. S'il vous plaît, attendez

La présentation est en train de télécharger. S'il vous plaît, attendez

Récursion IFT1025: Programmation 2 Jian-Yun Nie. Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion.

Présentations similaires


Présentation au sujet: "Récursion IFT1025: Programmation 2 Jian-Yun Nie. Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion."— Transcription de la présentation:

1 Récursion IFT1025: Programmation 2 Jian-Yun Nie

2 Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion de « ancêtre » Les parents sont des ancêtres Les ancêtres des parents sont des ancêtres –Définition de « ami » Les gens directement autour de moi sont des amis Les amis de mes amis sont mes amis

3 Pourquoi récursion Certains problèmes en informatiques sont de nature récursive –Ne peuvent pas être résolus sans récursion –E.g. ancêtre et ami Certains problèmes peuvent être formulés de façon plus concise et claire avec récursivité

4 Un exemple en Java class Test { … public int calcul(int val) { if (val<=0) return 0 else return val + calcul(val-1); }

5 Quelques fonctions mathématiques Fibobacci n: 01234567 Fibo(n): 1123581321 Une fonction de nature récursive –La valeur de fibo(n) dépend de fibo(n-1) et fibo(n-2)

6 Définition d’une fonction récursive Cas simple –Problème directement résoluble –Pas de récursion Cas récursif (cas complexe) –Appel à la même fonction –Pour des cas plus simples n-1, n-2 sont plus simples que n Cas simples Cas récursif

7 Forme d’une méthode récursive Méthode pour un problème n –Si n est directement résoluble, retourner une réponse ou faire un traitement direct –Sinon (cas récursif) 1.Décomposer le problème n en des sous problèmes moins complexes: n1, n2, … 2.Appel à Méthode pour traiter n1, n2, … 3.Utiliser les résultats pour n1, n2, … pour composer un résultat pour n

8 Exemple fibonacci Fibo(n) –Si n=0 ou n=1: cas simple Retourner le résultat = 1 –Si non (n>1): cas complexe Décomposer le problème en deux parties –n-1 et n-2 –Appel a la méthode pour les traiter: fibo(n-1), fibo(n-2) –Composer le résultat pour n: fibo(n-1)+fibo(n-2)

9 Importants pour réussir la récursion Bien définir le cas simple –Pour arrêter la récursion –Sinon, récursion à l’infinie Bien décomposer le problème –En sous-problèmes plus simples –Si les sous-problèmes sont aussi complexes: récursion à l’infinie

10 Mauvais exemples Sans une bonne condition d’arrêt: Une mauvaise décomposition

11 En Java public double fibo(int n) { if n<=1 return 1 else return fibo(n-1)+fibo(n-2); } Attention: à chaque récursion, on teste d’abord pour traiter le cas simple en premier

12 Exécution fibo(4) fibo(3)fibo(2) fibo(2)fibo(1)fibo(1)fibo(0) 1 1 1 fibo(1)fibo(0) 1

13 Exécution fibo(4)? fibo(3)? fibo(2)? fibo(1)?fibo(0)?fibo(1)? fibo(0)?fibo(1)? 11 3 1 5 2 2 11

14 Fonction transformable en récursive Factoriel n: 123456 Fac(n):12624120720 Somme:

15 En Java public double fact(int n) { int i; double f=1; for (i=1; i<=n; i++) f = f*n; return f; } public double somme(int n) { int i; double f=0; for (i=1; i<=n; i++) f = f+n; return f; } public double fact(int n) { if n=1 return 1 else return n*fact(n-1); } public double somme(int n) { if n=1 return 1 else return n+somme(n-1); }

16 Un autre exemple traverser un tableau Problème initial: traverser le tableau à partir de l’indexe 0 (jusqu’à la fin) Le problème est décomposable ? –Pour traverser à partir de l’indexe i Traverser l’élément courant i Traverser le reste du tableau – à partir de i+1 –Attention: condition d’arrêt! Traverser le reste – à partir de i+1 si il en reste

17 Traverser Structure d’une méthode –traverser(i, tableau) Traiter i Si non à la fin du tab, traverser(i+1, tableau) Appel pour traverser complètement un tableau int [ ] tableau; traverser(0, tableau);

18 import java.io.*; //------------------------------------------------------ class Parcours { //--------------------------------------------------- static void croissant( int index, int [] tableau ) { if( ( null != tableau ) && ( index >= 0 ) && ( index < tableau.length ) ) { System.out.println( tableau[index]); croissant( index + 1, tableau ); } //------------------------------------------------------------ static void decroissant( int index, int [] tableau ) { if( ( null != tableau ) && ( index >= 0 ) && ( index < tableau.length ) ) { decroissant( index + 1, tableau ); System.out.println( tableau[ index ] ); } //------------------------------------------------------------ public static void main( String [] args ) { // initialiser le tableau int [] tableau = new int [ 10 ]; for( int i = 0; i < 10; ++i ) tableau[ i ] = i; croissant( 0, tableau ); decroissant( 0, tableau ); }

19 Utiliser d’une méthode utilitaire Quand on appelle une méthode pour parcourir complètement un tableau, on ne devrait pas avoir besoin de spécifier l’index du début (0). –Appel normal: parcours(tab) Solution: –Une méthode à être appelée de l’extérieur : parcours(tableau) –Une autre méthode utilitaire qui utilise un index dans ses paramètres afin de faire la récursion : parcours_help(i, tableau) –parcours(tableau) appelle parcours_help(0, tableau)

20 import java.io.*; //------------------------------------------------------ class Parcours { // parcours_help est identique à croissant static void parcours_help( int index, int [] tableau ) { if( ( null != tableau ) && ( index >= 0 ) && ( index < tableau.length ) ) { System.out.println( tableau[index]); croissant( index + 1, tableau ); } //------------------------------------------------------------ static void parcours (int [] tableau ) { parcours_help(0, tableau); } //------------------------------------------------------------ public static void main( String [] args ) { // initialiser le tableau int [] tableau = new int [ 10 ]; for( int i = 0; i < 10; ++i ) tableau[ i ] = i; parcours( tableau ); }

21 Un problème plus complexe Tours de Hanoi: Problème: déplacer les n disques d’une tour à un autre Contraintes –Déplacer un disque à la fois –Plus gros disque jamais sur de plus petits

22 Origine Une légende raconte qu’un groupe de moines, gardien des trois tours, doivent déplacer 64 anneaux d’or d’une tour à une autre en respectant la règle unique qui stipule qu’un anneau ne doit pas reposer sur un anneau plus petit. Lorsque les moines auront déplacé les 64 anneaux, le monde se détruira.

23 Situations typique Libérer le dessus Déplacer le dernier Déplacer les autres

24 Décomposition Déplacer n disque de tour 1 à 3 –Si n=1: déplacer le disque directement Cas simple, condition d’arrêt de récursion –Sinon Déplacer n-1 disque de 1 à 2 –Problème moins complexe Déplacer 1 disque de 1 à 3 –Problème résoluble directement Déplacer n-1 disque de 2 à 3 –Problème moins complexe

25 Illustration Illustration

26

27 Une vue plus synthétique Déplacer 2 premier de A à B Déplacer 2 de B à A

28 En Java Stocker n disques dans un tableau de int Utiliser int pour désigner la grandeur de disque E.g.: –tour[1] = {4,3,2,1}; –Mieux: le générer automatiquement Supposons 3 tours: tour[1], tour[2], tour[3] public void deplacer(n,i,j): déplacer n disque de tour i à tour j –Si n=1: mettre un disque de tour[i] à tour[j] –Sinon: deplacer(n-1,i,6-i-j) deplacer(1,i,j) deplacer(n-1,6-i-j,j) Utilisation (Test) –Générer 3 tours –Appeler déplacer (Lab)


Télécharger ppt "Récursion IFT1025: Programmation 2 Jian-Yun Nie. Définition Le fait pour un programme ou une méthode de s'appeler lui-même. Par exemple –Définir la notion."

Présentations similaires


Annonces Google