Você está na página 1de 22

Algoritmos e Estruturas de

Dados
2010/2011
Luis Antunes

Anlise de
Algoritmos
Fac. Cincias Univ. Lisboa

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Eficincia de Algoritmos
!

Em Java no fcil medir a quantidade de tempo que


um programa leva a executar.
Primeiro carrefado o JVM (Java Virtual Machine)
!
Depois o ficheiro .class, depois outros ficheiros .class
! E finalmente o programa executa
! Se for num IDE (integrated development environment)
ainda pode ser anteriormente compilado o ficheiro.
!

! Logo, tenta-se aproximar o efeito das mudanas no

nmero de itens de dados (n) que o algoritmo processa.

Comparamos 2 algoritmos comparando as taxas de


crescimento (com n).
Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Eficincia
!

Muitos algoritmos bvios so ineficientes


! Mas podem servir para instncias simples dos problemas

! Outros algoritmos tm uma taxa de crescimento to

grande que, mesmo com os modernos computadores,


cada vez mais rpidos e com memrias maiores, no
conseguem executar.

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

O crescimento das funes


! Dada a funo f(n), como cresce se aumentarmos n?
n
1
2
3
4
5
6
7
8
9

2*n
2
4
6
8
10
12
14
16
18

f(n)
n^2 n^3
1
1
4
8
9
27
16 64
25 125
36 216
49 343
64 512
81 729

9000

e^n
2,7
7,4
20,1
54,6
148,4
403,4
1096,6
2981,0
8103,1

8000
7000
6000

2n

5000

n^2

4000

n^3

3000

e^n

2000
1000
0
1

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

O crescimento das funes


! Este assunto relevante para grandes problemas
!
!

Mesmo maus algoritmos podem servir em pequenas tarefas...


Vamos ignorar detalhes de implementao e focar apenas os
pontos relevantes do algoritmo em questo

Primeiro, quantificamos o crescimento de funes em


relao a outras funes.
!

Para depois poder comparar o tempo (memria) que demora


(ocupa) um dado algoritmo a resolver problemas
progressivamente maiores, com o crescimento de certas
funes (por exemplo f(n) = n, f(n) = n3, f(n) = en...)

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Exemplo: procura num array


! Se o target no

estiver presente, o
ciclo for executado
x.length vezes

! Se o target estiver presente, pode estar em qualquer

stio.

Assim, em mdia o ciclo ser executado x.length/2


vezes

! O tempo de execuo proporcional a x.length

Luis Antunes Introduo Programao 2010-2011

Fac. Cincias
Univ. Lisboa

Exemplo: ver se h elementos


em comum
! O corpo do ciclo

executado x.length
vezes.
! Mas invoca o search, que executado y.length vezes

para cada uma das x.length vezes


! A execuo total proporcional ao produto de y.length

por x.length

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Exemplo: ver se cada elemento


nico
! Se todos os elementos

forem nicos, o ciclo


i executado x.length
vezes
!

Dentro deste, o ciclo


j executado tambm
x.length vezes

! Logo o corpo do ciclo interior executado (x.length)2

vezes.
Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Verso mais eficiente


! Na primeira vez no

ciclo j, h x.length-1
vezes
! Na segunda vez

x-.length-2 vezes
! Na ltima vez, apenas 1
! O nmero total n x (n-1)/2 (com n = x.length vezes)

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Notao O ( grande)
!

Definio:
!

Sejam duas funes f, g: .


A funo g domina assimptoticamente f,
escrevendo-se f O(g), sse,
k C n : n>k |f(n)| C.|g(n)|
Ou seja, existe um par de constantes naturais k e C, tal que, a
partir de um dado argumento n>k, a funo g sempre maior
que f.
! Isto determina um limite superior ao crescimento da funo f.

De notar que O(g) representa um conjunto de funes que so


limitadas superiormente por g. O(g) diz-se uma classe de
complexidade.
! Dizer f O(g) ou f de ordem g dizer f O(g).
! f O(g) O(f) O(g)
Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Notao O Exemplos
1000000 O(1)
4.m 1 O(m)
10/n O(1/n)
5.x2 O(x3)
5.x2 O(x2)
5.x2 no O(x)
500.n4 n2 O(n4)
500.n4 + n2 O(n4)
n2.log10(n) O(n2.log(n))
45.2n O(en)
e 2.71828...
6n no O(5n)

Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Notao O
! Para comparar algoritmos da mesma classe de complexidade

pode ser til apresentar um maior detalhe da funo de


crescimento. Por exemplo, f(n) = n2 + n.log(n) cresce mais
depressa que g(n) = n2 + n, apesar de f e g serem O(n2)

! A constante do factor de maior crescimento tambm e til

nessa comparao. Por exemplo, a funo f(n) = n2/10 cresce


mais devagar que g(n) = 10.n2

! Em casos que na prtica ocorrem raramente, as constantes

das funes podem ser relevantes na comparao de


algoritmos de classes distintas. Por exemplo, a funo f(n) =
2n/100000 menor que a funo g(n) = n100000 para um
extenso conjunto da valores de n, apesar de g ser O(f) e
f no ser O(g)
Luis Antunes
Algoritmos e Estruturas de Dados 2010-2011

