13.07.2015 Views

Algorithmes récursifs - Licence 1 MASS - Introduction ... - LISIC

Algorithmes récursifs - Licence 1 MASS - Introduction ... - LISIC

Algorithmes récursifs - Licence 1 MASS - Introduction ... - LISIC

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>Algorithmes</strong> récursifs<strong>Licence</strong> 1 <strong>MASS</strong> - <strong>Introduction</strong> programmation JAVASébastien Verelverel@i3s.unice.frwww.i3s.unice.fr/∼verelÉquipe ScoBi - Université de Nice Sophia-Antipolis2 avril 2012


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéObjectifs de la séance 10Ecrire un algorithme récursif avec un seul testEtablir le lien entre dénition par récurrence et algorithmerécursifRecherche dichotomique d'un élément dans un tableauQuestion principale du jour :Comment écrire ce que l'on ne connait pas encore ?Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéPlan1 <strong>Algorithmes</strong> récursifsExemplesDénition<strong>Algorithmes</strong> classiques2 Résolution de problèmes par récursivitéSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemple du calcul du pgcdExemplesDénition<strong>Algorithmes</strong> classiquesAlgorithme PGCD(a, b : entier) : entierdébutsi b = 0 alorsretourner asinonc ← a modulo bretourner PGCD(b, c)n sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesExécution de l'algorithmePour a = 70 et b = 4621. PGCD(70, 462)2. b ≠ 05. c = 706. PGCD(462, 70)2. b ≠ 05. c = 426. PGCD(70, 42)2. b ≠ 05. c = 286. PGCD(42, 28)2. b ≠ 05. c = 14Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesExécution de l'algorithmePour a = 462 et b = 706. PGCD(28, 14)2. b ≠ 05. c = 06. PGCD(14, 0)2. b = 03. PGCD = 14Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéElements de l'algorithmeExemplesDénition<strong>Algorithmes</strong> classiquesBase : initialisation de la récurrencesi b = 0 alorsretourner asinon...n siHérédité : calcul à partir de paramètres plus "petits"si b = 0 alors...sinon...retourner PGCD(b, c)n sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesDénition (informelle)<strong>Algorithmes</strong> récursifsUn algorithme récursif est un algorithme qui fait appel à lui-mêmedans le corps de sa propre dénition.Il existe deux types d'algorithmes récursifs :les algorithmes récursifs qui se terminent :au bout d'un nombre ni d'opérations, l'algorithme s'arrête.les algorithmes récursifs qui ne se terminent pas :on peut imaginer que l'algorithme continue "éternellement" decalculer.Sébastien Verel<strong>Algorithmes</strong> récursifs


Exemples<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesAlgorithme suiteU(n : entier) : réeldébutsi n = 0 alorsretourner 2sinonretourner 1 suiteV(n − 1) + 22n sinsuiteU n'est pas un algorithme résursifSébastien Verel<strong>Algorithmes</strong> récursifs


Exemples<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesAlgorithme suiteV(n : entier) : réeldébutsi n = 0 alorsretourner 2sinonretourner 1 suiteV(n-1) +22n sinsuiteV est un algorithme résursif qui se termineSébastien Verel<strong>Algorithmes</strong> récursifs


Exemples<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesAlgorithme suiteW(n : entier) : réeldébutsi n = 0 alorsretourner 2sinonretourner 1 suiteW(n-3)+22n sinsuiteW(n) est un algorithme résursif :si n est un multiple de 3, suiteW se terminesinon suiteW ne se termine pasSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemple d'exécutionCalcul de la puissanceExemplesDénition<strong>Algorithmes</strong> classiquesDénition mathématique :{ 1, sia n n = 0=a n−1 .a, sinonAlgorithme puissance(a : réel, n : entier) : réeldébutsi n = 0 alorsretourner 1sinonretourner puissance(a, n-1) * an sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesExemple d'exécutionCalcul de la puissanceCalcul de (2.5) 3 : a = 2.5 et n = 3.1. puissance(2.5, 3)2. > puissance(2.5, 2)3. -> puissance(2.5, 1)4. -> puissance(2.5, 0) = 15. -> puissance(2.5, 1) = 1 * 2.5 = 2.56. > puissance(2.5, 2) = 2.5 * 2.5 = 6.257. puissance(2.5, 3) = 6.25 * 2.5 = 15.625Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesPrincipe d'exécution0 1........N3 N2 N1 Nen rouge : parcours "aller"en bleu : parcours "retour"Sébastien Verel<strong>Algorithmes</strong> récursifs


En Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiques/*************************************** calcul de la puissance d'un nombre** entrée :* - a : nombre* - n : puissance** sortie :* - a^n***************************************/double puissance(double a, int n) {if (n == 0)return 1;elsereturn puissance(a, n-1) * a;}Sébastien Verel<strong>Algorithmes</strong> récursifs


PGCD en Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiques/*************************************** calcul du pgcd de a et b** entrée :* - a, b : nombres entiers** sortie :* - pgcd(a, b)***************************************/int pgcd(int a, int b) {if (b == 0)return a;elsereturn pgcd(b, a % b);}Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesIntérêtsbien adapté à la résolution de certains problèmes (et passeulement mathématiques !)algorithmes souvent moins "laborieux" à écrire :moins de variables, beaucoups moins de boucles.une résolution par algorithme récursif nécessite souvent deprendre du recul pour résoudre le problème (avantage !)Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéA ne pas oublier !ExemplesDénition<strong>Algorithmes</strong> classiquesHérédité : calcul à partir de paramètres plus "petits"si b = 0 alors...sinon...retourner PGCD(b, b mod a)n sin0 1........N3 N2 N1 NSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéA ne pas oublier !ExemplesDénition<strong>Algorithmes</strong> classiquesBase : initialisation de la récurrencesi b = 0 alorsretourner asinon...n si0 1........N3 N2 N1 NSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesParallèle entre principe de récurrence et algorithme récursifdénition mathématique par récurrencetrès prochedénition d'un algorithme récursif (cf. puissance)Modes de calcul proches :a 3 = a.a 2 = a.a.a 1 = a.a.aSouvent, dénition mathématique valide lorsque algorithme récursifassocié se termine.Sébastien Verel<strong>Algorithmes</strong> récursifs


