5COP096 Teoria da Computação Aula 4 Prof. Dr. Sylvio Barbon Junior 1
Sumário 1) Técnicas de Análise de Algoritmos 2) Paradigmas de Projeto de Algoritmos 1) Indução 2) Recursão 3) Algoritmos Tentativa e erro 2
Técnicas de Análise de Algoritmos - A determinação do tempo de execução de um programa qualquer pode se tornar um problema matemático complexo quando se desejar encontrar o valor exato da função de complexidade. - É mais fácil determinar que o número esperado de comparações é O(n)do que (n+1)/2, porém não tem a precisão adequada. - A análise de algoritmos utiliza técnicas de matemática discreta, não existe um conjunto de regras para analisar programas, mas algumas propriedades se destacam: 1) Instruções de atribuição, leitura ou escrita são O(1). 2) O tempo de execução de uma sequência de comandos será determinado pelo maior tempo de execução. 3) Comandos de decisão são O(1). 3
Técnicas de Análise de Algoritmos 4) O tempo de execução de um anel (laço) é a soma do corpo mais o tempo para avaliação a condição para término, multiplicado pelo número de iterações do anel. 5) Procedimentos Recursivos estão associados a própria função de complexidade. 4
Considerando os paradigmas para projeto de algoritmos, estudaremos: -Indução; - Recursividade; - Tentativa e Erro; - Divisão e Conquista; - Balanceamento; - Programação Dinâmica; -Gulosos; - Aproximados; 5
Indução Raciocínio que parte de dados particulares e, por meio de uma sequência de operações cognitivas, chega a leis ou conceitos mais gerais, indo dos efeitos à causa, das consequências ao princípio, da experiência à teoria. 6
Indução PASSO BASE HIPÓTESE DE INDUÇÃO 1. Té válido para n = 1. 2. Para todo n > 1, se Té válido para n-1, então T é válido para N. 7
Indução Exemplo 1. Comprovar que S(n) = 1 + 2 + 3 +... + n é S(n)= n(n+1)/2 Prova por indução: 1) Passo Base: S(1) = 1 (1+1)/2 = 1 2) Hipótese de Indução: S(n) é n(n+1)/2 S(n+1) = (n+1)(n+2)/2 S(n+1) = S(n) + (n+1) Comprovado! S(n+1) = n(n+1)/2 + (n+1) = (n+1)(n+2)/2 8
Indução Exemplo 2. Considere T(2n) 2T(n) + 2n -1, T(2) =1 Prova por indução: Qual o f(n) parat(n) = O(f(n))? Será que f(n) = n²? Será que f(n) = cn? 1) Passo Base: 1) Passo Base: T(2) = 1 f(2) = 4 T(2n) c2n 2) Hipótese de Indução: 2) Hipótese de Indução: T(2n) 2T(n) + 2n -1 T(2n) 2T(n) + 2n -1 T(2n) 2n² + 2n 1, T(2n) 2cn + 2n 1 < (2n)², > c2n < 4n² Inequação, encontrar o limite superior para O Será que f(n) = n logn? 1) Passo Base: T(2) < 2 log2 2) Hipótese de Indução: T(2n) 2T(n) + 2n 1, T(2n) 2n logn+2n 1 < 2n log2n Comprovado, mas 4n² apresenta 2n² de diferença, indicativo de folga para T(n) Diferença de 2n- 1,indicativo de que T(n) está entre cne n². Diferença de apenas 1, indicativo de que T(n) está muito próximo da solução! T(n) =n logn n +19
Recursão -É um método que chama a si mesmo, direta ou indiretamente. - Permite uma descrição mais clara e concisa de um algoritmo. 10
Recursão Exemplo 1: Árvore Binária de Pesquisa, onde todo no interno contém um registro com a seguinte propriedade, Chaves menores na subárvore esquerda e todos os registros com chaves maiores na subárvore direita. public class ArvoreBinaria{ private static class Noh{ Object reg; Noh esquerda; Noh direita; private Noh raiz; 11
Recursão Exemplo 1: Árvore Binária de Pesquisa. Algoritmo mais popular para percorrer árvores é o ordem de caminhamento central. private void central (Noh p){ if(p!= null){ central(p.esquerda); System.out.println(p.reg.toString()); central(p.dir); O compilador utiliza uma estrutura de PILHA, onde são armazenados os dados para cada chamada de método que ainda não terminou de processar. Cada variável fica armazenada sem acesso global, dentro da pilha de recursão. 12
Recursão Todo comando repetitivo implicam a necessidade de considerar o problema da terminação. P ifbthenc[s i,p]. Sendo P um método recursivo, B a condição de terminação, C uma composiçãodoscomandoss i ep. Exemplo:P ifn>0thenp[s i,p(n-1)]. Quando não usar Recursividade Um algoritmo recursivo nem sempre é o melhor para resolver um problema. O consumo de memória é maior do que outras soluções. Recursividade Não recursivo P ifbthen [S, P]. P (x=x 0; whilebdo S) 13
Paradigmas de Projeto de Algoritmos Recursão Exemplo Fibonacci: public class Fibonacci{ public static int fibrec(int n){ if(n<2) return n; else return(fibrec(n-1) + fibrec(n-2)); public class Fibonacci{ public static int fibrec(int n){ inti =1, f=0; for(int k=1; k<=n; k++){ f = i+f; i= f-i; f 0 = 0 f 1 = 1 f n = f n-1 + f n-2 {para n 2 0,1,1,2,3,5,8,13,21,34,55 14
Recursão Exemplo Fibonacci: n 10 20 30 50 100 Recursivo 8ms 1s 2min 21dias 10 9 anos Iterativo 1/6ms 1/3ms 1/2ms 3/4ms 1,5ms Brassard e Bradley(1996, p.73) f 0 = 0 f 1 = 1 f n = f n-1 + f n-2 {para n 2 0,1,1,2,3,5,8,13,21,34,55 15
Recursão Exemplo 1 Torres de Hanoi staticvoidhanoi(intn, into, intd, intt) { if(n > 1) { hanoi(n -1, O, T, D); mover(o, D); if(n>1){ hanoi(n -1, T, D, O); T(1) = 1 T(n) = 2T(n-1) + 1
Recursão Exemplo 2 MergeSort private static void sort( Comparable[] a, Comparable[] aux, int l, int r){ T(1) = 0 if ( r<=l+1) return; T(n) = 2T(n/2) + n int m = l + ( r l ) / 2 ; sort ( a, aux, l, m); sort( a, aux, m, r); merge( a, aux, l, m,r);
Recursão Exemplo 3 Busca em Árvore Binária index binsearch(number n, index low, index high, const keytype S[], keytype x) iflow highthen mid= (low+ high) / 2 ifx = S[mid] then return mid elsifx < s[mid] then return binsearch(n, low, mid-1, S, x) else return binsearch(n, mid+1, high, S, x) else return 0 end binsearch T(1) = 1 T(n) = T(n/2) + 1
Recursão Exercício 1: Escreva um algoritmo recursivo para determinar o (um) maior elemento de um vetor A[1..n] de inteiros; Encontre a função de custo T(n) do algoritmo desenvolvido. Qual a complexidade assintótica, O, do algoritmo desenvolvido?
Recursão Exercício 2: Considere o algoritmo a seguir, supondo que a operação crucial é inspecionar elemento. O algoritmo inspeciona os n elementos de um conjunto e, de alguma forma, consegue descartar 2/5 dos elementos e fazer uma chamada recursiva sobre os 3n/5 elementos restantes. Escreva uma equação de recorrência que descreva esse comportamento. voidpesquisa (intn) { if(n < 1) inspecione elemento ; termine; else{ para cada um dos elementos, inspecione elemento ; Pesquisa(3 * n / 5);
Recursão Exercício 3: Considere a função abaixo: intx(inta) { if(a<=0) then return0; else return(a + X(a-1)); a) O que essa função faz? b) Calcule a sua ordem de complexidade. Mostre como você chegou a esse resultado. c) Escreva uma função não-recursiva que resolve o mesmo problema. Qual é a ordem de complexidade da sua função? Explique. d) Qual implementação é mais eficiente? Justifique.
Algoritmos Tentativa e Erro - É a resolução de problemas tentando todas as alternativas possíveis; - Recursividade pode ser usada para problemas de Tentativa e Erro; -Aideiadestealgoritmoédecomporoprocessoemumnúmerofinito de subtarefas parciais, exploradas exaustivamente; - Seguem as seguintes regras: 1) Passos em direção à solução são tentados e registrados. 2)Casoumdospassosnãolevaàsoluçãofinal, essedeveser retirado e apagado do registro;
Referências Ziviani, Nivio. Projeto de algoritmos: com implementações em Java e C. Thomson Learning, 2007. Leiserson, Charles E., Ronald L. Rivest, and Clifford Stein. Introduction to algorithms. Ed. Thomas H. Cormen. The MIT press, 2001.