Estruturas de Dados – aulas – bloco 4

Download Report

Transcript Estruturas de Dados – aulas – bloco 4

UNDB ESTRUTURAS DE DADOS Prof. Alessandro Gonçalves

[email protected]

Complexidade de Algoritmos

Conceituação Complexidade no pior caso, melhor caso e caso médio Exemplos

Complexidade de Algoritmos

Avaliação de tempo na história: 1) Algoritmos primitivos 2) A avaliação do tempo na matemática.

Ex: tábuas de Log 3) O aparecimento do computador

O tempo como fator primordial

Complexidade de Algoritmos

Avaliação de espaço na história: 1) No início era fundamental

Ex: quanto de memória tenho ?

Eniac: 200 bits 2) Hoje já não é tão importante

Era da fartura

Complexidade de Algoritmos

Dois métodos para avaliar o tempo: Empírico e Analítico Empírico 1) Medição do tempo de execução do algoritmo 2) Dependentes do hardware (memória, computador...) e software (compilador, linguagem...) 3) Permitem tratamento estatístico 4) Mais simples de ser implementado

Complexidade de Algoritmos

Dois métodos para avaliar o tempo: Empírico e Analítico Analítico 1) Expressões matemáticas para determinar o tempo 2) Independentes do hardware (memória, computador...) e software (compilador, linguagem...) 3) Permitem tratamento estatístico 4) Mais complexo de ser implantado

Complexidade de Algoritmos

Implantação do método Analítico 1) Considera-se grande quantidade de dados 2) Valores assintóticos 3) Desconsiderar constantes aditivas e multiplicativas

Ex: 2*n² + 10x + 5 é equivalente a n² + x.

As duas expressões acima são da ordem n² 4) Baseado em uma variável independente, na entrada do algoritmo(caixa preta) 5) Mais complexo de ser implantado

Complexidade de Algoritmos

Definindo uma expressão matemática 1) Divide-se o algoritmo em passos 2) Cada passo é composto de número fixo de operações básicas 3) A operação básica de maior frequência é conhecida como “operação dominante”.

4) O número de passos do algoritmo é a frequência da operação dominante.

5) Em algoritmos de ordenação, geralmente a operação dominante é a comparação.

Complexidade de Algoritmos

Exemplo em C – inverte.c

Resumo: void inverte() { int x, temp; } } for (x = 0; x<5; x++) { temp = vet[x]; vet[x] = vet[9-x]; vet[9-x] = temp; Cada passo corresponde a troca entre dois elementos Variável independente: número de elementos (n) Número de passos: número de execuções do bloco

Complexidade de Algoritmos

2 3 5 0 1 2 3 0 1 Soma de matrizes (para a turma resolver) 0 0 2 3 -1 4 -4 1 0 2 3 7 3 0 6 -1 1 1 Algoritmo: Para i = 1 até n faça Para j = 1 até n faça Cij = Aij + Bij Fim Para J Fim Para i Variável independente ?

Número de passos ?

Número de linhas da matriz N²

Complexidade de Algoritmos

25 9 36 8 Multiplicação de matrizes (para a turma resolver) 2 7 69 47 4 3 5 2 70 55 Algoritmo: Para i = 1 até n faça Para j = 1 até n faça Dij = 0 Para k = 1 até n faça ...

Dij = Dij + Aik * Bkj

Número de colunas da matriz A

Número de passos ?

Complexidade de Algoritmos

Definindo uma expressão matemática Nos exemplos anteriores, o número de passos dependia sempre do tamanho da entrada, não do seu valor.

Mas isso nem sempre ocorre. Em geral, o número de passos depende do valor da entrada.

Considere: Duas matrizes A e B e uma variável X.

Se X = 0, faça C = A+B Se X <>0, faça D = A.B

Número de passos ?

N² ou N³

Complexidade de Algoritmos

Definindo uma expressão matemática para Complexidade de Tempo Ideal seria sempre conhecer o número de passos, conforme a entrada Difícil de ser atingido na prática Alternativa: determinar o número de passos para entradas específicas e representativas

Complexidade de Algoritmos

Determinando entradas representativas A = Algoritmo E = {E1, E2..., En} T1 = número de passos de A, quando a entrada for Ei

Complexidade de Algoritmos

Complexidade do Pior Caso Número de passos da entrada mais desfavorável A mais utilizada Quase sempre é relevante(Ex: aplicações de segurança) Quando falo que um algoritmo tem uma Complexidade “X”, estamos falando da Complexidade do Pior Caso Complexidade do Melhor Caso Número de passos da entrada mais favorável Pouco utilizada Pouco relevante Aplicações específicas Complexidade do Caso Médio Número de passos da entrada média Relevante Tratamento matemático e geralmente, complexo pois depende da probabilidade

Complexidade de Algoritmos

q = 0.5 ou 50%

Complexidade de Algoritmos

Exercícios (20 minutos) 1) Calcule a complexidade do algoritmo para calcular n!

