récursivité · desbricoles récursivité complexité références exponentiation(pas)rapide a13 =...

Post on 10-Mar-2021

1 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

Des bricoles Récursivité Complexité Références

Récursivité

Émeric Tourniaire

10 décembre 2019

Des bricoles Récursivité Complexité Références

Exponentiation (pas) rapide

a13 = a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a ˆ a

def pow(a, b):res = 1for i in range(b):

res = res*areturn res

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 a

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 aa4 3 a

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 aa4 3 aa8 1 a5

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 aa4 3 aa8 1 a5a16 0 a13

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 aa4 3 aa8 1 a5a16 0 a13

Invariant : res ˆ accb

Des bricoles Récursivité Complexité Références

Exponentiation rapide

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

accn bn resn

a 13 1a2 6 aa4 3 aa8 1 a5a16 0 a13

Invariant : res ˆ accb

Optimal ?

Des bricoles Récursivité Complexité Références

Non.

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

accn bn resn

a 13 1a2 6 aa4 3 aa8 1 a5a16 0 a13

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

accn bn resn

a 13 1 1a2 6 a 0a4 3 a 1a8 1 a5 1a16 0 a13

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

accn bn resn

a 13 1 2a2 6 a 1a4 3 a 2a8 1 a5 1

0 a13

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)

‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

accn bn resn

a 13 1 2a2 6 a 1a4 3 a 2a8 1 a5 1

0 a13

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

Des bricoles Récursivité Complexité Références

Non.

‚ b en binaire.13 = 8 + 4 + 1 = Ę1101

2

‚ l(n) = tlg(n)u + ν(n)‚ a13 = a ˆ a4 ˆ a8

‚ a15 = a ˆ a2 ˆ a4 ˆ a83 + 3 = 6 multiplications.

‚ a15 = (a3)5 y = a3 = a ˆ a ˆ ay5 = (y ˆ y)2 ˆ y2 + 3 = 5 multiplications.

Des bricoles Récursivité Complexité Références

Non.

Several authors have published statements (without proof) thatthe binary method actually gives the minimum possible number ofmultiplications. But that is not true.

(D. E. Knuth, AoCP, V. 2, ed 3, 4.6.3)

Des bricoles Récursivité Complexité Références

Non.

Several authors have published statements (without proof) thatthe binary method actually gives the minimum possible number ofmultiplications. But that is not true.

(D. E. Knuth, AoCP, V. 2, ed 3, 4.6.3)

Des bricoles Récursivité Complexité Références

Non.

‚ La méthode de factorisation est meilleure.

Faux (exemple, a33)

‚ l(2n) = l(n) + 1

Faux (exemple, l(191) = l(382) = 11)

Des bricoles Récursivité Complexité Références

Non.

‚ La méthode de factorisation est meilleure.Faux (exemple, a33)

‚ l(2n) = l(n) + 1

Faux (exemple, l(191) = l(382) = 11)

Des bricoles Récursivité Complexité Références

Non.

‚ La méthode de factorisation est meilleure.Faux (exemple, a33)

‚ l(2n) = l(n) + 1Faux (exemple, l(191) = l(382) = 11)

Des bricoles Récursivité Complexité Références

Méthode du paysan russe

def mult(a, b):acc = ares = 0while b>0:

if b%2 == 1:res = res+acc

acc = acc+accb = b//2

return res

Des bricoles Récursivité Complexité Références

Deux exemples simples

def f(x):return x*x

for i in range (10):print(f(i))

Des bricoles Récursivité Complexité Références

Deux exemples simples

def f(x):a = x+1return a

a = 12b = f(a)print(a, b)

Des bricoles Récursivité Complexité Références

Flot du programme

__main__

a = 12

b = f(a)

print(a, b)

A

f()

def f(x):a = x+1return a

Des bricoles Récursivité Complexité Références

Flot du programme

__main__

a = 12

b = f(a)

print(a, b)

A

f()

def f(x):a = x+1return a

Des bricoles Récursivité Complexité Références

Fonctions en cascade

def fonction(i):def f(x):

return x+ireturn f

li = [fonction(i) for i in range (10)]

Des bricoles Récursivité Complexité Références

Fonctions en cascade

def fonction(i):def f(x):

return x+ireturn f

li = [fonction(i) for i in range (10)]

Des bricoles Récursivité Complexité Références

Fonctions en cascade

def fonction(i):if i == 0:

return identitedef f(x):

return li[i´1](x)+1return f

