Sunteți pe pagina 1din 44

Recurso

Alm do Sedgewick, veja www.ime.usp.br/pf/algoritmos/aulas/recu.html www.ime.usp.br/pf/algoritmos/aulas/enum.html

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

1 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

2 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

3 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

4 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

5 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

6 / 44

Recurso

Visto em camisetas: para entender recurso preciso entender recurso. A piada tecnicamente falha!

Denies recursivas em matemtica Provas por induo nita Algoritmos denidos de forma recursiva

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

7 / 44

Algumas denies recursivas

Suponha que denimos f (n) para n 0 da seguinte forma: f (n) = 1 se n = 0 nf (n 1) se n > 0.

Temos ento que os valores de f (n) (n 0) so 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, . . .

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

8 / 44

Algumas denies recursivas

Conhecemos f (n); esta a funo fatorial: f (n) = n! = n(n 1) . . . 1 =


1kn

k.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

9 / 44

Algumas denies recursivas

Suponha que denimos g (m, n) para m, n 0, com m e n no simultaneamente nulos da seguinte forma: g (m, n) = m se n = 0 g (n, m mod n) se n > 0.

Tabela?

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

10 / 44

Algumas denies recursivas

Suponha que denimos g (m, n) para m, n 0, com m e n no simultaneamente nulos da seguinte forma: g (m, n) = m se n = 0 g (n, m mod n) se n > 0.

Tabela?

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

11 / 44

Algumas denies recursivas

Tambm conhecemos g (m, n); esta a funo mdc: g (m, n) = mdc(m, n) = (m, n).

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

12 / 44

Um algoritmo recursivo

int gcd(int m, int n) { if (n == 0) return m; return gcd(n, m % n); }

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

13 / 44

Prova de que a funo gcd devolve o mdc

Demonstrao.
Provamos isso por induo em n. Se n = 0, isso claro, para qualquer m. Suponha agora que n > 0 e que, para qualquer m 0 gcd(m, k) devolve mdc(m, k) se k < n. Temos que mdc(m, n) = mdc(n, m mod n) [isto exige uma prova, que estamos omitindo]. Por hiptese de induo, o lado direito dessa equao exatamente o que gcd(n, m % n) Portanto, gcd(m, n) devolve mdc(m, n).

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

14 / 44

Prova de que a funo gcd devolve o mdc

Demonstrao.
Provamos isso por induo em n. Se n = 0, isso claro, para qualquer m. Suponha agora que n > 0 e que, para qualquer m 0 gcd(m, k) devolve mdc(m, k) se k < n. Temos que mdc(m, n) = mdc(n, m mod n) [isto exige uma prova, que estamos omitindo]. Por hiptese de induo, o lado direito dessa equao exatamente o que gcd(n, m % n) Portanto, gcd(m, n) devolve mdc(m, n).

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

15 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

16 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

17 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

18 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

19 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

20 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

21 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

22 / 44

Quanto tempo demora?


Vamos supor que na entrada so dados valores N M. Raciocnio simples: N cai em cada chamada. Assim, T (M, N) = O(N) = O(M) Se r = m%n, ento, n + r < m, logo r < m/2. Mas em duas chamadas, r passa a ser o valor de m, ou seja, a cada duas chamadas, m pelo menos dividido por 2. Portanto, depois de 2k chamadas, o valor de m passa a ser M menor que 2k . Assim, se M < 2k , o programa termina. T (M, N) < 2 log2 (M + 1) = O(log M). Obs: vale a estimativa T (M, N) < 1, 44 log2 (M + 1)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

23 / 44

A funo de Ackermann

n + 1 se m = 0 A(m, n) = A(m 1, 1) se m > 0 e n = 0 A(m 1, A(m, n 1)) se m > 0 e n > 0. Trivial de programar em C, mas para m 4, impossvel de calcular (A(4, 2) > 1019278 ). Wikipedia e Mathworld so seus amigos aqui.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

24 / 44

A funo de Ackermann

n + 1 se m = 0 A(m, n) = A(m 1, 1) se m > 0 e n = 0 A(m 1, A(m, n 1)) se m > 0 e n > 0. Trivial de programar em C, mas para m 4, impossvel de calcular (A(4, 2) > 1019278 ). Wikipedia e Mathworld so seus amigos aqui.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

25 / 44

A funo de Ackermann

n + 1 se m = 0 A(m, n) = A(m 1, 1) se m > 0 e n = 0 A(m 1, A(m, n 1)) se m > 0 e n > 0. Trivial de programar em C, mas para m 4, impossvel de calcular (A(4, 2) > 1019278 ). Wikipedia e Mathworld so seus amigos aqui.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

26 / 44

Listas ligadas

Um outro jeito de denir as mesmas listas que j vimos: Uma lista ligada : Uma lista vazia ou Uma clula apontando para uma lista ligada.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

27 / 44

Listas ligadas

Um outro jeito de denir as mesmas listas que j vimos: Uma lista ligada : Uma lista vazia ou Uma clula apontando para uma lista ligada.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

28 / 44

Listas ligadas

