Vous êtes sur la page 1sur 23

Anlise de complexidade

Introduo
Algoritmo: sequncia de instrues necessrias para a resoluo de um problema bem formulado (passveis de implementao em computador) Estratgia:
especificar (definir propriedades) arquitectura (algoritmo e estruturas de dados) anlise de complexidade (tempo de execuo e memria) implementar (numa linguagem de programao) testar (submeter entradas e verificar observncia das propriedades especificadas)

Anlise de complexidade
Anlise de algoritmos
Provar que um algoritmo est correcto Determinar recursos exigidos por um algoritmo (tempo, espao, 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

Anlise de complexidade
Anlise de algoritmos
Que dados usar ?
dados reais: verdadeira medida do custo de execuo dados aleatrios: assegura-nos que as experincias testam o algoritmo e no apenas os dados especficos
Caso mdio

dados perversos: mostram que o algoritmo funciona com qualquer tipo de dados
Pior caso!

dados benficos:
Melhor caso

Anlise de complexidade
Complexidade espacial e temporal
Complexidade espacial de um programa ou algoritmo: espao de memria que necessita para executar at ao fim
S(n) : espao de memria exigido em funo do tamanho n da entrada

Complexidade temporal de um programa ou algoritmo: tempo que demora a executar (tempo de execuo)
T(n) : tempo de execuo em funo do tamanho n da entrada

Complexidade vs. Eficincia Por vezes estima-se a complexidade para o melhor caso (pouco til), o pior caso (mais til) e o caso mdio (igualmente til)

Anlise de complexidade
Complexidade temporal
Anlise precisa uma tarefa complicada
algoritmo implementado numa dada linguagem a linguagem compilada e o programa executado num dado computador difcil prever tempos de execuo de cada instruo e antever optimizaes muitos algoritmos so sensveis aos dados de entrada muitos algoritmos no so bem compreendidos

Para prever o tempo de execuo de um programa


apenas necessrio um pequeno conjunto de ferramentas matemticas

Anlise de complexidade
Crescimento de funes
O tempo de execuo geralmente dependente de um nico parmetro n
ordem de um polinmio tamanho de um ficheiro a ser processado, ordenado, etc. ou medida abstracta do tamanho do problema a considerar (usualmente relacionado com o nmero de dados a processar)

Quando h mais do que um parmetro


procura-se exprimir todos os parmetros em funo de um s faz-se uma anlise em separado para cada parmetro

Anlise de complexidade
Ordens de complexidade mais comuns
Os Algoritmos tm tempo de execuo proporcional a
1 : muitas instrues so executadas uma s vez ou poucas vezes (se isto acontecer para todo o programa diz-se que o seu tempo de execuo constante) log n : tempo de execuo logartmico (cresce ligeiramente medida que n cresce; quando n duplica log n aumenta mas muito pouco; apenas duplica quando n aumenta para n2) n : tempo de execuo linear (tpico quando algum processamento feito para cada dado de entrada; situao ptima quando necessrio processar n dados de entrada, ou produzir n dados na sada)

Anlise de complexidade
Ordens de complexidade mais comuns
n log n : tpico quando se reduz um problema em subproblemas, se resolve estes separadamente e se combinam as solues (se n igual a 1 milho, n log n perto de 20 milhes) n2 : tempo de execuo quadrtico (tpico quando necessrio processar todos os pares de dados de entrada; prtico apenas em pequenos problemas, ex: produto de vectores) n3 : tempo de execuo cbico (para n = 100, n3 = 1 milho, ex: produto de matrizes) 2n : tempo de execuo exponencial (provavelmente de pouca aplicao prtica; tpico em solues de fora bruta; para n = 20, 2n = 1 milho; se n duplica, o tempo passa a ser o quadrado)

Anlise de complexidade
Ordens de complexidade mais comuns

Anlise de complexidade
Notao de O grande
Na prtica, difcil (seno impossvel) prever com rigor o tempo de execuo de um algoritmo ou programa
Para obter o tempo a menos de:
constantes multiplicativas (normalmente estas constantes so tempos de execuo de operaes atmicas) parcelas menos significativas para valores grandes de n

Identificam-se as operaes dominantes (mais frequentes ou muito mais demoradas) e determina-se o nmero de vezes que so executadas (e no o tempo de cada execuo, que seria uma constante multiplicativa) Exprime-se o resultado com a notao de O grande

Anlise de complexidade
Notao de O grande
Definio: T(n) = O(f(n)) (l-se: T(n) de ordem f(n)) se e s se existem constantes positivas c e n0 tal que T(n) c.f(n) para todo o n > n0 Esta notao usada com trs objectivos:
limitar o erro que feito ao ignorar os termos menores nas frmulas matemticas limitar o erro que feito na anlise ao desprezar parte do programa que contribui de forma mnima para o custo/complexidade total permitir-nos classificar algoritmos de acordo com limites superiores no seu tempo de execuo

Anlise de complexidade
Notao de O grande
Exemplos:
ck nk+ ck-1 nk-1 +...+ c0 = O(nk) (ci - constantes) log2 n = O(log n) (no se indica a base porque mudar de base multiplicar por uma constante) 4 = O(1) (usa-se 1 para ordem constante)

Anlise de complexidade
Metodologia para determinar a complexidade
Considere-se o seguinte cdigo: for (i = 0; i < n; i++) { Instrues; } A contabilizao do nmero de instrues simples: n iteraes e, em cada uma, so executadas um nmero constante de instrues O(n)

Anlise de complexidade
Metodologia para determinar a complexidade
Considere-se o seguinte cdigo: for (i = 0; i < n; i++) for (j = 0; j < n; j++) { Instrues; } A contabilizao do nmero de instrues ainda simples: o ciclo interno (for j) O(n) e executado n vezes O(n2)

Anlise de complexidade
Eficincia da Pesquisa Sequencial
int PesquisaSequencial (int x, int V[], int n) { int i = 0, k = -1; // k = posio onde se encontra x em V while ( (i < n) && (k == -1) ) if (x == V[i]) k = i; else if (V[i] < x) i = i + 1; else k = -2; return (k); }

Anlise de complexidade
Eficincia da Pesquisa Sequencial
Eficincia temporal:
A operao realizada mais vezes o teste da condio de continuidade do ciclo for, que no mximo n+1 vezes (no caso de no encontrar x o pior caso) Se x existir no array, o teste realizado aproximadamente n/2 vezes (no caso mdio) e, 1 vez (no melhor caso)

Logo, T(n) = O(n) (linear) no pior caso e no caso mdio

Anlise de complexidade
Eficincia da Pesquisa Sequencial
Eficincia espacial:
Gasta o espao das variveis locais (incluindo argumentos) Como os arrays so passados por referncia (na linguagem C, o que passado o endereo do primeiro elemento do array), o espao ocupado pelas variveis locais constante e independente do tamanho do array Logo, S(n) = O(1) (constante) em qualquer caso

Anlise de complexidade
Eficincia da Pesquisa Binria
int PesquisaBinaria (int x, int V[], int n) { int inicio = 0, fim = n 1, meio, k = -1; while ( (inicio <= fim) && (k == -1) ) { meio = (inicio + fim) / 2; if (x == V[meio]) k = meio; else if (x < V[meio]) fim = meio - 1; else inicio = meio + 1; } return (k); }

Anlise de complexidade
Eficincia da Pesquisa Binria
Eficincia temporal:
Em cada iterao, o tamanho do sub-array a analisar dividido por um factor de aproximadamente igual a 2 Ao fim de k iteraes, o tamanho do sub-array a analisar aproximadamente igual a n/2k Se no existir no array o valor procurado, o ciclo s termina quando n/2k 1 log2 n - k 0 k log2 n No pior caso, o nmero de iteraes aproximadamente igual a log2 n. Logo, T(n) = O(log n) (logartmico)

Anlise de complexidade
Eficincia da Ordenao por Borbulhagem
void Ordenar_Borbulagem (int V[], int n) { int k, Num_trocas, aux; do{ Num_trocas = 0; for (k = 0; k < n-1; k++) if (V[k] > V[k+1]) { aux = V[k]; V[k] = V[k+1]; V[k+1] = aux; Num_trocas++; } }while (Num_trocas != 0); }

Anlise de complexidade
Eficincia da Ordenao por Borbulhagem
No melhor caso:
Apenas 1 execuo do ciclo for : n-1 comparaes e 0 trocas No total : (n-1) operaes O(n)

No pior caso:
1 passagem pelo ciclo for : n1 comparaes e n1 trocas 2 passagem pelo ciclo for : n1 comparaes e n2 trocas ... (n-1)-sima passagem pelo ciclo for: n-1 comparaes e 1 troca Total de comparaes : (n-1)x(n-1) = n2 2n + 1 Total de trocas : (n-1) + (n-2) + ... + 1 = n(n-1)/2 = (n2 2n)/2 Total de operaes : (n2 2n + 1) + ((n2 2n)/2) O(n2)

Anlise de complexidade
Eficincia da Ordenao por Borbulhagem
void Ordenar_Borbulagem_Opt (int V[], int n) { int k, kk, fim = n-1, aux; do{ kk = 0; for (k = 0; k < fim; k++) if (V[k] > V[k+1]) { aux = V[k]; V[k] = V[k+1]; V[k+1] = aux; kk = k; } fim = kk; }while (kk != 0);

Anlise de complexidade
Eficincia da Ordenao por Borbulhagem
No melhor caso:
Apenas 1 execuo do ciclo for : n-1 comparaes e 0 trocas No total : (n-1) operaes O(n)

No pior caso:
1 passagem pelo ciclo for : n1 comparaes e n1 trocas 2 passagem pelo ciclo for : n2 comparaes e n2 trocas ... (n-1)-sima passagem pelo ciclo for: 1 comparao e 1 troca Total de comparaes : (n-1) + (n-2) + ... + 1 = n(n-1)/2 Total de trocas : (n-1) + (n-2) + ... + 1 = n(n-1)/2 Total de operaes : 2x(n(n1)/2) = n(n-1) = (n2n) O(n2)

Vous aimerez peut-être aussi