Académique Documents
Professionnel Documents
Culture Documents
1. Récursivité.
2. Paradigme
«
diviser
pour
régner
».
1. RÉCURSIVITÉ.
a. Principe.
b. Récursivité
versus
itéra/on.
c. Récursivité
croisée.
d. Récursivité
mul/ple.
e. Récursivité
imbriquée.
f. Exercice.
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
1.
Récursivité.
a.
Principe.
Défini&on
:
un
sous–programme
(procédure
ou
fonc/on)
est
dit
récursif
s’il
s’appelle
lui
même.
Idée
:
pour
effectuer
une
tâche
ou
un
calcul,
on
se
ramène
à
la
réalisa/on
d’une
tâche
similaire
mais
de
complexité
moindre.
On
recommence
jusqu’à
obtenir
une
tâche
élémentaire.
a.
Principe.
Exemple
classique
:
calcul
de
n!
=
1
x
2
x
3
x
…
x
n.
On
montre
facilement
la
rela/on
de
récurrence
n!
=
n
x
(n-‐1)!
Si
on
sait
calculer
(n-‐1)!,
on
connaîtra
donc
la
valeur
de
n!
Mais
(n-‐1)!
=
(n-‐1)
x
(n-‐2)!
On
est
donc
ramené
au
calcul
de
(n-‐2)!
Et
ainsi
de
suite
jusqu’à
1!
dont
on
connaît
la
valeur
:
1
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
1.
Récursivité.
a.
Principe.
Exemple
:
calcul
récursif
de
n!
def factorielleRecursive(n):
if n == 0 or n == 1:
return 1
else:
return n*factorielleRecursive(n-1)
a.
Principe.
Déroulement
du
programme
:
si
par
exemple
n
=
4
facto(1) = 1
a.
Principe.
Remarque
importante
:
• Il
est
indispensable
de
prévoir
une
condi/on
d’arrêt
à
la
récursion
sinon
le
programme
ne
se
termine
jamais.
a.
Principe.
Exemple
à
ne
pas
suivre
:
def factorielleRecursiveBadJob(n):
return n*factorielleRecursiveBadJob(n-1)
def factorielleIterative(n):
resultat = 1
for i in range(2,n+1):
resultat *= i
return resultat
• Elle
est
très
u/le
pour
concevoir
des
algorithmes
sur
des
structures
complexes
comme
les
listes,
les
arbres
et
les
graphes.
c.
Récursivité
croisée.
Récursivité
croisée
:
c’est
un
cas
bien
par/culier
de
récursivité
où
une
fonc/on
appelle
une
autre
fonc/on
qui
elle
même
appelle
la
première.
c.
Récursivité
croisée.
Exemple
:
test
de
la
parité
d’un
nombre
def pair(n):
if n == 0:
return True
else:
return impair(n-1)
def impair(n):
if n == 0:
return False
else:
return pair(n-1)
d.
Récursivité
mul&ple.
Récursivité
mul&ple
:
sous-‐programme
récursif
réalisant
plusieurs
appels
à
lui
même.
Exemple
:
calcul
des
coefficients
binomiaux.
1 si k = 0 ou si k = n
n
= n −1 n −1
k + sinon
k −1 k
d.
Récursivité
mul&ple.
Exemple
:
calcul
des
coefficients
binomiaux
def coeffs(n,k):
if k == 0 or k == n:
return 1
else:
return coeffs(n-1,k-1) + coeffs(n-1,k)
e.
Récursivité
imbriquée.
Récursivité
imbriquée
:
sous
programme
récursif
dont
l’appel
à
lui
même
con/ent
un
autre
appel
à
lui
même.
Exemple
:
fonc/on
91
de
McCarthy
définie
sur
Z
par
e.
Récursivité
imbriquée.
Exemple
:
fonc/on
91
de
McCarthy
def f91(n):
if n > 100:
return n-10
else:
return f91(f91(n+11))
f.
Exercice.
Exercice
:
écrire
de
deux
façons
(itéra/ve
et
récursive)
une
fonc/on
ayant
pour
paramètres
un
réel
x
et
un
en/er
n,
et
retournant
la
valeur
de
x
puissance
n.
f.
Exercice.
Solu&on
:
version
itéra/ve
def puissanceIterative(x,n):
resultat = 1
for i in range(1,n+1):
resultat *= x
return resultat
f.
Exercice.
Solu&on
:
version
récursive
def puissanceRecursive(x,n):
if n == 0:
return 1
else:
return x*puissanceRecursive(x,n-1)
a. Principe.
b. Exemple
1
:
calcul
du
maximum
d’une
liste.
c. Exemple
2
:
recherche
d’un
élément
dans
une
liste.
d. Exemple
3
:
algorithme
de
Karatsuba.
a.
Principe.
• Les
algorithmes
de
la
par/e
précédente
étaient
basés
pour
la
plupart
sur
la
simple
exploita/on
d’une
formule
de
récurrence.
a.
Principe.
Trois
étapes
:
① Diviser
:
on
divise
les
données
ini/ales
en
plusieurs
sous-‐
par/es.
a.
Principe.
• On
va
se
familiariser
avec
ce
principe
général
sur
plusieurs
exemples.
• La
recherche
de
ces
phases
se
fera
sur
des
exemples
lors
des
séances
Labs.
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
2.
Diviser
pour
régner.
• Résolu&on :
def maximum(l,d,f):
if d == f:
return l[d]
m = (d+f) // 2
x = maximum(l,d,m)
y = maximum(l,m+1,f)
return x if x > y else y
maListe = [38,-3, 2, 1, 7]
print(maximum(maListe,0,4))
• Résolu&on :
def recherche(l,x,d,f):
if d == f:
return l[d] == x
m = (d+f) // 2
return recherche(l,x,d,m) or
recherche(l,x,m+1,f)
maListe = [38,-3, 2, 1, 7]
print(recherche(maListe,7,0,4))
• La
liste
étant
triée,
il
est
facile
de
voir
dans
quelle
moi&é
peut
éventuellement
se
trouver
l’élément
cherché.
• Résolu&on :
def dicho(l,x,d,f):
if d > f:
return False
else:
m = (d+f) // 2
if l[m] == x:
return True
else:
if x < l[m]:
return dicho(l,x,d,m-1)
else:
return dicho(l,x,m+1,f)
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
2.
Diviser
pour
régner.
def dicho2(l,x):
if len(l) == 0:
return False
else:
m = (len(l)-1) // 2
if l[m] == x:
return True
else:
if x < l[m]:
return dicho2(l[:m],x)
else:
return dicho2(l[m+1:],x)
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
2.
Diviser
pour
régner.
• Exemple
:
recherche
de
l’élément
-‐4
dans
ce8e
liste,
il
faut
trois
comparaisons
pour
conclure
à
son
absence.
12 × 34 = (1×10 + 2) × (3×10 + 4)
= 3×10 2 + (1× 4 + 2 × 3) ×10 + 8
= 300 +100 + 8
= 408
• Et
là
on
s’aperçoit
qu’il
suffit
en
fait
de
réaliser
3
“pe/ts”
produits
contre
4
dans
la
méthode
usuelle.
• Ce
que
l’on
vient
de
faire
sur
des
nombres
à
2
chiffres
on
peut
bien
sûr
le
faire
sur
des
nombres
à
n
chiffres,
en
les
coupant
en
deux
par/es
de
n/2
chiffres.
©
SUPINFO
Interna/onal
University
–
h8p://www.supinfo.com
2.
Diviser
pour
régner.
a × d + b × c = ( a + b) × ( c + d ) − a × c − b × d
• Résolu&on :
def karatsuba(x,y):
if x < 10 or y < 10:
return x*y
m = max([len(str(x)),len(str(y))])
n = (m+1)//2
z = 10**n
a, b = x//z, x%z
c, d = y//z, y%z
u = karatsuba(a,c)
v = karatsuba(a+b,c+d)
w = karatsuba(b,d)
return u*(10**(2*n))+(v-u-w)*(10**n)+ w
Algorithmes de tri.