Fac. Cincias
Univ. Lisboa

Algumas Propriedades
Seja a funo F de ordem O(f) e G de ordem O(g)
F de ordem O(F)
Exemplo: 5.n2 + 4.n 300 O( 5.n2 + 4.n 300 )
c.F, com c uma constante, de ordem O(f)
Exemplo: O( 5000.n2 ) = O( n2 )
F + G de ordem O( f + g )
Exemplo: O( n2 ) + O( n ) = O( n2 + n ) = O( n2 )
F G de ordem O(f g)
Exemplo: O( n2 ) O( n3 . log n) = O( n5 . log n)
se F O(G) ento O( f + g ) = O( g )

Algoritmos e Estruturas de Dados DI - FCUL

Classes de Complexidade
Algumas classes de complexidade importantes (e progressivamente mais
abrangentes):
Constante, O(1)
Logartmica, O(log n)
Linear, O(n)
Pseudo-linear, O(n. log n)
Quadrtica, O(n2)
Polinomial, p1 O(np)
Exponencial, p>1 O(pn)
Factorial, O(n!) (n/e)n. 2n

Algoritmos e Estruturas de Dados DI - FCUL

Comparao de funes

Luis Antunes Introduo Programao 2010-2011

Fac. Cincias
Univ. Lisboa

Tempo vs. Espao


A complexidade temporal determina o nmero aproximado de
operaes necessrias para resolver um problema de dimenso n.
A complexidade espacial determina a memria aproximadamente
necessria para resolver um problema de dimenso n.
Estas complexidades podem ser analisadas no cenrio:
do melhor caso possvel (best-case)
do pior caso possvel (worst-case)
do caso mdio (average-case), para o qual se considera uma
distribuio probabilstica associada aos dados de entrada.
Quando nada se sabe, assume-se uma distribuio uniforme.

Algoritmos e Estruturas de Dados DI - FCUL

Anlise de Programas
A complexidade temporal de um programa pode ser determinada
analisando a sua estrutura. Como uma linguagem de programao possui
uma sintaxe e uma semntica bem definidas, a tarefa facilitada.
Considerase o pior caso, i.e., escolhese sempre a opo que implique no
nmero mximo de instrues. Procedese da mesma forma para o clculo
da complexidade espacial.
Existe um conjunto de comandos cuja complexidade temporal constante,
i.e., pertencem classe O(1):
Declaraes
Atribuies
Acessos aos mtodos
Uso das operaes aritmticas, lgicas e relacionais dos tipos de
dados primitivos

Algoritmos e Estruturas de Dados DI - FCUL

Anlise de Programas
Em relao aos restantes comandos, considere a guarda G O(fG), os
comandos A O(fA), B O(fB) e C O(fC) e N como o nmero de
iteraes mximo de cada ciclo:

A; B;

O( fA + fB )

if (G) A else B;

O( fG + fA + fB )

while (G) A;

O( N . ( fG + fA ) )

do A while (G);

O( N . ( fG + fA ) )

for (B;G;C) A;

O( fB + N . ( fG + fA + fC ) )

Algoritmos e Estruturas de Dados DI - FCUL

Um exemplo
Qual a complexidade do seguinte cdigo?
1 int x=0;
2 for(int i=0; i<n; i++)
3
for(int j=0; j<n; j++)
4
x=x+1;
1
4
3-4
2-4
1-4

->
->
->
->
->

O(1) uma declarao e inicializao


O(1) um clculo de expresso e uma atribuio
O(1+n(1+1+1)) = O(1+3n) = O(n)
um ciclo for
O(1+n(1+1+n)) = O(1+2n+n2) = O(n2) um ciclo for
O(1+n2) = O(n2) o cdigo a sequncia de duas instrues

principais

Algoritmos e Estruturas de Dados DI - FCUL

Um exemplo mais complicado...


Seja f(v) o nmero de instrues executadas por este mtodo. Qual a
sua complexidade temporal?
void slowSort( int[] v ) {
for(int i=0; i<v.length; i++)
for(int j=i+1; j<v.length; j++)
if (v[j] < v[i]) {
swap = v[i];
v[i] = v[j];
v[j] = swap;
}
}

Para a n-sima passagem pelo vector no primeiro ciclo, o segundo ciclo


percorre v.length-n, i.e., a soma total de trocas de variveis de (v.length
1)+(v.length2)+...+1 = v.length.(v.length1)/2. Logo f(v) O(v.length2)
Algoritmos e Estruturas de Dados DI - FCUL

Outro exemplo
Dado o seguinte cdigo, qual a sua complexidade temporal?
//@ requires domain.length == images.length

boolean isInjective(int[] domain, int[] images) {


slowSort( images );
for(int i=1; i<images.length; i++)
if (images[i-1] == images[i])
return false;
return true;
}

Nesta funo, existem duas tarefas (a) ordenar o vector images, (b)
comparar os elementos desse vector, para verificar se existe algum
igual. Quais as suas complexidades?
Qual a complexidade total?

Algoritmos e Estruturas de Dados DI - FCUL

Você também pode gostar