programação i aula 15 definições recursivas -...

25
Programação I Aula 15 — Definições recursivas Pedro Vasconcelos DCC/FCUP 2018 Pedro Vasconcelos (DCC/FCUP) Programação I Aula 15 — Definições recursivas 2018 1 / 30

Upload: vandieu

Post on 03-Aug-2018

229 views

Category:

Documents


0 download

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