Você está na página 1de 57

Tempo de processamento

Um algoritmo que realiza uma tarefa em 10 horas

melhor que outro que realiza em 10 dias

Quantidade de memria necessria


Um algoritmo que usa 1MB de memria RAM

melhor que outro que usa 1GB

Medir o tempo gasto por um algoritmo


No uma boa opo Depende do compilador Pode preferir algumas construes ou otimizar melhor Depende do hardware GPU vs. CPU, desktop vs. smartphone

Estudar o nmero de vezes que operaes so executadas

Achar o mximo de um vetor


int vmax(int *vec, int n) { int i; int max = vec[0]; for(i = 1; i < n; i++) { if(vec[i] > max) { max = vec[i]; } } return max; } 1 n-1 n-1 A < n-1 n-1 n-1 1

Complexidade: f(n) = n-1 Esse algoritmo timo

Anlise de complexidade feita em funo de n


n indica o tamanho da entrada Nmero de elementos no vetor Nmero de vrtices num grafo Nmero de linhas de uma matriz

Diferentes entradas podem ter custo diferente


Melhor caso

Pior caso
Caso mdio

Recuperar um registro num arquivo procurando sequencialmente Quantos registros precisam ser processados em uma busca? Melhor caso: f(n) = 1 Pior caso: f(n) = n Caso mdio: f(n) = (n+1)/2
Supondo que registros procurados esto presentes

no arquivo e que registros so pesquisados com a mesma probabilidade

Problema: encontrar o valores minimo e mximo em um vetor


void minmax(int *vec, int n, int *min, int *max) { int i; int *min = vec[0]; int *max = vec[0]; for(i = 1; i < n; i++) { if(vec[i] < *min) { *min = vec[i]; } if(vec[i] > *max) { *max = vec[i]; melhor caso: f(n) = 2(n-1) } pior caso: f(n) = 2(n-1) } } caso mdio: f(n) = 2(n-1)

1 1 n-1 n-1 A < n-1 n-1 B < n-1 -

Se vec[i] < *min, ento no precisamos checar se vec[i] > *max


void minmax2(int *vec, int n, int *min, int *max) { int i; melhor caso: int *min = vec[0]; int *max = vec[0]; (decrescente) for(i = 1; i < n; i++) { f(n) = n-1 if(vec[i] < *min) { *min = vec[i]; pior caso: } else { (crescente) if(vec[i] > *max) { *max = vec[i]; f(n) = 2(n-1) } caso mdio: } } (aleatrio) }

1 1 n-1 n-1 A < n-1 n-1-A B < n-1-A -

f(n) > 3(n-1)/2

Comparar elementos par-a-par


Custo: n/2 comparaes

Comparar elementos par-a-par


Custo: n/2 comparaes

Elementos vermelhos so maiores que os azuis Encontrar o mximo entre os elementos vermelhos
Custo: n/2 comparaes

Encontrar o mnimo entre os elementos azuis


Custo: n/2 comparaes

1 1 n/2 n/2 n/4 n/4 n/2 A < n/2 n/2 B < n/2 -

void minmax3(int *vec, int n, int *min, int *max) { int i; int *min = INT_MAX; int *max = INT_MIN; for(i = 0; i < n; i += 2) { if(vec[i] < vec[i+1]) { a = i; v = i+1; melhor caso: } else { a = i+1; v = i; f(n) = 3n/2 } pior caso: if(vec[a] < *min) *min = vec[a]; f(n) = 3n/2 if(vec[v] > *max) caso mdio: *max = vec[v]; f(n) = 3n/2 } }

Algoritmo timo

Algoritmo
Melhor caso MinMax1 MinMax2 MinMax3 2(n-1) n-1 3n/2

f(n)
Pior caso 2(n-1) 2(n-1) 3n/2 Caso mdio 2(n-1) > 3(n-1)/2 3n/2

Para valores suficientemente pequenos de n, qualquer algoritmo custa pouco para ser executado, mesmo os ineficientes
Escolha de um algoritmo no um problema crtico

Logo, analisamos algoritmos para grandes valores de n


Estudamos o comportamento assinttico das

funes de complexidade de um programa (comportamento pra grandes valores de n)

Uma funo f(n) domina assintoticamente outra funo g(n) se existem duas constantes positivas c e m tais que, para n m , temos |g(n)| c|f(n)|.

f(n) = n2, g(n) = n


f(n) domina assintoticamente g(n) c = 1, m = 0 |g(n)| 1|f(n)| para todo n m = 0

f(n) = n2, g(n) = (n+1)2


f(n) e g(n) dominam assintoticamente uma outra |f(n)| 1|g(n)| para todo n m = 0 |g(n)| 4|f(n)| para todo n m = 1

Definimos g(n) = O(f(n)) se f(n) domina assintoticamente g(n)


L se g(n) da ordem no mximo f(n)

