Gerson da Silva Borges [email protected] Gerson Borges Estruturas de Dados e Arquivos 1 DEFINIÇÕES • Algoritmo: – seqüência de ações executáveis para a obtenção de uma solução para determinado tipo de problema – descrição de um padrão de comportamento expresso em termos de um conjunto finito de ações – manual de montagem de equipamentos, receitas médicas, receitas de culinária • Estrutura de Dados: – forma de representação dos dados reais Gerson Borges • A escolha do algoritmo influencia a escolha da representação de dados e vice-versa. • Programas são algoritmos que podem ser seguidos por computadores. Estruturas de Dados e Arquivos 2 MEDIDA DE TEMPO DE EXECUÇÃO • Aspectos a serem observados: – Tempo de execução – Espaço ocupado (memória) • Análise divide-se em: – análise de um algoritmo em particular – análise de uma classe de algoritmos • limite (o melhor que se pode obter) • ótimo (quando atinge o limite) • Como medir o custo? – Implementar e medir – Através de modelo matemático Gerson Borges Estruturas de Dados e Arquivos 3 MODELO MATEMÁTICO • Complexidade de tempo ou espaço • O tempo geralmente cresce com o tamanho da entrada. O tempo é função da entrada: função de complexidade f(n) • Não necessariamente o tempo, mas o número de vezes que uma operação relevante é realizada • Exemplo: – Descobrir o maior elemento de um vetor – f(n) = número de comparações realizadas entre os elementos, para um vetor de tamanho n Gerson Borges Estruturas de Dados e Arquivos 4 MEDIDA DE TEMPO DE EXECUÇÃO int Max(int x[]) { int i, tmp; tmp = x[0]; Operação relevante: número de vezes for (i=1; i<n; i++) que elementos do vetor são { if (x[i] > tmp) comparados tmp = x[i]; } return tmp; } Problema: Localizar o maior elemento de um vetor de n elementos. • f(n) = n - 1, para n > 0 • Este algoritmo é ótimo porque atinge o limite Gerson Borges Estruturas de Dados e Arquivos 5 MEDIDA DE TEMPO DE EXECUÇÃO • Pior caso: – maior tempo sobre todas as possíveis entradas de tamanho n. • Melhor caso: – menor tempo sobre todas as possíveis entradas de tamanho n. • Caso médio ou esperado: – média dos tempos de todas as possíveis entradas de tamanho n. • Quando conseguimos determinar o menor custo possível, temos a medida da dificuldade de se resolver tais problemas. • Quando o custo é igual ao menor custo, podemos concluir que o algoritmo é ótimo. Gerson Borges Estruturas de Dados e Arquivos 6 MEDIDA DE TEMPO DE EXECUÇÃO int Pesq(int x[], int tmp) { int i; for (i=0; i<n; i++) { if (x[i] == tmp) Operação relevante: número de vezes return i; que elementos do vetor são } comparados return -1; } • Melhor caso: f(n) = 1 – o registro é o primeiro • Pior caso: f(n) = n – o registro é o último ou não existe • Caso médio: f(n) = (n+1)/2 Problema: Pesquisar a ocorrência de uma determinada chave num vetor de n elementos. Gerson Borges Estruturas de Dados e Arquivos 7 MEDIDA DE TEMPO DE EXECUÇÃO Problema: Localizar o maior e o menor void MaxMin1(int Vet[],int *Max, int *Min) elemento de um vetor de n elementos. { int i; *Max = Vet[0]; Operação relevante: número de vezes *Min = Vet[0]; que elementos do vetor são for(i=1;i<n;i++) comparados { if (Vet[i]> *Max) • Melhor, pior e caso médio: *Max = Vet[i]; f(n) = 2(n-1) if (A[i]< *Min) *Min = Vet[i]; } } Gerson Borges Estruturas de Dados e Arquivos 8 MEDIDA DE TEMPO DE EXECUÇÃO Problema: Localizar o maior e o menor void MaxMin2(int Vet[],int *Max, int *Min) elemento de um vetor de n elementos. { int i; *Max = Vet[0]; Operação relevante: número de vezes *Min = Vet[0]; que elementos do vetor são for (i=1; i<n; i++) comparados { if (Vet[i]> *Max) *Max = Vet[i]; • Melhor caso: f(n) = n-1 else if (Vet[i]< *Min) • Pior caso: f(n) = 2(n-1) *Min = Vet[i]; • Caso médio: f(n) = 3n/2 - 3/2 } } Gerson Borges Estruturas de Dados e Arquivos 9 MEDIDA DE TEMPO DE EXECUÇÃO • Dividir o vetor em dois – Comparar elementos de A aos pares: • A[1] com A[2] • A[3] com A[4] • … – Em cada comparação: • Subconjunto X: incluir o maior • Subconjunto Y: incluir o menor • Max: o maior em X • Min: o menor em Y Gerson Borges • Complexidade: – Divisão: n/2 comparações – Achar o maior: n/2 - 1 – Achar o menor: n/2 - 1 • Melhor, pior e caso médio – f(n) = 3n/2 - 2 • Este algoritmo é ótimo Estruturas de Dados e Arquivos 10 MEDIDA DE TEMPO DE EXECUÇÃO void MaxMin3(int Vet[],int *Max,int *Min) { int i, fim; if (n%2 != 0) // n é par { Vet[n] = Vet[n-1]; fim = n; } else fim = n-1; if (Vet[0] > Vet[1]) { *Max = Vet[0]; *Min = Vet[1]; } else { *Max = Vet[1]; *Min = Vet[0]; } Gerson Borges for (i=2; i< fim; i+=2) { if (Vet[i]>Vet[i+1]) { if (Vet[i] > *Max) *Max = Vet[i]; if (Vet[i+1] < *Min) *Min = Vet[i+1]; } else { if (Vet[i+1]>*Max) *Max = Vet[i+1]; if (A[i] < *Min) *Min = Vet[i]; } } } Estruturas de Dados e Arquivos 11 MEDIDA DE TEMPO DE EXECUÇÃO Comparação: • Os algoritmos 2 e 3 são melhores que o 1 de forma geral • O algoritmo 3 é melhor que o 2 em relação ao pior caso e bastante próximo no caso médio Algoritmo Melhor Pior Médio MaxMin1 2(n-1) 2(n-1) 2(n-1) MaxMin2 n-1 2(n-1) 3n/2 – 3/2 MaxMin3 3n/2 - 2 3n/2 - 2 3n/2 - 2 Gerson Borges Estruturas de Dados e Arquivos 12 COMPORTAMENTO ASSINTÓTICO Definição: – A função f(n) domina assintoticamente outra g(n) se existem c e m tais que |g(n)| c.|f(n)|, para n m Comportamento assintótico de f(n): – Limite do custo quando n cresce f, g c.f(n) g(n) Notação O: m – g(n) é O(f(n)) se f(n) domina assintoticamente g(n) Gerson Borges Algoritmos e Estruturas de Dados n 13 COMPORTAMENTO ASSINTÓTICO • Classes de comportamento: – O(1) - complexidade constante – O(log n) - complexidade logarítmica – O(n) - complexidade linear – O(n . log n) - complexidade “n log n” – O(n2) - complexidade quadrática – O(n3) - complexidade cúbica – O(2n) - complexidade exponencial n=100 1 66 100 0,7x103 104 106 1,3x1030 – As classes acima estão em ordem crescente de dificuldade Gerson Borges Estruturas de Dados e Arquivos 14 CRESCIMENTO DO TEMPO Um algoritmo de complexidade exponencial é ineficiente para entradas muito grandes e não pode ser executado no computador. Gerson Borges Estruturas de Dados e Arquivos 15 COMPORTAMENTO ASSINTÓTICO • Operações: – f(n) – c.O( f(n) ) – O( f(n) ) + O( f(n) ) – O( O( f(n) ) ) – O( f(n) ) + O( g(n) ) – O( f(n) ) . O( g(n) ) – f( n ) . O( g(n) ) Gerson Borges = = = = = = = O( O( O( O( O( O( O( f(n) ) f(n) ), c constante f(n) ) f(n) ) max( f(n), g(n) ) ) f(n).g(n) ) f(n).g(n) ) Estruturas de Dados e Arquivos 16 TÉCNICAS DE ANÁLISE Comandos de atribuição, de leitura ou de escrita • O(1) Seqüência de comandos • Seqüência de maior tempo Comandos de decisão ou condicional (if) • Condição O(1) + comandos internos • Considerando o pior caso Comandos de repetição (for, while, do-while) • (Condição de parada O(1) + comandos internos ) x número de repetições Módulos não-recursivos (funções) • O tempo de cada módulo, iniciando-se com aqueles que não chamem outros. • Em seguida, tratar estes últimos usando os tempos avaliados anteriormente, repetindo o processo até chegar à parte principal. Módulos recursivos • Associar uma função de complexidade f(n), desconhecida a princípio, e depois obtê-la em termos de uma relação de recorrência. Gerson Borges Estruturas de Dados e Arquivos 17 TÉCNICAS DE ANÁLISE Cuidados ao resolver uma equação de recorrência: • Constantes que multiplicam o lado esquerdo também multiplicarão todos os termos do lado direito; • A constante que multiplicar n do lado esquerdo apenas multiplicará n do lado direito; • Determinar o valor de fim de recursão; • Determinar os limites do somatório; • Testar o resultado. Gerson Borges Estruturas de Dados e Arquivos 18 TÉCNICAS DE ANÁLISE • Supor o programa capaz de ler e ordenar um vetor com n (<= 1000) valores inteiros. – Considere o algoritmo para ordenar os n elementos de um conjunto Vet, cujo príncípio é o seguinte: • Selecione o menor elemento do conjunto • Troque este elemento com o primeiro elemento Vet[0]. • A seguir repita as duas operações acima com os n-1 elementos restantes, depois com os n-2 elementos restantes, até que reste apenas um elemento. Gerson Borges Estruturas de Dados e Arquivos 19 MEDIDA DE TEMPO DE EXECUÇÃO • Linhas 3,4,5 – O (máx(1,1,1)) O(1) – n-i repetições O(n-i) • Linhas 1, 2, 3-5, 6, 7, 8 – O (máx(1,1,n-i,1,1,1)) O(n-i) – n-1 repetições, cada uma com um valor diferente de i O(n2) n 1 n 1 n 1 i 1 i 1 i 1 (n i ) n i n(n 1) n(n 1) n(n 1) 2 2 n2 2 n 2 Gerson Borges void Ordena(int Vet[]) { int i, j, min, tmp; 1 for (i=0; i<n-1; i++) 2 { min = i; 3 for (j=i+1; j<n; j++) 4 { if (Vet[j]<Vet[min]) 5 min:=j; } // troca 6 tmp = Vet[min]; 7 Vet[min] = Vet[i]; 8 Vet[i] = tmp; } } Estruturas de Dados e Arquivos 20 CRESCIMENTO DO TEMPO Problema do caixeiro viajante • percorrer todas as cidades sem repetição com menor distância 4 9 5 • • • • 3 8 8 rotas possíveis: (n-1)! distâncias a somar: n.(n-1)! = n! 4 cidades: 24 distâncias 50 cidades: 1064 distâncias – se a capacidade for de 109 somas por segundo, demora 1045 séculos só para somar! Gerson Borges Estruturas de Dados e Arquivos 21 RECURSIVIDADE void Pesquisa(int n) { if (n <= 1) //verifica um e para else //verifica n elementos Pesquisa(n/3); } • Equação de Recorrência: – T(1) = 1 – T(n) = n + T(n/3), n > 1 Gerson Borges Estruturas de Dados e Arquivos 22 RECURSIVIDADE T ( n) n T (n 3) T (n 3) n 3 T (n 3 3) T (n 3 3) n 3 3 T (n 3 3 3) T ( n) n n 3 n 3 3 n 3 3 3 2 3 n n 3 n 3 n 3 2 3 n1 1 3 1 3 1 3 1 3n n 1 3 n 1 1 3 2 i 0 Gerson Borges i Estruturas de Dados e Arquivos 23 RECURSIVIDADE x • Solução se n 3 1 T ( n) n T (n 3) T (n 3) n 3 T (n 3 3) T (n 3 3) n 3 3 T (n 3 3 3) T ( n) n n 3 n 3 3 T ( n 3 x ) n n 3 n 32 n 3x 1 1 n 1 1 3 1 32 1 3x 1 1 x 1 x x 1 1 3 n n 3 n 1 3i 1 n 1 1 11 3 23 i 0 Gerson Borges n 1 3n 1 1 O ( n) 2/3 2 2 Estruturas de Dados e Arquivos 24