2) Sejam duas matrizes: (a ij ) e (b kj ) tais que: 1 < i < n; 1 <= k<= n; 1<= j <= m, escrever os algoritmos para fazer C = A + B D = A * B Determinar as complexidades

Complexidade de Algoritmos

Solução dos exercícios Soma := 0 Para i = n até 1 passo -2 faça Soma := Soma + n*(n-1); Fim Para Complexidade: n

Complexidade de Algoritmos

Solução dos exercícios Algoritmo: soma de matrizes Para i := 1 até n faça Para j := 1 até p faça Cij := aij + bij Complexidade = n.p

Complexidade de Algoritmos

Solução dos exercícios Algoritmo: multiplicação de matrizes Para i := 1 até n faça (linhas da matriz A) Para j := 1 até p faça (colunas da matriz B) Dij = 0 Para k := 1 até p faça Dij := Dij + aik * bkj Complexidade = n.p.k

Complexidade de Algoritmos

Análise de algoritmo Demo (A,n) { Entrada: um array A[] com n elementos inteiros Saída: o maior elemento em A[];

Int c; C = A[0]; For (i = 1; i < n; i ++) { If (c < A[i]) c = A[i]; } } Return c;

Quantas operações primitivas são necessárias para a execução ?

Complexidade de Algoritmos

Análise de algoritmo 1) inicializar a variável array como A[0]. Duas operações primitivas 2) o contador i é inicializado com o valor 1 no início do laço for. Corresponde a uma operação primitiva 3) a condição i < n é verificada antes de entrar no laço for. Uma operação primitiva de comparar dois números; 4) o contador i é inicializado em 0 e incrementado em 1 no fim de cada iteração do laço, a comparação i < n é feita n vezes, assim a condição contribui com n unidades para a contagem

Complexidade de Algoritmos

Análise de algoritmo 5) o laço for é executado n-1 vezes. A cada iteração, A[i] é comparado com c (duas operações primitivas indexação e atribuição). O contador i é incrementado. Duas operações primitivas, soma e atribuição. Assim, a cada iteração do laço quatro ou seis operações são realizadas, dependendo se A[i] < c ou A[i] > c. Desta forma, o corpo do laço contribui para a contagem variando de 4(n-1) ou 6(n-1) 6) retorna o valor da variável que corresponde a uma operação primitiva e é executada apenas uma vez.

Resumo Melhor caso: 2 + 1 + n + 4(n-1) + 1 = 5n Pior caso: 2 + 1 + n + 6(n-1) + 1 = 7n - 2

Complexidade de Algoritmos

Notação O (Omicron) Refere-se ao pior caso Melhor caso: 2 + 1 + n + 4(n-1) + 1 = 5n => n Pior caso: 2 + 1 + n + 6(n-1) + 1 = 7n – 2 => n O(n) = f(x) = 7n -2 Para calcularmos O, consideramos sempre o valor mais relevante, em termos de “n” ou outras variáveis envolvidas

Complexidade de Algoritmos