Quando dizemos que o tempo de execuo de um programa T(n) = O(n2), existem constantes c e m tais que T(n) cn2 para n m

f(n) = (n+1)2 = O(n2)


Pois (n+1)2 4n2, para n m = 1

f(n) = n2 e g(n) = n
n = O(n2), (faa m = 0 e c = 1) Mas n2 no O(n)
Suponha que existam c e m tais que para todo n m, n2 cn Logo n c para todo n m, contradio

f(n) = 3n3 + 2n2 + n = O(n3)


Basta mostrar que f(n) 6n3, para n m = 0 Podemos dizer que f(n) = 3n3 + 2n2 + n = O(n4),

mas essa afirmao mais fraca que f(n) = O(n3)

f(n) = log5(n) = O(log(n))


logb(n) difere de logc(n) por uma constante logb(c) f(n) log5(e)log(n), para todo n m = 0

Imagine um programa com trs fases


A primeira com custo O(n) A segunda com custo O(n2)

A terceira com custo O(n log(n))

Aplicando a regra da soma


O tempo de execuo total do programa O(n2)

Uma funo g(n) (f(n)) se g(n) domina assintoticamente f(n) Notao O denota um limite superior e a notao denota um limite inferior

f(n) = 3n3 + 2n2 + n = (n3)


Basta mostrar que n3 3n3 + 2n2 + n, para n m = 0 Podemos dizer que f(n) = 3n3 + 2n2 + n = (n2), mas

essa afirmao mais fraca que f(n) = (n3)

Uma funo g(n) (f(n)) se g(n) e f(n) dominam assintoticamente uma outra
Definio equivalente: g(n) = (f(n)) se

g(n) = O(n) e g(n) = (f(n))

Notao O um limite assinttico firme Diz que duas funes crescem de forma similar e que a diferena constante

Prove que 4log2(n) + 16 = O(n)

Prove que 4log2(n) + 16 = O(log2n) 2n+1 = O(2n). Verdadeiro ou falso? 22n = O(2n). Verdadeiro ou falso?
Verdadeiro, faa c = 2 e m = 0

4log2(n) + 16 n para n m = 64 = 26

4log2(n) + 16 5log2(n) para n m = 217

Falso. Prova: Suponha 22n c2n, divida por 2n e

obtenha 2n c

Por que falar o tempo de execuo do algoritmo A pelo menos O(2n) no faz sentido?
Um algoritmo com tempo de execuo O(2n)

realiza no mximo c2n operaes. Falar que um algoritmo realiza pelo menos no mximo c2n operaes no faz sentido.

Prove que max(f(n), g(n)) = (f(n) + g(n))


max(f(n), g(n)) 1(f(n) + g(n)) para n m = 0 max(f(n), g(n)) (1/2)(f(n) + g(n)),

para n m = 0

Se f uma funo de complexidade para um algoritmo, ento O(f) considerada a complexidade assinttica do algoritmo Podemos comparar algoritmos usando suas complexidades assintticas
Um algoritmo O(n) melhor do que um O(n2) Algoritmos com a mesma complexidade

assinttica so equivalentes

s vezes, a constante da funo de complexidade de um algoritmo importar


Um algoritmo com complexidade 2n2 melhor

do que um com complexidade 100n para valores de n menores que 50 Quando dois algoritmos tm a mesma complexidade assinttica, podemos desempatar usando a constante da funo de complexidade

Complexidade constante Tempo de execuo do algoritmo independe do tamanho da entrada Os passos do algoritmo so executados um nmero fixo de vezes
Exemplo: determinar se um nmero mpar

Complexidade logartmica Tpico de algoritmos que dividem um problema transformando-o em problemas menores (dividir para conquistar) Tempo de execuo pode ser considerado menor do que uma constante grande
Quando n um milho, log(n) 20 A base do logartmo tem impacto pequeno

Exemplo: busca binria

Complexidade linear O algoritmo realiza um nmero fixo de operaes sobre cada elemento da entrada Melhor situao para um algoritmo que processa n elementos de entrada e produz n elementos de sada
Exemplo: busca sequencial, calcular fatorial

Tpico de algoritmos que dividem um problema em subproblemas, resolve cada subproblema de forma independente, e depois combina os resultados
Exemplo: ordenao (eficiente)

Complexidade quadrtica Tpico de algoritmos que operam sobre pares dos elementos de entrada
Comumente em um anel dentro de outro

til para resolver problemas de tamanhos relativamente pequenos Exemplos: ordenao (ineficiente), imprimir uma matriz

Complexidade cbica til para resolver problemas pequenos Exemplo: multiplicao de matrizes

Complexidade exponencial Tpicos de algoritmos que fazem busca exaustiva (fora bruta) para resolver um problema No so teis do ponto de vista prtico
Quando n 20, O(2n) um milho

Complexidade exponencial
Pior do que O(cn)

