Algoritmos Crescimento de Funções Estruturas Discretas e Lógica Matemática Dep. de Informática – UFMA Prof. Anselmo Paiva
Algoritmos Um conjunto finito de instruções precisas para que um computador realize uma computação e resolva um problema. Prof. Anselmo Paiva
Exemplo: encontrar o maior elemento de uma sequência Algoritmos Exemplo: encontrar o maior elemento de uma sequência Procedure max(a1, a2, …, an: integers) max := a1 for i := 2 to n if max < ai then max := ai {max is the largest element} Prof. Anselmo Paiva
Complexidade Em geral nao estamos preocupados com o tempo e/ou a memória que um algoritmo utiliza para pequenas entradas de dados. Por exemplo: Enquanto a diferença em complexidade de tempo entre a busca linear e a busca binária para uma sequência com n=10 números é insgnificante, ela é gigante para n = 230. Prof. Anselmo Paiva
Complexidade Sejam A e B dois algoritmos que resolvem a mesma classe de problemas. A complexidade de tempo de A é 5.000n, e a de B é 1.1n para uma entrada com n elementos. Para n = 10 A requer 50,000 passos B requer somente 3 B parece ser superior a A. Para n = 1000 A requer 5,000,000 passos B requer 2.51041 Prof. Anselmo Paiva
Assim, algoritmo B não pode ser usado em grandes conjuntos de dados Complexidade Assim, algoritmo B não pode ser usado em grandes conjuntos de dados O que é importante é o crescimento da função de complexidade. O crescimento do tempo e espaço(memória) em relação ao crescimento do tamanho da entrada n é um bom mecanismo para comparar algoritmos. Prof. Anselmo Paiva
Comparação: complexidade de tempo dos algoritmos A e B Entrada Algoritmo A Algoritmo B n 5,000n 1.1n 10 50,000 3 100 500,000 13,781 1,000 5,000,000 2.51041 1,000,000 5109 4.81041392 Prof. Anselmo Paiva
Crescimento de Funções Em geral é descrito usando a notação big-O. Definição: Seja f e g funções de inteiros em reais. Dizemos que f(x) é O(g(x)) se existem constantes C e k tais que |f(x)| C|g(x)| sempre que x > k. Prof. Anselmo Paiva
Crescimento de Funções Quando analizamos o crescimento de funções de complexidade, f(x) e g(x) são sempre positivas. Podemos então simplificar a notação big-O para: f(x) Cg(x) sempre que x > k. Para mostrar que f(x) é O(g(x)), temos somente que encontrar um par (C, k) (o qual nunca é único unique). Prof. Anselmo Paiva
Crescimento de Funções A Idéia por trás da notação big-O é estabelecer um limite superior (upper boundary) para o crescimento da função f(x) para grandes valores de x. Este limite é definido pela função g(x) que é usualmente mais simples que f(x). Aceitamos a constante C no requisito f(x) Cg(x) whenever x > k, porque C não cresce com x. Estamos somente interessados em valores grandes de x, assim está OK se f(x) > Cg(x) for x k. Prof. Anselmo Paiva
Crescimento de Funções Exemplo: Mostre que f(x) = x2 + 2x + 1 é O(x2). Para x > 1 temos: x2 + 2x + 1 x2 + 2x2 + x2 x2 + 2x + 1 4x2 Assim, para C = 4 e k = 1: f(x) Cx2 whenever x > k. f(x) is O(x2). Prof. Anselmo Paiva
Crescimento de Funções Se f(x) é O(x2), tambem é O(x3)? Sim. x3 cresce mais rápido que x2, assim x3 cresce mais rápido que f(x). Mas estamos interessados sempre na menor função g(x) que cresce mais rápido que f(x). Prof. Anselmo Paiva
Crescimento de Funções Funções g(n) “Populare” n log n, 1, 2n, n2, n!, n, n3, log n Prof. Anselmo Paiva
Crescimento de Funções Um problema que pode ser resolvido em tempo polinomial é denominado tratável. Problemas com complexidade maior são denominados intratáveis. Problemas que não possuem um algoritmo que o resolvam são denominados não computáveis Mais sobre isso é uma disciplina de Teoria da Computação ou Computabilidade. Prof. Anselmo Paiva
Regras Úteis para Big-O Para qualquer polinômio f(x)= anxn + an-1xn-1 + … + a0, onde a0, a1, …, an são números reais, f(x) is O(xn). Se f1(x) é O(g1(x)) e f2(x) é O(g2(x)), então (f1 + f2)(x) é O(max(g1(x), g2(x))) Se f1(x) é O(g(x)) e f2(x) é O(g(x)), então (f1 + f2)(x) é O(g(x)). Se f1(x) é O(g1(x)) e f2(x) é O(g2(x)), então (f1f2)(x) é O(g1(x) g2(x)). Prof. Anselmo Paiva
Exemplos de Complexidade O que o seguinte algoritmo computa? proc who_knows(a1, a2, …, an: integers) m := 0 for i := 1 to n-1 for j := i + 1 to n if |ai – aj| > m then m := |ai – aj| {m é a maior diferença entre dois números na sequência de entrada} Comparações: n-1 + n-2 + n-3 + … + 1 = (n – 1)n/2 = 0.5n2 – 0.5n Complexidade de Tempo é O(n2). Prof. Anselmo Paiva
Complexity Examples Outro algoritmo para o mesmo problema: proc max_diff(a1, a2, …, an: integers) min := a1 max := a1 for i := 2 to n if ai < min then min := ai else if ai > max then max := ai m := max - min Comparações: 2n - 2 Complexidade de tempo é O(n). Prof. Anselmo Paiva