Exercícios 1) n³ -1 2) n² + 2.log n n n 3) 3.n + 5.2

n n - 1 4) (n-1) + n n n² 5) 5.3 + 4.2

6) 6.347.562

7 n 7) 5.n + 3.2 + n!

8) 3n + 7m + 2 9) 5n² + 9m + 4 10) 3n + 5m + n.m

Complexidade de Algoritmos

Respostas 1) O(n³) 2) O(n²) n 3) O(n) n 4) O(n) n ² 5) O(2) 6) O(1) 7) O(n!) 8) O(n + m) 9) O(n² + m) 10) O(n.m)

Complexidade de Algoritmos

Escalas N 1 10 100 log 0 2 3.32

6.64

n n 1 10 100 1000 9.97

n!

2 n O(n) 1000 n.log

2 n 0 33 664 9970 n² n² 1 100 10.000

1.000.000

n.log

2 n n³ 1 1000 1.000.000

10 9 n 2 n 2 1024 1,28 x 10 30 1,072 x 10 31 n!

1 3x10 6 3x10 157 3x10 2567 n log 2 n

Complexidade de Algoritmos

Propriedades da notação O O(g + h) = O(g) + O(h) O(g . h) = O(g) . O(h) O(k . g) = k . O(g) = O(g)

Complexidade de Algoritmos

Video Torre de Hanoi Programa Torre de Hanoi em C Para solucionar um Hanói de 64 discos, são necessários 18.446.744.073.709.551.615 movimentos

Complexidade de Algoritmos

Propriedades da notação O Cota superior – menor complexidade de um algoritmo conhecido Nos exemplos anteriores, a complexidade de multiplicação de matrizes era O(n³) O(n³) O algoritmo de Strassen diminuiu a complexidade para O(n 2,807 ) O(n 2,807 ) O(n³) O algoritmo de Coppersmith e Winograd melhoraram para O (n 2,376 ) O (n 2,376 ) O(n 2,807 ) O(n³)

Complexidade de Algoritmos

Notação Ɵ (Teta) Refere-se ao caso médio Este é o caso que é o mais difícil de ser determinado, pois, necessita de análise estatística e em conseqüência de muitos testes, contudo é muito utilizado, pois é o que representa mais corretamente a complexidade do algoritmo.

Exemplo : Procurar uma palavra em um busca de uma palavra na metade do dicionário. Pode-se iniciar a dicionário. Imediatamente se sabe se foi encontrada a palavra ou, no caso duas metades deve se repetir o processo contrário, em qual das (é um processo recursivo) até se chegar ao resultado. Em cada busca (ou sub-busca), o problema (as reduzindo páginas em que a palavra pode estar) vão se à metade, o que corresponde com a função logarítmica.

Este procedimento de busca (conhecido como busca uma estrutura ordenada têm complexidade logarítmica.

binária) em Ɵ(log 2 n)

Complexidade de Algoritmos

Notação Ω (ômega) Refere-se ao melhor caso Pouco utilizado porque sempre precisamos saber como o algoritmo se comporta em situações difíceis (pior caso).

Exemplo : Exemplo 1: Em uma lista telefônica queremos encontrar um número, assume-se que a complexidade do caso melhor é Ω (1), pois está pressupondo-se o número desejado está na primeira posição.

Exemplo 2: Extrair qualquer elemento de um vetor. A se queira buscar. Portanto constante Ω (1).

indexação em um vetor ou array, leva o mesmo tempo seja qual for o índice que é uma operação de complexidade

Complexidade de Algoritmos

Conclusão Nas complexidades algorítmicas temos: Ω( ) <= θ( ) <= O() Algoritmos ótimos podem ser obtidos de duas formas: 1) melhoramento interno do código OU 2) comparação dos algoritmos entre si, escolhendo o de menor complexidade.

exemplo

Complexidade de Algoritmos

UNDB

ESTRUTURAS DE DADOS Prof. Alessandro Gonçalves [email protected]