li = [fonction(i) for i in range (1000)]

li [0](5) ? li [500](5) ? li [1000](1) ?

Des bricoles Récursivité Complexité Références

Pile de contextes

li[10]

A

li[9]

B

li[8]

APile de

contextes

B…

Des bricoles Récursivité Complexité Références

Pile de contextes

li[10]

A

li[9]

B

li[8]

APile de

contextes

B…

Des bricoles Récursivité Complexité Références

Pile de contextes

li[10]

A

li[9]

B

li[8]

APile de

contextes

B

Des bricoles Récursivité Complexité Références

Pile de contextes

li[10]

A

li[9]

B

li[8]

APile de

contextes

B…

Des bricoles Récursivité Complexité Références

Définition de la récursivité

Des bricoles Récursivité Complexité Références

Définition de la récursivité

DéfinitionUne fonction est récursive si elle s’appelle elle-même

Des bricoles Récursivité Complexité Références

Définition de la récursivité

Définition bisUne fonction est récursive si elle s’appelle elle-même mais c’estmieux si elle termine (attention aux conditions initiales !).

Des bricoles Récursivité Complexité Références

Définition de la récursivité

PropriétéPour bien comprendre la récursivité, il faut bien comprendre larécursivité.

Des bricoles Récursivité Complexité Références

Définition de la récursivité

def ping ():print("Ping")pong()

def pong ():print("Pong")ping()

Des bricoles Récursivité Complexité Références

Suites récurrences

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

Des bricoles Récursivité Complexité Références

Suites récurrences

def pow(a, b):acc = ares = 1while b > 0:

if b%2 == 1:res = res*acc

acc = acc*accb = b//2

return res

‚ bn+1 = bn//2

‚ accn+1 = acc2n

#

resn+1 = resn

resn+1 = resn ˆ accn

Des bricoles Récursivité Complexité Références

Suites récurrences

def pow(a, b, res =1):if b == 0:

return resif b%2 == 1:

return pow(a*a, b//2, res*a)else:

return pow(a*a, b//2, res)

‚ bn+1 = bn//2

‚ accn+1 = acc2n

#

resn+1 = resn

resn+1 = resn ˆ accn

Des bricoles Récursivité Complexité Références

Suites récurrences

def pow(a, b):if b == 0:

return 1if b%2 == 1:

return a*pow(a*a, b//2)else:

return pow(a*a, b//2)

‚ bn+1 = bn//2

‚ accn+1 = acc2n

#

resn+1 = resn

resn+1 = resn ˆ accn

Des bricoles Récursivité Complexité Références

Décoration de fonctions

‚ Trace de la fonction‚ Lisibilité‚ Décorateur

def pow(a, b):if b == 0:

return 1if b%2 == 1:

return a*pow(a*a, b//2)else:

return pow(a*a, b//2)

Des bricoles Récursivité Complexité Références

Décoration de fonctions

‚ Trace de la fonction‚ Lisibilité‚ Décorateur

def pow(a, b):print(a, b)if b == 0:

return 1if b%2 == 1:

return a*pow(a*a, b//2)else:

return pow(a*a, b//2)

Des bricoles Récursivité Complexité Références

Décoration de fonctions

In: pow(3,15)3 159 781 36561 143046721 0Out: 14348907

def pow(a, b):print(a, b)if b == 0:

return 1if b%2 == 1:

return a*pow(a*a, b//2)else:

return pow(a*a, b//2)

Des bricoles Récursivité Complexité Références

Décoration de fonctions

‚ Trace de la fonction‚ Lisibilité‚ Décorateur

def madecoration(func):def wrapper(args):# Des trucsfunc(args)# D'autres trucs

return wrapper

func = madecoration(func)

Des bricoles Récursivité Complexité Références

Décoration de fonctions

def trace(func):def wrapper(*args):

print("␣"* wrapper.space , end="")print('{}␣<´␣{}'. format(func.__name__ , args))wrapper.space += 1val = func(*args)wrapper.space ´= 1print("␣"* wrapper.space , end="")print('{}␣´>␣{}'. format(func.__name__ , val))return val

wrapper.space=0return wrapper

@tracedef pow(a, b):

...

Des bricoles Récursivité Complexité Références

Décoration de fonctions

def pow(a, b):if b == 0:

return 1if b%2 == 1:

return a*pow(a*a, b//2)else:

return pow(a*a, b//2)

In: pow(2,13)pow <´ (2, 13)

pow <´ (4, 6)pow <´ (16, 3)

pow <´ (256, 1)pow <´ (65536 , 0)pow ´> 1

pow ´> 256pow ´> 4096

pow ´> 4096pow ´> 8192Out: 8192

Des bricoles Récursivité Complexité Références

Décoration de fonctions

def pow(a, b, res =1):if b == 0:

return resif b%2 == 1:

return pow(a*a, b//2, res*a)else:

return pow(a*a, b//2, res)

In: pow(2,13)pow <´ (2, 13)

pow <´ (4, 6, 2)pow <´ (16, 3, 2)

pow <´ (256, 1, 32)pow <´ (65536 , 0, 8192)pow ´> 8192

pow ´> 8192pow ´> 8192

pow ´> 8192pow ´> 8192Out: 8192

Des bricoles Récursivité Complexité Références

Décoration de fonctions

Guido Van RossumI don’t believe in recursion as the basis of all programming. This isa fundamental belief of certain computer scientists, especially thosewho love Scheme and like to teach programming by starting with a”cons” cell and recursion. But to me, seeing recursion as the basisof everything else is just a nice theoretical approach to fundamentalmathematics (turtles all the way down), not a day-to-day tool.

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

@tracedef fact(n):

if n == 0:return 1

elsereturn n*fact(n´1)

In: fact(3)fact <´ (3,)

fact <´ (2,)fact <´ (1,)

fact <´ (0,)fact ´> 1

fact ´> 1fact ´> 2

fact ´> 6Out: 6

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!Comment faire pour que cesoit récursif terminal ?

‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

@tracedef fact(n):

if n == 0:return 1

elsereturn n*fact(n´1)

In: fact(3)fact <´ (3,)

fact <´ (2,)fact <´ (1,)

fact <´ (0,)fact ´> 1

fact ´> 1fact ´> 2

fact ´> 6Out: 6

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

def fibo(n):if n <= 1:

return 1return fibo(n´1) + fibo(n´2)

Des bricoles Récursivité Complexité Références

Exemples de suitesfi

bo´>

1fi

bo´>

2fi

bo<´

(1,)

fibo

´>

1fi

bo´>

3fi

bo´>

8fi

bo<´

(4,)

fibo

<´(3

,)fi

bo<´

(2,)

fibo

<´(1

,)fi

bo´>

1fi

bo<´

(0,)

fibo

´>

1fi

bo´>

2fi

bo<´

(1,)

fibo

´>

1fi

bo´>

3fi

bo<´

(2,)

fibo

<´(1

,)fi

bo´>

1fi

bo<´

(0,)

fibo

´>

1fi

bo´>

2fi

bo´>

5fi

bo´>

13

fibo

<´(6

,)fi

bo<´

(5,)

fibo

<´(4

,)fi

bo<´

(3,)

fibo

<´(2

,)fi

bo<´

(1,)

fibo

´>

1fi

bo<´

(0,)

fibo

´>

1fi

bo´>

2fi

bo<´

(1,)

fibo

´>

1fi

bo´>

3fi

bo<´

(2,)

fibo

<´(1

,)fi

bo´>

1fi

bo<´

(0,)

fibo

´>

1fi

bo´>

2fi

bo´>

5fi

bo<´

(3,)

fibo

<´(2

,)fi

bo<´

(1,)

fibo

´>

1fi

bo<´

(0,)

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

def pgcd(a, b):if b == 0:

return areturn pgcd(b, a%b)

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

$

&

%

Q(1) = Q(2) = 1

Q(n) =Q(n ´ Q(n ´ 1))

+Q(n ´ Q(n ´ 2))

Des bricoles Récursivité Complexité Références

Exemples de suites

‚ Factorielle n!‚ Fibonacci Fn‚ PGCD‚ Suite de Hopfstadter‚ Suite de Ackerman

$

&

%

A(0, n) = n + 1

A(m, 0) = A(m ´ 1, 1) si m ą 0

A(m, n) = A(m ´ 1,A(m, n ´ 1))

Des bricoles Récursivité Complexité Références

Tours de Hanoï

PrincipePour déplacer n disques du pic a au pic b, on déplace n ´ 1disques du pic a au c, puis on déplace le dernier disque de a à b,puis on déplace les n ´ 1 disques de c à b.

Des bricoles Récursivité Complexité Références

Tours de Hanoï

PrincipePour déplacer n disques du pic a au pic b, on déplace n ´ 1disques du pic a au c, puis on déplace le dernier disque de a à b,puis on déplace les n ´ 1 disques de c à b.

Des bricoles Récursivité Complexité Références

Tours de Hanoï

PrincipePour déplacer n disques du pic a au pic b, on déplace n ´ 1disques du pic a au c, puis on déplace le dernier disque de a à b,puis on déplace les n ´ 1 disques de c à b.

Des bricoles Récursivité Complexité Références

Tours de Hanoï

PrincipePour déplacer n disques du pic a au pic b, on déplace n ´ 1disques du pic a au c, puis on déplace le dernier disque de a à b,puis on déplace les n ´ 1 disques de c à b.

Des bricoles Récursivité Complexité Références

Tours de Hanoï

PrincipePour déplacer n disques du pic a au pic b, on déplace n ´ 1disques du pic a au c, puis on déplace le dernier disque de a à b,puis on déplace les n ´ 1 disques de c à b.

Des bricoles Récursivité Complexité Références

Tours de Hanoï

def hanoi(n, a, b):if n == 1:

print("On␣déplace␣un␣disque␣de␣{}␣vers␣{}". format(a, b))else:

hanoi(n´1, a, 6´a´b)print("On␣déplace␣un␣disque␣de␣{}␣vers␣{}". format(a, b))hanoi(n´1, 6´a´b, b)

Des bricoles Récursivité Complexité Références

Permutations

ProblèmeGénérer toutes les permutations d’une liste d’éléments ?

def permut(l1, l2):if l2 == []:

return [l1]res = []for i in l2:

res += permut(l1+[i], [k for k in l2 if k!=i])return res

Des bricoles Récursivité Complexité Références

Permutations

ProblèmeGénérer toutes les permutations d’une liste d’éléments ?def permut(l1, l2):

if l2 == []:return [l1]

res = []for i in l2:

res += permut(l1+[i], [k for k in l2 if k!=i])return res

Des bricoles Récursivité Complexité Références

Evaluation de la complexité

‚ Équation donnant C(n) en fonction de C(k) avec k ă n‚ Factorielle : C(n) = C(n ´ 1) + 1

C(n) = O(n)‚ Fibonacci : C(n) = C(n ´ 1) + C(n ´ 2)

C(n) = O(Fn)

‚ Dichotomie : C(n) = C(n/2) + 1C(n) = O(lg(n))

‚ Hanoi : C(n) = 2C(n ´ 1) + 1C(n) = O(2n)

Des bricoles Récursivité Complexité Références

Piège à complexité

‚ Coûts « cachés »

Des bricoles Récursivité Complexité Références

Piège à complexité

‚ Coûts « cachés »‚ C(n) = 1 + C(n/2)‚ C(n) = O(lg(n))

def dicho(x, l):""" Cherche si x est dans

l triée """if l en (l)==0:

return Falsek = l en (l)//2if x == l[k]:

return Trueif x < l[k]:

return dicho(x, l[:k])return dicho(x, l[k+1:])

Des bricoles Récursivité Complexité Références

Piège à complexité

‚ Coûts « cachés »‚ C(n) = 1 + n/2 + C(n/2)‚ C(n) = O(n)

def dicho(x, l):""" Cherche si x est dans

l triée """if l en (l)==0:

return Falsek = l en (l)//2if x == l[k]:

return Trueif x < l[k]:

return dicho(x, l[:k])return dicho(x, l[k+1:])

Des bricoles Récursivité Complexité Références

Piège à complexité

‚ Coûts « cachés »‚ C(n) = 1 + n/2 + C(n/2)‚ C(n) = O(n)‚ Meilleure version…

def dicho(x, l, a, b):""" Cherche si x est dans

l[a:b] triée """if b´a == 1:

return l[a] == xk = (a+b)//2if x == l[k]:

return Trueif x < l[k]:

return dicho(x, l, a, k)return dicho(x, l, k+1, b)

Des bricoles Récursivité Complexité Références

Diviser pour régner

ThéorèmeSi on a une complexité de la forme C(n) = 2 ˆ C(n/2) + O(n),alors C(n) = O(n lg n)

Des bricoles Récursivité Complexité Références

Garder du cache

def cache(func):memoire = {}def wrapper(*args):

if args not in memoire:memoire[args] = func(*args)

return memoire[args]return wrapper

Des bricoles Récursivité Complexité Références

‚ http://info-llg.fr/commun-mp/?a=cours‚ The art of Computer Programming‚ http://neopythonic.blogspot.fr/2009/04/

tail-recursion-elimination.html

top related