programação i aula 15 definições recursivas -...
TRANSCRIPT
Programação IAula 15 — Definições recursivas
Pedro Vasconcelos
DCC/FCUP
2018
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 1 / 30
Nesta aula
1 Definições recursivas
2 ExemplosFactorialFloco de neve de KochTorre de Hanoi
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 2 / 30
Recursividade
Uma definição diz-se recursiva seusamos na definição o próprioconceito que estamos a definir.
Apesar de parecerem paradoxais,as definições recursivas podem serúteis em linguística, matemática ecomputação!
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 4 / 30
Algoritmos recursivos
Estratégia dividir e conquistar:para os casos simples obtemos a solução diretamentepara casos maiores, decompomos o problema em partes maispequenas; resolvemos os sub-problemas recursivamente
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 5 / 30
Factorial
Podemos calcular o factorial de n recursivamente:
fact(0) = 1fact(n) = n × fact(n − 1) (n > 0)
A primeira equação define o caso base: factorial de 0
A segunda equação define o caso recursivo: como calcularfact(n) usando fact(n − 1).
Podemos usar para calcular o factorial de qualquer inteironão-negativo.
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 8 / 30
Exemplo
Calcular o fatorial de 4.
fact(4) = 4× fact(3)= 4× (3× fact(2))= 4× (3× (2× fact(1)))= 4× (3× (2× (1× fact(0))))= 4× (3× (2× (1× 1)))= 24
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 9 / 30
Factorial recursivo em Python
def fact(n):if n==0: # caso base
return 1else: # caso recursivo
return n*fact(n-1)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 10 / 30
Exemplos
>>> fact(0)1>>> fact(4)24>>> fact(5)120>>> fact(-1)maximum recursion depth exceeded
Visualizar execução usando http://pythontutor.com.O que significa o erro do último exemplo?
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 11 / 30
Floco de neve de Koch
O “floco de neve” é uma curvafechada proposta pelo matemáticoHelve von Koch em 1904; é um dosprimeiros exemplos de um fractal.
Vamos escrever um programa paradesenhar aproximações a estacurva.
Fonte: https://pt.wikipedia.org/wiki/Curva_de_Koch
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 13 / 30
Curva de Koch
n = 0
n = 1
n = 2
n = 3
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 14 / 30
Curva de Koch (cont.)
Vamos definir um procedimento koch(n,size) para desenhar afigura de ordem n:
a figura de ordem 0 é uma linha
a figura de ordem n contém quatro sub-figuras de ordem n − 1
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 15 / 30
Curva de Koch (cont.)
from turtle import *
def koch(n, size):if n == 0: # caso base: só uma linha
forward(size)else: # caso recursivo
# 4 sub-figuras de ordem n-1 e 1/3 tamanhokoch(n-1, size/3)left(60)koch(n-1, size/3)right(120)koch(n-1, size/3)left(60)koch(n-1, size/3)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 16 / 30
Curva de Koch (cont.)
Podemos simplificar a definição anterior:
right(α) é equivalente a left(−α);
left(0) não altera a orientação.
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 17 / 30
Curva de Koch (cont.)
def koch(n, size):if n == 0: # caso base
forward(size)else: # caso recursivo
for angle in [60, -120, 60, 0]:koch(n-1, size/3)left(angle)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 18 / 30
Exemplos
koch(0,300)
koch(1,300)
koch(2,300)
koch(3,300)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 19 / 30
Exemplos (cont.)
O procedimento koch desenha apenas 1/3 da curva fechada
Para desenhar o “floco de neve”: basta repetir koch três vezesrodando a tartaruga (exercício da folha 9)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 20 / 30
Torre de Hanoi
Começamos com N discos empilhados com diametros crescentesPodemos mover um disco de cada vez e não podemos colocarsobre outro de menor diâmetroObjetivo: mover todos os discos do primeiro para o terceiro pino
Fonte: http://en.wikipedia.org/wiki/Tower_of_Hanoi
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 22 / 30
Exemplo (3 discos)
Solução: A→ C; A→ B; C→ B; A→ C; B→ A; B→ C; A→ C.
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 23 / 30
Solução recursiva
Para mover n discos da pilha X para Y usando Z como auxiliar:
se n = 1: (caso base) mover um único disco de X para Y
se n > 1: (caso recursivo)1 recursivamente mover n − 1 discos de X para Z
usando Y como auxiliar2 mover um disco no topo de X para Y3 recursivamente mover n − 1 discos de Z para Y
usando X como auxiliar
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 24 / 30
Solução recursiva (cont.)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 25 / 30
Implementação
def hanoi(n, X, Y, Z):”’Mover n discos da pilha X para a pilha Yusando a pilha Z como espaço auxiliar.”’if n==1: # caso base
print(X, ’->’, Y)elif n > 1: # caso recursivo
# mover n - 1 discos da origem para o auxiliarhanoi(n - 1, X, Z, Y)# mover um disco de X para Yprint(X, ’->’, Y)# mover n - 1 discos do auxiliar para o destinohanoi(n - 1, Z, Y, X)
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 26 / 30
Solução para três discos
>>> hanoi(3,"A","C","B")A -> CA -> BC -> BA -> CB -> AB -> CA -> C
>>> hanoi(2,"A","B","C")A -> CA -> BC -> B
>>> hanoi(2,"B","C","A")B -> AB -> CA -> C
A solução de 3 discos contém as soluções de dois sub-problemas de2 discos.
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 27 / 30
Observações
O número de movimentos T para resolver o puzzle crescebastante quando o número de discos N aumenta
N 2 3 4 5 6 7 8 9 10T 3 7 15 31 63 127 255 511 1023
Porquê. . . ?
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 28 / 30
Observações (cont.)
Para tamanho 1 efetuamos 1 movimentoPara tamanho N > 1:
1 resolvemos 2 sub-problemas de tamanho N − 1;2 e efetuamos mais 1 movimento
Obtemos uma equação de recorrência
T (1) = 1T (N) = 2× T (N − 1) + 1
A solução é T (N) = 2N − 1
O número de movimentos cresce de forma exponencial com onúmero de discos
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 29 / 30
Crescimento exponencial
Se cada movimento demorar 1 segundo:
10 discos demoram 210 − 1 segundos ≈ 17 minutos20 discos demoram 220 − 1 segundos ≈ 12 dias30 discos demoram 230 − 1 segundos ≈ 34 anos40 discos demoram 240 − 1 segundos ≈ 35 mil anos60 discos demoram mais do que idade atual do universo(≈ 1.1× 1012 anos)!
Só podemos resolver problemas com crescimento exponencial paratamanhos pequenos!
Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 30 / 30