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;
}

Complexidade: f(n) = n-1


Esse algoritmo timo

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

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

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

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)

Se vec[i] < *min, ento no precisamos


checar se vec[i] > *max

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

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)
}

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

f(n)

Algoritmo
Melhor caso

Pior caso

Caso mdio

MinMax1

2(n-1)

2(n-1)

2(n-1)

MinMax2

n-1

2(n-1)

> 3(n-1)/2

MinMax3

3n/2

3n/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)

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

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

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

2n+1 = O(2n). Verdadeiro ou falso?


Verdadeiro, faa c = 2 e m = 0

22n = O(2n). Verdadeiro ou falso?


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

Enquanto algoritmos exponenciais so tpicos de


solues fora bruta

Um problema considerado

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