A méditerCalcul de la puissance<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesAlgorithme puissanceTerminale(a : réel, n : entier, acc : réel) :réeldébutsi n = 0 alorsretourner accsinonretourner puissanceTerminale(a, n − 1, acc ∗ a)n sinComment s'exécute cet algorithme ? puissanceTerminale(2.5, 3, 1)récursivité terminale : équivalent à une itérationSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéCalcul de la factorielleExemplesDénition<strong>Algorithmes</strong> classiquesFactorielle{ 1, si n = 0n! =n.(n − 1)!, sinonAlgorithme factorielle(n : entier) : entierdébutsi n = 0 alorsretourner 1sinonretourner n * factorielle(n-1)n sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesExécution de l'algorithmeCalcul de 3!.1. factorielle(3) = 3 * factorielle(2)2. > factorielle(2) = 2 * factorielle(1)3. -> factorielle(1) = 1 * factorielle(0)4. -> factorielle(0) = 15. -> factorielle(1) = 1 * 1 = 16. > factorielle(2) = 2 * 1 = 27. factorielle(3) = 3 * 2 = 6Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesRecherche dichotomiqueRecherche d'une dénition dans un dictionnaireAlgorithme rechercheDicho(cible : mot) : liste de motdébutpremier ← premier mot du dictionnairedernier ← dernier mot du dictionnaireLire le mot médian entre premier et derniertant que mot lu n'est pas le mot cible fairesi mot cible est avant le mot lu alorsdernier ← mot lusinonpremier ← mot lun siLire le mot médian entre premier et derniern tant queretourner dénition du mot lunSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesRecherche dichotomique : récursiveRecherche de l'existence d'un mot dans un dictionnaireAlgorithme recherche(m : mot, l : liste) : booléendébutvariable lu : motlu ← median(l)si lu = m alorsretourner Vraisinonsi lu < m alorsretourner recherche(m, liste à droite de lu)sinonretourner recherche(m, liste à gauche de lu)n sin sin−→ Incomplet (jamais Faux) ! !Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesRecherche dichotomique : récursiveRecherche de l'existence d'un mot dans un dictionnaireAlgorithme recherche(m : mot, l : liste) : booleendébutvariable lu : motsi l est vide alorsretourner Fauxsinonlu ← median(l)si lu = m alorsretourner Vraisinonsi lu < m alorsretourner recherche(m, liste à droite de lu)sinonretourner recherche(m, liste à gauche de lu)n sin sin sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesRecherche dichotomiqueRecherche dans un tableau de nombres entiers ordonnésAlgorithme recherche(x : entier, t : tableau d'entiers, a : entier, b : entier) :booléendébutvariablec : entiersi a > b alorsretourner Fauxsinonc ← (a + b)/2si t[c] = x alorsretourner Vraisinonsi t[c] < x alorsretourner recherche(x, t, c+1, b)sinonretourner recherche(x, t, a, c-1)n sin sin sin Sébastien Verel <strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExécution de l'algorithmeExemplesDénition<strong>Algorithmes</strong> classiquest : 2 5 6 8 11 15 201. recherche(6, t, 0, 6)1. c = 31. t[3] > 62. > recherche(6, t, 0, 2)2. c = 12. t[1] < 63. -> recherche(6, t, 2, 2)3. c = 23. t[2] = 63. -> recherche(6, t, 2, 2) = Vrai4. > recherche(6, t, 0, 2) = Vrai5. recherche(6, t, 0, 6) = VraiSébastien Verel<strong>Algorithmes</strong> récursifs


En Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiques/*************************************** recherche du nombre x dans le tableau entre les bornes a et** entrée :* - x : nombre à rechercher* - tab : tableau de recherche* - a, b :borne de la recherche** sortie :* - vrai ssi le nombre est dans le tableau***************************************/boolean recherche(int x, int [] t, int a, int b) {if (a > b)return false;else {int c = (a + b) / 2;if (t[c] == x)return true;elseSébastien Verel<strong>Algorithmes</strong> récursifs


En Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExemplesDénition<strong>Algorithmes</strong> classiquesboolean recherche(int x, int [] t, int a, int b) {if (a > b)return false;else {int c = (a + b) / 2;if (t[c] == x)return true;elseif (t[c] < x)return recherche(x, t, c + 1, b);elsereturn recherche(x, t, a, c - 1);}}Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéQuand utiliser un algorithme récursif ?Est-ce que le problème dépend d'un (ou plusieurs)paramètre(s) ?Est-il possible de résoudre le problème lorsque la (les) valeur(s)du paramètre est "petite(s)" ?Est-il possible de résoudre le problème à l'aide de la résolutiondu problème portant sur une (des) "plus petite(s)" valeur(s)du paramètre ?Si oui, oui, ouialors la résolution par un algorithme récursif est à envisager.Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéTours de Hanoï (Édouard Lucas 1842 - 1891)Le problème des tours de Hanoï consiste à déplacer N disques dediamètres diérents d'une tour de départ à une tour d'arrivée enpassant par une tour intermédiaire et ceci en un minimum decoups, 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 grandque lui ou sur un emplacement vide.Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéComment résoudre ce problème ?Est-ce que le problème dépend d'un (ou plusieurs)paramètre(s) ?−→ Oui le nombre de disques.Est-il possible de résoudre le problème lorsque la (les) valeur(s)du paramètre est "petite(s)" ?−→ Oui lorsque le nombre de disque est 1.Est-il possible de résoudre le problème à l'aide de la résolutiondu problème portant sur une (des) "plus petite(s)" valeur(s)du paramètre ?−→ Oui...Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéAlgorithme récursifAlgorithme hanoi(n : entier, A : caractère, B : caractère, C :caractère ) : riendébutsi n = 1 alorsécrire("déplacer ", A, " vers ", C)sinonhanoi(n-1, A, C, B) ;écrire("déplacer ", A, " vers ", C)hanoi(n-1, B, A, C) ;n sinSébastien Verel<strong>Algorithmes</strong> récursifs


En Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivité/*************************************** résolution des tours de Hanoi** entrée :* - n : nombre de disques du problème* - A : pic initial* - B : pic intermédiaire* - C : pic final** sortie :* - aucune***************************************/void hanoi(int n, char A, char B, char C) {if (n == 1)println("déplacer " + A + " vers " + C);else {hanoi(n-1, A, C, B);println("déplacer " + A + " vers " + C);hanoi(n-1, B, A, C);Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExécution de l'algorithmeHanoi(2, 'a', 'b', 'c')Hanoi(3, 'a', 'b', 'c')Hanoi(4, 'a', 'b', 'c')Quel est le nombre de déplacements en fonction de n ?Pour tout entier n ≥ 1, C n = 2 n − 1. A démontrer par récurrence...Pour n = 64, les moines d'Hanoi y sont encore...Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéTemps de diusionCalculer T a (n) = a + 2a + 3a + . . . + n.aEst-ce que le problème dépend d'un (ou plusieurs)paramètre(s) ?−→ Oui n.Est-il possible de résoudre le problème lorsque la (les) valeur(s)du paramètre est "petite(s)" ?−→ Oui pour n = 0 ou n = 1Est-il possible de résoudre le problème à l'aide de la résolutiondu problème portant sur une (des) "plus petite(s)" valeur(s)du paramètre ?−→ Oui, T a (n) = T a (n − 1) + n.aSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéTemps de diusionAlgorithmeAlgorithme diusion(a : réel, n : entier) : réeldébutsi n = 0 alorsretourner 0sinonretourner diusion(a, n-1) +n.an sinSébastien Verel<strong>Algorithmes</strong> récursifs


En Java<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivité/*************************************** calcul du temps de diffusion** entrée :* - n : nombre de particule à diffuser* - a : temps pour diffusion 1 particule sur le bord** sortie :* - temps total***************************************/float diffusion(float a, int n) {if (n == 0)return 0;elsereturn diffusion(a, n-1) + a * n;}Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéExécution de l'algorithmeCalcul de T 4 (3)1. diusion(4, 3)2. > diusion(4, 2)3. -> diusion(4, 1)4. -> diusion(4, 0) = 05. -> diusion(4, 1) = 0 + 4 = 46. > diusion(4, 2) = 4 + 2.4 = 127. diusion(4, 3) = 12 + 3.4 = 24Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéRégionnement du planEtant donné un nombre n de droites, calculer le nombre R nmaximum de régions du plan obtenusEst-ce que le problème dépend d'un (ou plusieurs)paramètre(s) ?−→ Oui le nombre n de droites.Est-il possible de résoudre le problème lorsque la (les) valeur(s)du paramètre est "petite(s)" ?−→ Oui pour n = 0 ou n = 1Est-il possible de résoudre le problème à l'aide de la résolutiondu problème portant sur une (des) "plus petite(s)" valeur(s)du paramètre ?−→ Oui, en comptant le nombre régions ajoutées lorsqu'onajoute une droite à n − 1 droites : une région supplémentairepar droite coupée, plus une dernière région.Sébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéRégionnement du planAlgorithmeAlgorithme region(n : entier) : entierdébutsi n = 0 alorsretourner 1sinonretourner region(n-1) +nn sinSébastien Verel<strong>Algorithmes</strong> récursifs


<strong>Algorithmes</strong> récursifsRésolution de problèmes par récursivitéObjectifs de la séance 10Ecrire un algorithme récursif avec un seul testEtablir le lien entre preuve par récurrence et algorithme récursifRecherche dichotomique d'un élément dans un tableauQuestion principale du jour :Comment écrire ce que l'on ne connait pas encore ?Sébastien Verel<strong>Algorithmes</strong> récursifs

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!