Carregar apresentação
A apresentação está carregando. Por favor, espere
PublicouManoel Lancastre de Vieira Alterado mais de 8 anos atrás
1
Recursividade e análise Cristiano Arbex Valle arbex@dcc.ufmg.br Vinicius Fernandes dos Santos viniciussantos@dcc.ufmg.br
2
Algoritmos e Estrutura de Dados II Recursividade Um procedimento que chama a si mesmo é dito ser recursivo. Recursividade permite descrever algoritmos de forma mais clara e concisa, especialmente problemas recursivos por natureza ou que utilizam estruturas recursivas. Exemplos Algoritmos de “Dividir para Conquistar” Árvores
3
Algoritmos e Estrutura de Dados II Exemplo Fatorial: n! = n*(n-1)! para todo n>0 0! = 1 Em C int Fat (int n) { if (n <= 0) return 1; else return n * Fat(n-1); }
4
Algoritmos e Estrutura de Dados II Estrutura Normalmente, as funções recursivas são divididas em duas partes Chamada Recursiva Condição de Parada A chamada recursiva pode ser Direta: função A chama ela mesma Indireta: A chama B que chama A novamente A condição de parada é fundamental para evitar loops infinitos
5
Algoritmos e Estrutura de Dados II Execução Internamente, quando qualquer chamada de função é feita dentro de um programa, é criado um Registro de Ativação na Pilha de Execução do programa O registro de ativação armazena: Os parâmetros e variáveis locais da função “ponto de retorno” no programa ou subprograma que chamou essa função Ao final da execução da função: O registro é desempilhado A execução volta ao subprograma que chamou a função
6
Algoritmos e Estrutura de Dados II Execução pilha de execução topo da pilha registro de ativação
7
Algoritmos e Estrutura de Dados II int Fat(int n) { if (n <= 0) return 1; else return n * Fat(n-1); } main() { int f; f = fat(4); printf(“%d”,f); } pilha de execução fat(4) fat(3) fat(2) fat(1) fat(0) Exemplo
8
Algoritmos e Estrutura de Dados II Complexidade A complexidade de tempo do fatorial recursivo é O(n). (Em breve iremos ver a maneira de calcular isso usando equações de recorrência) Mas a complexidade de espaço também é O(n), devido à pilha de execução Já no fatorial não recursivo a complexidade de espaço é O(1) int Fat(int n) { int f; f = 1; while(n > 0) { f = f * n; n = n – 1; } return f; }
9
Algoritmos e Estrutura de Dados II Recursividade Portanto, a recursividade nem sempre é a melhor solução, mesmo quando a definição matemática do problema é feita em termos recursivos.
10
Algoritmos e Estrutura de Dados II Fibonacci Outro exemplo: Série de Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89... F 1 = F 2 = 1 F(n) = F(n-1) + F(n-2) n > 2 Phi = 1,6180339... (Proporção áurea)
11
Algoritmos e Estrutura de Dados II Fibonacci Outro exemplo: Série de Fibonacci: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89... F 1 = F 2 = 1 F(n) = F(n-1) + F(n-2) n > 2
12
Algoritmos e Estrutura de Dados II Fibonacci Outros exemplos na natureza:
13
Algoritmos e Estrutura de Dados II Fibonacci Série de Fibonacci: F 1 = F 2 = 1 F(n) = F(n-1)+ F(n-2) n > 2 int Fib(int n) { if (n < 3) return 1; else return Fib(n-1) + Fib(n-2); }
14
Algoritmos e Estrutura de Dados II Análise da função Fibonacci Ineficiência em Fibonacci Termos F(n-1) e F(n-2) são computados independentemente Custo para cálculo de F(n) O( n ) onde = (1 + 5)/2 = 1,61803... Exponencial
15
Algoritmos e Estrutura de Dados II Fibonacci não recursivo Complexidade: O(n) Conclusão: não usar recursividade cegamente! int FibIter(int n) { int fn1 = 1, fn2 = 1; int fn, i; if (n < 3) return 1; for (i = 3; i <= n; i++) { fn = fn2 + fn1; fn2 = fn1; fn1 = fn; } return fn; }
16
Algoritmos e Estrutura de Dados II Quando vale a pena usar recursividade Algoritmos complexos, cuja implementação iterativa é complexa e normalmente requer o uso explícito de uma pilha Dividir para Conquistar (Ex. Quicksort) Divide and Conquer Caminhamento em Árvores (pesquisa)
17
Algoritmos e Estrutura de Dados II Dividir para Conquistar Duas chamadas recursivas Cada uma resolvendo a metade do problema Muito usado na prática Solução eficiente de problemas Decomposição Não se reduz trivialmente como fatorial Duas chamadas recursivas Não produz recomputação excessiva como fibonacci Porções diferentes do problema
18
Algoritmos e Estrutura de Dados II Exemplo: régua void regua(int l, r, h) { int m; if (h > 0) { m = (l + r) / 2; marca(m, h); regua(l, m, h – 1); regua(m, r, h – 1); }
19
Algoritmos e Estrutura de Dados II Execução: régua regua(0, 8, 3) marca(4, 3) regua(0, 4, 2) marca(2, 2) regua(0, 2, 1) marca(1, 1) regua(0, 1, 0) regua(1, 2, 0) regua(2, 4, 1) marca(3, 1) regua(2, 3, 0) regua(3, 4, 0) regua(4, 8, 2) marca(6, 2) regua(4, 6, 1) marca(5, 1) regua(4, 5, 0) regua(5, 6, 0) regua(6, 8, 1) marca(7, 1) regua(6, 7, 0) regua(7, 8, 0)
20
Algoritmos e Estrutura de Dados II Representação por árvore 0, 8, 3 0, 4, 2 4, 8, 2 0, 2, 12, 4, 14, 6, 1 6, 8, 1 0, 1, 0 1, 2, 02, 3, 0 3, 4, 0 4, 5, 0 5, 6, 0 6, 7, 0 7, 8, 0
21
Organizam dados de forma hierárquica Acontecem com frequência na natureza Fáceis de representar e manipular com computadores Úteis para várias tarefas Árvores
22
Exemplos
24
Terminologia
25
Raiz Terminologia Raiz
26
Folhas Terminologia Folhas
27
Nós internos Terminologia Nós internos
28
Filhos Pai Terminologia
29
Descendentes Terminologia
30
Ancestrais Terminologia
31
Irmãos Terminologia
32
Níveis 0 1 2 3 4 Terminologia
33
Caminho Terminologia
34
Algoritmos e Estrutura de Dados II Análise de Algoritmos Recursivos Para cada procedimento recursivo é associada uma função de complexidade f(n) desconhecida, onde n mede o tamanho dos argumentos para o procedimento. Por se tratar de um algoritmo recursivo, f(n) vai ser obtida através de uma equação de recorrência. Equação de recorrência: maneira de definir uma função por uma expressão envolvendo a mesma função. Análise de complexidade
35
Algoritmos e Estrutura de Dados II Análise de Algoritmos Recursivos Custo de um algoritmo recursivo: T(n) Custo de cada subproblema: T(n / b) Número de chamadas recursivas: a Custo de cada chamada: f(n) Capturado pela equação de recorrência: Análise de complexidade
36
Algoritmos e Estrutura de Dados II Resolvendo a Equação de Recorrência Existem várias formas de se resolver uma equação de recorrência. A mais simples é expandir a equação e depois fazer uma substituição dos termos. Análise de complexidade
37
Algoritmos e Estrutura de Dados II Exemplo 1 Determine a equação de recorrência para a função abaixo. Qual a sua complexidade? int Fat(int n) { if (n <= 0) return 1; else return n * Fat(n-1); } Análise de complexidade
38
Exemplo 1 Algoritmos e Estrutura de Dados II Análise de complexidade
39
Algoritmos e Estrutura de Dados II Exemplo 2 Determine a equação de recorrência para a função abaixo. Qual a sua complexidade? void ex(int *X, int n){ int i; if (n > 0) { for (i=0; i<n-1; i++) X[i] = 0; X[n] = n; ex(X, n-1); } } Análise de complexidade
40
Exemplo 2 Algoritmos e Estrutura de Dados II Análise de complexidade
41
Algoritmos e Estrutura de Dados II Exemplo 3 Determine a equação de recorrência para a função abaixo (considere ( A[] global). Qual a sua complexidade? void Pesquisa(n) { if (n <= 1) { verifica(A[0]); } else { for (int i = 0; i < n; i++) { verifica(A[i]); } Pesquisa(n/3); } Análise de complexidade
42
Algoritmos e Estrutura de Dados II Análise da Função Recursiva Suposições: A função verifica() é O(1) n é sempre divisível por 3 Qual a equação de recorrência? T(n) = n + T(n/3) T(1) = 1 Análise de complexidade
43
Algoritmos e Estrutura de Dados II Resolvendo a equação Substitui-se os termos T(k), k 1, tenham sido substituídos por fórmulas contendo apenas T(1). Análise de complexidade 1 → n/3 K = 1 → n = 3 K
44
Algoritmos e Estrutura de Dados II Resolvendo a Equação Considerando que T(n/3 K ) = T(1) temos: Temos uma PG finita: O(n) Análise de complexidade
45
Exemplo 3 Algoritmos e Estrutura de Dados II Análise de complexidade Resolva a relação de recorrência: T(n) = T(n/2) + c (c é uma constante) T(1) = 1 Expandindo:
46
Exemplo 3 Algoritmos e Estrutura de Dados II Análise de complexidade Resolva a relação de recorrência: n/2 k = 1 n = 2 k
Apresentações semelhantes
© 2024 SlidePlayer.com.br Inc.
All rights reserved.