No so teis do ponto de vista prtico


Quando n 20, O(n!) maior que 2 quintilhes

(tamanho)

Algoritmo polinomial no tempo de execuo tem funo de complexidade O(f(n)), onde f(n) um polinmio Algoritmos polinomiais geralmente so obtidos atravs de um entendimento mais profundo da estrutura do problema

Um problema considerado

Enquanto algoritmos exponenciais so tpicos de solues fora bruta

Intratvel: se no existe algoritmo polinomial para resolv-lo Bem resolvido: se existe algoritmo polinomial para resolv-lo

Existem algoritmos de complexidade exponencial que so teis


Por exemplo, o algoritmo simplex tem pior caso

de tempo de execuo exponencial, mas na mdia executa muito mais rpido do que isso Infelizmente, estas excees so incomuns e a maioria dos algoritmos exponenciais conhecidos no so muito teis

Um caixeiro viajante deseja visitar n cidades de tal forma que sua viagem inicie e termine em uma mesma cidade Cada cidade deve ser visitada uma nica vez Duas cidades i, j podem ser ligadas por uma estrada de comprimento ci,j O problema encontrar a menor rota para a viagem

A figura abaixo mostra 4 cidades (c1, c2, c3 e c4) e os pesos nas arestas mostram os comprimentos de cada estrada
O percurso c1, c3, c4, c2, c1 a soluo para o problema, cujo percurso total tem distncia 24

Um algoritmo simples seria verificar todas as rotas e escolher a menor delas H (n - 1)! rotas possveis e a distncia total percorrida em cada rota envolve n adies, logo o nmero total de adies n! No exemplo anterior teramos 24 adies; se tivssemos 50 cidades, o nmero de adies seria aproximadamente 1064 Em um computador que executa 109 adies por segundo, o tempo total para resolver o problema com 50 cidades seria maior do que 1045 sculos s para executar as adies

Determinar o tempo de execuo de um algoritmo pode ser complexo Determinar a complexidade assinttica, sem preocupao com as constantes envolvidas, pode ser uma tarefa mais simples Anlise de algoritmos utiliza tcnicas de matemtica discreta
Manipulao de somas, produtos, permutaes,

coeficientes binomiais, equaes de recorrncia

Comando simples (atribuio, comparao, operao aritmtica, acesso a memria): O(1) Sequncia de comandos: mximo dos tempos de execuo dos comandos Comando condicional: tempo dos comandos dentro do condicional mais o tempo pra testar a condio, que O(1) Anel: Tempo de execuo dos comandos do anel mais teste de parada (geralmente O(1)), multiplicado pelo nmero de iteraes

Para funes no recursivas:


Comece pelas funes que no chamam nenhuma

outra funo Depois analise funes que chamam apenas funes analisadas no passo anterior E assim sucessivamente at chegar ao programa principal (main)

- int soma_acumulada(int n) { int i; 1 int acumulador = 0; n for(i = 0; i < n; i++) { n acumulador += i; } 1 return acumulador; - }

Qual a funo de complexidade do nmero de atribuies para o acumulador? Qual a ordem de complexidade da funo soma_acumulada?

- void exemplo(int n) - { int i, j; 1 int a = 0; n for(i = 0; i < n; i++) n(n+1)/2 ? for(j = n; j > i; j--) n(n+1)/2 ? a += i + j; 1 exemplo1(n); - }

Qual a complexidade assinttica da funo exemplo?

Encontre o menor valor no vetor Troque-o com o primeiro elemento V[0] Repita os passos acima com os n-1 itens restantes, depois com os n-2 restantes, at que reste apenas 1

- void ordena(int *V, int n){ int i, j, min, x; n-1 for(i = 0; i < n - 1; i++) { n-1 min = i; n(n-1)/2 for(j = i + 1; j < n; j++) ? n(n-1)/2 if(V[j] < V[min]) ? A < n(n-1)/2 min = j; ? /* troca A[min] e A[i]: */ n-1 x = V[min]; n-1 V[min] = V[i]; n-1 V[i] = x; } Qual a complexidade assinttica - }

do nmero de comparaes?

n n*n n*n n*n*n n*n*n -

// A, B e C sao vetores globais void e1(int n){ int i, j, k; for(i = 0; i < n; i++) for(j = 0; j < n; j++) { C[i][j] = 0; for(k = n-1; k >= 0; k--) { C[i][j] = C[i][j] + A[i][k] * B[k][j]; } } } }

O que faz essa funo? Qual sua complexidade assinttica?

1 n n(n+1)/2 n(n+1)/2 n(n-1)/2 n(n-1)/2 -

void e2(int n) { int i, j, x, y; x = y = 0; for(i = 1; i <= n; i++) { for(j = i; j <= n; j++) x = x + 1; for(j = 1; j < i; j++) y = y + 1; } }

Você também pode gostar