Um outro jeito de denir as mesmas listas que j vimos: Uma lista ligada : Uma lista vazia ou Uma clula apontando para uma lista ligada.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

29 / 44

Os ingredientes de uma denio recursiva

Os objetos a serem denidos devem ter um certo tamanho. Mais comum: um inteiro positivo. Um objeto denido em termos de objetos menores. Precisa haver uma base: objetos pequenos para os quais a denio direta.

2 3

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

30 / 44

Os ingredientes de uma denio recursiva

Os objetos a serem denidos devem ter um certo tamanho. Mais comum: um inteiro positivo. Um objeto denido em termos de objetos menores. Precisa haver uma base: objetos pequenos para os quais a denio direta.

2 3

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

31 / 44

Os ingredientes de uma denio recursiva

Os objetos a serem denidos devem ter um certo tamanho. Mais comum: um inteiro positivo. Um objeto denido em termos de objetos menores. Precisa haver uma base: objetos pequenos para os quais a denio direta.

2 3

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

32 / 44

Como consertar?
Para entender recurso preciso entender recurso.

Exerccio 1.
Como consertar a frase para ela car matematicamente correta?

Exerccio 2.
Mais importante: como resolver o problema anterior, mantendo a piada?

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

33 / 44

Como consertar?
Para entender recurso preciso entender recurso.

Exerccio 1.
Como consertar a frase para ela car matematicamente correta?

Exerccio 2.
Mais importante: como resolver o problema anterior, mantendo a piada?

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

34 / 44

Como consertar?
Para entender recurso preciso entender recurso.

Exerccio 1.
Como consertar a frase para ela car matematicamente correta?

Exerccio 2.
Mais importante: como resolver o problema anterior, mantendo a piada?

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

35 / 44

Expresses em notao pr-xa

Expresso E em notao pr-xa: <natural> E= + F G * F G, onde F e G so expresses em notao pr-xa. (Por simplicidade, ignoramos as operaes -, /, mod.)

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

36 / 44

Expresses em notao pr-xa

Valor val(E) de uma expresso E em <natural> val(E) = val(F) + val(G) val(F) val(G)

notao pr-xa: se E = <natural> se E = + F G se E = * F G.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

37 / 44

Avaliao de expresses em notao pr-xa


/* prog5.4.c */ #include <stdio.h> char *a; int i; int eval() { int x = 0; while (a[i] == ) i++; if (a[i] == +) { i++; return eval() + eval(); } if (a[i] == *) { i++; return eval() * eval(); } while ((a[i] >= 0) && (a[i] <= 9)) x = 10*x + (a[i++]-0); return x; }

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

38 / 44

Por que funciona?

A parte recursiva no mistrio: implementa uma denio recursiva. Mas o que acontece com essa parte: int x = 0; while ((a[i] >= 0) && (a[i] <= 9)) x = 10*x + (a[i++]-0); ????? Queremos: se a[r..s] um trecho maximal de dgitos consecutivos, ento x adquire o valor representado por esse trecho.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

39 / 44

Por que funciona?

A parte recursiva no mistrio: implementa uma denio recursiva. Mas o que acontece com essa parte: int x = 0; while ((a[i] >= 0) && (a[i] <= 9)) x = 10*x + (a[i++]-0); ????? Queremos: se a[r..s] um trecho maximal de dgitos consecutivos, ento x adquire o valor representado por esse trecho.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

40 / 44

Por que funciona?

A parte recursiva no mistrio: implementa uma denio recursiva. Mas o que acontece com essa parte: int x = 0; while ((a[i] >= 0) && (a[i] <= 9)) x = 10*x + (a[i++]-0); ????? Queremos: se a[r..s] um trecho maximal de dgitos consecutivos, ento x adquire o valor representado por esse trecho.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

41 / 44

Por que funciona?

A parte recursiva no mistrio: implementa uma denio recursiva. Mas o que acontece com essa parte: int x = 0; while ((a[i] >= 0) && (a[i] <= 9)) x = 10*x + (a[i++]-0); ????? Queremos: se a[r..s] um trecho maximal de dgitos consecutivos, ento x adquire o valor representado por esse trecho.

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

42 / 44

Avaliao de expresses em notao pr-xa

/* prog5.4.c */ [...] int main(int argc, char *argv[]) { a=argv[1]; printf("%d\n", eval()); return 0; }

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

43 / 44

Exerccio
Exerccio 3.
Os nmeros de Fibonacci so denidos pela recorrncia Fn = Fn1 + Fn2 , F0 = 0, F1 = 1.

Eles crescem muito rpido e estouram a capacidade de variveis. Escreva um programa que, lendo n, k na linha de comando, imprime o valor fib(n, k) (onde a funo unsigned long fib(unsigned long n, unsigned long k) devolve Fn mod k esse modk para no ter que se preocupar com estouro dos inteiros).
1

Implemente fib como uma funo recursiva (conforme visto em aula). Implemente fib iterativamente, com tempo O(n). Implemente fib com tempo O(log n) (isto requer um tiquinho de matemtica!)
44 / 44

2 3

Princpios de Desenvolvimento de Algoritmos 2 sem 2011

S-ar putea să vă placă și