Análise de complexidade

Documentos relacionados
ANÁLISE DE COMPLEXIDADE DOS ALGORITMOS

Algoritmos 3/17/ Algoritmos como área de estudo e investigação

Análise de complexidade

Análise de Complexidade de Algoritmos

5. Análise de Complexidade de Algoritmos. João Pascoal Faria (versão original) Ana Paula Rocha (versão 2003/2004) Luís Paulo Reis (versão 2005/2006)

Algoritmos de pesquisa

Complexidade de algoritmos Notação Big-O

Aula 1. Teoria da Computação III

É interessante comparar algoritmos para valores grandes de n. Para valores pequenos de n, mesmo um algoritmo ineficiente não custa muito para ser

Algoritmo. Exemplo. Definição. Programação de Computadores Comparando Algoritmos. Alan de Freitas

Análise de Algoritmos Estrutura de Dados II

Complexidade de Algoritmos

Medida do Tempo de Execução de um Programa. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Análise e Projeto de Algoritmos

Área que visa determinar a complexidade (custo) de um algoritmo, com isso é possível:

Algoritmos de pesquisa

ESTRUTURAS DE DADOS prof. Alexandre César Muniz de Oliveira

Análise de algoritmos. Parte I

Projeto e Análise de Algoritmos

Análise de Complexidade de Algoritmos. mario alexandre gazziro

INF 1010 Estruturas de Dados Avançadas

Medida do Tempo de Execução de um Programa

Introdução à Ciência da Computação II

ALGORITMOS AVANÇADOS UNIDADE I Análise de Algoritmo - Notação O. Luiz Leão

ANÁLISE DE ALGORITMOS: PARTE 1. Prof. André Backes. Como resolver um problema no computador? Precisamos descrevê-lo de uma forma clara e precisa

Teoria da Computação Aula 9 Noções de Complexidade

CES-11. Noções de complexidade de algoritmos. Complexidade de algoritmos. Avaliação do tempo de execução. Razão de crescimento desse tempo.

Análise de Algoritmos

Complexidade de Algoritmos

ANÁLISE DE COMPLEXIDADE DE ALGORITMOS

Algoritmos Avançados Análise de Complexidade

Complexidade de Algoritmos

2. Complexidade de Algoritmos

Análise de Algoritmos

Algoritmos e Estruturas de Dados I Prof. Tiago Eugenio de Melo

ANÁLISE DE ALGORITMOS: PARTE 3

Teoria da Computação Aula 8 Noções de Complexidade

Introdução à Ciência da Computação II

Algoritmos e Estruturas de Dados I Aula 06 Custos de um algoritmo

Análise de algoritmos Parte I

Módulo 7. Complexidade de Algoritmos. Algoritmos e Estruturas de Dados II C++ Rone Ilídio

Análise de Algoritmos

MCTA028 Programação Estruturada Aula 19 Custos de um algoritmo e funções de complexidade

Quantidade de memória necessária

Medida do Tempo de Execução de um Programa. Bruno Hott Algoritmos e Estruturas de Dados I DECSI UFOP

Medida do Tempo de Execução de um Programa. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

Teoria dos Grafos Aula 7

BCC202 - Estrutura de Dados I

BCC202 - Estrutura de Dados I

Elementos de Análise Assintótica

ESTRUTURA DE DADOS I AULA I

