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

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

Embed Size (px)

Citation preview

Page 1: 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

Récursion

IFT1025: Programmation 2

Jian-Yun Nie

Page 2: 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

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

Page 3: 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

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é

Page 4: 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

Un exemple en Java

class Test

{ …

public int calcul(int val)

{

if (val<=0) return 0

else return val + calcul(val-1);

}

}

sinon ),1(

0 si ,0)(

valcalculval

valvalcalcul

Page 5: 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

Quelques fonctions mathématiques• Fibobacci

n: 0 1 2 3 4 5 6 7

Fibo(n): 1 1 2 3 5 8 13 21

• Une fonction de nature récursive– La valeur de fibo(n) dépend de fibo(n-1) et fibo(n-2)

1 ),2()1(

1 ,1

0 ,1

)(

nnfibonfibo

n

n

nfibo

Page 6: 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

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

1 ),2()1(

1 ,1

0 ,1

)(

nnfibonfibo

n

n

nfiboCas simples

Cas récursif

Page 7: 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

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

Page 8: 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

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)

Page 9: 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

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

Page 10: 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

Mauvais exemples

• Sans une bonne condition d’arrêt:

• Une mauvaise décomposition

1 ),2()1(

)(

nnfibonfibo

nfibo

1 ),1()(

1 ,1

0 ,1

)(

nnfibonfonct

n

n

nfonct

1 ),2()1(

1 ,1

)(

nnfibonfibo

nnfibo

1 ),1()1(

1 ,1

0 ,1

)(

nnfibonfonct

n

n

nfonct

Page 11: 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

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

Page 12: 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

Exécutionfibo(4)

fibo(3) fibo(2)

fibo(2) fibo(1) fibo(1) fibo(0)

1 1 1

fibo(1) fibo(0)

1 1

Page 13: 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

Exécutionfibo(4)?

fibo(3)? fibo(2)?

fibo(2)? fibo(1)? fibo(0)?fibo(1)?

fibo(0)?fibo(1)?

1 1

3

1

5

2

2

11

Page 14: 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

Fonction transformable en récursive

• Factoriel

n: 1 2 3 4 5 6

Fac(n): 1 2 6 24 120 720

• Somme:

1 ),1(*

1 ,1)(

nnfacn

nnfac

n

i

infac1

)(

1 ),1(

1 ,1)(

nnsommen

nnsomme

n

i

insomme1

)(

Page 15: 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

En Javapublic 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 1else return n*fact(n-1);

}

public double somme(int n){

if n=1 return 1else return n+somme(n-1);

}

Page 16: 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

Un autre exempletraverser 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

Page 17: 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

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 tableauint [ ] tableau;

traverser(0, tableau);

Page 18: 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

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 tableauint [] tableau = new int [ 10 ];for( int i = 0; i < 10; ++i ) tableau[ i ] = i;

croissant( 0, tableau );decroissant( 0, tableau );

}}

Page 19: 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

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)

Page 20: 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

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 tableauint [] tableau = new int [ 10 ];for( int i = 0; i < 10; ++i ) tableau[ i ] = i;

parcours( tableau ); }}

Page 21: 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

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

Page 22: 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

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.

Page 23: 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

Situations typique

• Libérer le dessus

• Déplacer le dernier

• Déplacer les autres

Page 24: 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

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

Page 25: 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

Illustration

       

                                                              

                                                                                      

       

                                                              

                                                                                      

Illustration

Page 26: 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
Page 27: 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

Une vue plus synthétiqueDéplacer 2 premier de A à B

Déplacer 2 de B à A

Page 28: 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

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)