Comportamento Assintótico. Algoritmos e Estruturas de Dados Flavio Figueiredo (

Programação II. Busca em Vetor (search) Bruno Feijó Dept. de Informática, PUC-Rio

Capítulo. Análise de Algoritmos. 6.1 Complexidade de Algoritmos 6.1

Teoria da Computação. Computabilidade e complexidade computacional

Teoria da computabilidade Indecidíveis Decidíveis

01 Análise de Algoritmos (parte 2) SCC201/501 - Introdução à Ciência de Computação II

INF1007: Programação 2 6 Ordenação de Vetores. 01/10/2015 (c) Dept. Informática - PUC-Rio 1

Complexidade Assintótica de Programas Letícia Rodrigues Bueno

AULA 17. Melhores momentos. Segmento de soma máxima. Segmento de soma máxima. Conclusões. Algumas técnicas

COMPLEXIDADE DE ALGORITMOS

Complexidade de Algoritmos

Método BubbleSort. Estrutura de Dados II Prof Jairo Francisco de Souza

Melhores momentos AULA 1. Algoritmos p.38/86

Análise e Complexidade de Algoritmos

Técnicas de projeto de algoritmos: Indução

4. Algoritmos de Busca em Vetores

Análise e Projeto de Algoritmos

Busca em Memória Primária Estrutura de Dados II

BC1424 Algoritmos e Estruturas de Dados I Aula 05 Custos de um algoritmo e funções de complexidade

Projeto e Análise de Algoritmos

Divisão e Conquista. Norton T. Roman. Apostila baseada nos trabalhos de Cid de Souza, Cândida da Silva e Delano M. Beder

O Problema da Ordenação Métodos de Ordenação Parte 1

Classes, Herança e Interfaces

Projeto e Análise de Algoritmos

Técnicas de Projeto de Algoritmos

Transcrição:

Introdução Algoritmo: sequência de instruções necessárias para a resolução de um problema bem formulado (passíveis de implementação em computador) Estratégia: especificar (definir propriedades) arquitectura (algoritmo e estruturas de dados) análise de complexidade (tempo de execução e memória) implementar (numa linguagem de programação) testar (submeter entradas e verificar observância das propriedades especificadas)

Análise de algoritmos Provar que um algoritmo está correcto Determinar recursos exigidos por um algoritmo (tempo, espaço, etc.) comparar os recursos exigidos por diferentes algoritmos que resolvem o mesmo problema (um algoritmo mais eficiente exige menos recursos para resolver o mesmo problema) prever o crescimento dos recursos exigidos por um algoritmo à medida que o tamanho dos dados de entrada cresce

Análise de algoritmos Que dados usar? dados reais: verdadeira medida do custo de execução dados aleatórios: assegura-nos que as experiências testam o algoritmo e não apenas os dados específicos Caso médio dados perversos: mostram que o algoritmo funciona com qualquer tipo de dados Pior caso! dados benéficos: Melhor caso

Complexidade espacial e temporal Complexidade espacial de um programa ou algoritmo: espaço de memória que necessita para executar até ao fim S(n) : espaço de memória exigido em função do tamanho n da entrada Complexidade temporal de um programa ou algoritmo: tempo que demora a executar (tempo de execução) T(n) : tempo de execução em função do tamanho n da entrada Complexidade vs. Eficiência Por vezes estima-se a complexidade para o melhor caso (pouco útil), o pior caso (mais útil) e o caso médio (igualmente útil)

Complexidade temporal Análise precisa é uma tarefa complicada algoritmo é implementado numa dada linguagem a linguagem é compilada e o programa é executado num dado computador difícil prever tempos de execução de cada instrução e antever optimizações muitos algoritmos são sensíveis aos dados de entrada muitos algoritmos não são bem compreendidos Para prever o tempo de execução de um programa apenas é necessário um pequeno conjunto de ferramentas matemáticas

Crescimento de funções O tempo de execução geralmente dependente de um único parâmetro n ordem de um polinómio tamanho de um ficheiro a ser processado, ordenado, etc. ou medida abstracta do tamanho do problema a considerar (usualmente relacionado com o número de dados a processar) Quando há mais do que um parâmetro procura-se exprimir todos os parâmetros em função de um só faz-se uma análise em separado para cada parâmetro

Ordens de complexidade mais comuns Os Algoritmos têm tempo de execução proporcional a 1 : muitas instruções são executadas uma só vez ou poucas vezes (se isto acontecer para todo o programa diz-se que o seu tempo de execução é constante) log n : tempo de execução é logarítmico (cresce ligeiramente à medida que n cresce; quando n duplica log n aumenta mas muito pouco; apenas duplica quando n aumenta para n 2 ) n : tempo de execução é linear (típico quando algum processamento é feito para cada dado de entrada; situação óptima quando é necessário processar n dados de entrada, ou produzir n dados na saída)

Ordens de complexidade mais comuns n log n : típico quando se reduz um problema em subproblemas, se resolve estes separadamente e se combinam as soluções (se n é igual a 1 milhão, n log n é perto de 20 milhões) n 2 : tempo de execução quadrático (típico quando é necessário processar todos os pares de dados de entrada; prático apenas em pequenos problemas, ex: produto de vectores) n 3 : tempo de execução cúbico (para n = 100, n 3 = 1 milhão, ex: produto de matrizes) 2 n : tempo de execução exponencial (provavelmente de pouca aplicação prática; típico em soluções de força bruta; para n = 20, 2 n = 1 milhão; se n duplica, o tempo passa a ser o quadrado)

Ordens de complexidade mais comuns

Notação de O grande Na prática, é difícil (senão impossível) prever com rigor o tempo de execução de um algoritmo ou programa Para obter o tempo a menos de: constantes multiplicativas (normalmente estas constantes são tempos de execução de operações atómicas) parcelas menos significativas para valores grandes de n Identificam-se as operações dominantes (mais frequentes ou muito mais demoradas) e determina-se o número de vezes que são executadas (e não o tempo de cada execução, que seria uma constante multiplicativa) Exprime-se o resultado com a notação de O grande

Notação de O grande Definição: T(n) = O(f(n)) (lê-se: T(n) é de ordem f(n)) se e só se existem constantes positivas c e n 0 tal que T(n) c.f(n) para todo o n > n 0 Esta notação é usada com três objectivos: limitar o erro que é feito ao ignorar os termos menores nas fórmulas matemáticas limitar o erro que é feito na análise ao desprezar parte do programa que contribui de forma mínima para o custo/complexidade total permitir-nos classificar algoritmos de acordo com limites superiores no seu tempo de execução

Notação de O grande Exemplos: c k n k + c k-1 n k-1 +...+ c 0 = O(n k ) (c i - constantes) log 2 n = O(log n) (não se indica a base porque mudar de base é multiplicar por uma constante) 4 = O(1) (usa-se 1 para ordem constante)

Metodologia para determinar a complexidade Considere-se o seguinte código: for i = 1:1:n instruções; A contabilização do número de instruções é simples: n iterações e, em cada uma, são executadas um número constante de instruções O(n)

Metodologia para determinar a complexidade Considere-se o seguinte código: for i = 1:1:n for j = 1:1:n instruções; A contabilização do número de instruções é ainda simples: o ciclo interno (for j) é O(n) e é executado n vezes O(n2)

Eficiência da Pesquisa Sequencial function [resultado] = PesquisaSequencial_1 (Elem, V, tam) i = 1; resultado = -1; % resultado = posição onde esta Elem em V (-1 = nao existe) while i <= tam & resultado == -1 if Elem == V(i) resultado = i; elseif V(i) < Elem i = i + 1; else resultado = -2;

Eficiência da Pesquisa Sequencial Eficiência temporal: A operação realizada mais vezes é o teste da condição de continuidade do ciclo while, que é no máximo n+1 vezes (no caso de não encontrar x o pior caso) Se x existir no vetor, o teste é realizado aproximadamente n/2 vezes (no caso médio) e, 1 vez (no melhor caso) Logo, T(n) = O(n) (linear) no pior caso e no caso médio

Eficiência da Pesquisa Binária Iterativa function [k] = PesquisaBinariaIt (Elem, V, tam) inicio = 1; fim = tam; k = -1; while inicio <= fim & k == -1 meio = floor((inicio + fim) / 2); if Elem == V(meio) k = meio; elseif Elem < V(meio) fim = meio - 1; else inicio = meio + 1;

Eficiência da Pesquisa Binária Eficiência temporal: Em cada iteração, o tamanho do subvetor a analisar é dividido por um fator de aproximadamente igual a 2 Ao fim de k iterações, o tamanho do subvetor a analisar é aproximadamente igual a n/2 k Se não existir no vetor o valor procurado, o ciclo só termina quando n/2 k 1 log 2 n - k 0 k log 2 n No pior caso, o número de iterações é aproximadamente igual a log 2 n. Logo, T(n) = O(log n) (logarítmico)

Eficiência da Ordenação por Borbulhagem function [V] = OrdenarBorbulhagem (V, N) Num_trocas = 1; while Num_trocas ~= 0 Num_trocas = 0; for k = 1:N-1 if V(k) > V(k+1) aux = V(k); V(k) = V(k+1); V(k+1) = aux; Num_trocas = Num_trocas + 1;

Eficiência da Ordenação por Borbulhagem No melhor caso: Apenas 1 execução do ciclo for : n-1 comparações e 0 trocas No total : (n-1) operações O(n) No pior caso: 1ª passagem pelo ciclo for : n 1 comparações e n 1 trocas 2ª passagem pelo ciclo for : n 1 comparações e n 2 trocas... (n-1)-ésima passagem pelo ciclo for: n-1 comparações e 1 troca Total de comparações : (n-1)x(n-1) = n 2 2n + 1 Total de trocas : (n-1) + (n-2) +... + 1 = n(n-1)/2 = (n 2 n)/2 Total de operações : (n 2 2n + 1) + ((n 2 n)/2) O(n 2 )

Eficiência da Ordenação por Borbulhagem function [V] = OrdenarBorbulhagem (V, N) Num_trocas = 1; while Num_trocas ~= 0 Num_trocas = 0; for k = 1:N-1 if V(k) > V(k+1) aux = V(k); V(k) = V(k+1); V(k+1) = aux; Num_trocas = Num_trocas + 1;

Eficiência da Ordenação por Borbulhagem No melhor caso: Apenas 1 execução do ciclo for : n-1 comparações e 0 trocas No total : (n-1) operações O(n) No pior caso: 1ª passagem pelo ciclo for : n 1 comparações e n 1 trocas 2ª passagem pelo ciclo for : n 2 comparações e n 2 trocas... (n-1)-ésima passagem pelo ciclo for: 1 comparação e 1 troca Total de comparações : (n-1) + (n-2) +... + 1 = n(n-1)/2 Total de trocas : (n-1) + (n-2) +... + 1 = n(n-1)/2 Total de operações : 2x(n(n 1)/2) = n(n-1) = (n 2 n) O(n 2 )