Você está na página 1de 32

Universidade Federal do Par

Instituto de Cincias Exatas e Naturais


Faculdade de Computao

Anlise de Algoritmos

Conceitos bsicos

Nelson Cruz Sampaio Neto


nelsonneto@ufpa.br

www.laps.ufpa.br/nelson
Algoritmos

Podemos descrever um algoritmo de vrias maneiras:

Usando linguagem comum.

Usando uma linguagem de programao de alto nvel: C,


Pascal, Java, etc.
Implementando-o em linguagem de mquina diretamente
executvel em hardware.
Em um pseudo-cdigo de alto nvel.

Usaremos essencialmente pseudo-cdigo nesta disciplina!


Exemplo de pseudo-cdigo

Algoritmo ORDENA-POR-INSERO: rearranja um vetor A [ 1 ... n ]


de modo que fique crescente.
Anlise de algoritmos

O que importante analisar?

Finitude: o algoritmo para?

Corretude: o algoritmo faz o que promete?

Eficincia ou complexidade no tempo: calcula-se o tempo


de execuo do algoritmo (anlise emprica), ou quantas
instrues so executadas em funo do tamanho da
entrada (medida de complexidade).
O algoritmo para
ORDENA-POR-INSERO (A, n)

1 para j = 2 at n faa
...
4 i = j1
5 enquanto i 1 e A[ i ] > chave faa
6 ...
7 i = i1
8 ...

No lao enquanto na linha 5 o valor de i diminui a cada iterao e o valor


inicial i = j 1 1 . Logo, a sua execuo para em algum momento por
causa do teste condicional i 1.

O lao na linha 1 evidentemente para (o contador j atingir o valor n + 1


aps n 1 iteraes). Portanto, o algoritmo para.
Corretude de algoritmos
Um algoritmo est correto se, para toda instncia do problema, ele para e
devolve uma resposta correta.

Usamos o mtodo de loops invariantes para nos ajudar a entender por


que um algoritmo correto. Como?

Inicializao: o invariante verdadeiro antes da primeira iterao do


loop (trivial, em geral).
Manuteno: se o invariante for verdadeiro antes de uma iterao do
loop, ele permanecer verdadeiro antes da prxima iterao.
Trmino: se o algoritmo para e o invariante vale no incio da ltima
iterao, ento o algoritmo correto.

Invariante do algoritmo ORDENA-POR-INSERO: No comeo de cada


iterao do lao para (linhas 18), o vetor A[1 . . . j 1] est ordenado.
Invariantes de lao e provas de corretude

Definio: Um invariante uma propriedade que relaciona as


variveis do algoritmo a cada execuo completa do lao.

O invariante deve ser escolhido de modo que, ao trmino do


lao, tenha-se uma propriedade til para mostrar a corretude
do algoritmo.

Em geral, mais difcil descobrir um invariante apropriado do


que mostrar sua validade se ele for dado de bandeja.
Eficincia de algoritmos

Em geral, no basta saber que um dado algoritmo para e


correto. Se ele for muito lento, ter pouca utilidade.

Queremos projetar algoritmos eficientes (rpidos).

Mas o que seria uma boa medida de eficincia?

Existe um critrio uniforme para comparar algoritmos?

Antes de responder, preciso definir um modelo


computacional de mquina.
Modelo computacional

Simula mquinas convencionais de verdade.

Estabelece quais os recursos disponveis, as instrues


bsicas e quanto elas custam (= tempo).

Com o modelo podemos estimar atravs de uma anlise


matemtica o tempo que um algoritmo gasta em funo do
tamanho da entrada (= anlise de complexidade).

A anlise de complexidade depende sempre do modelo


computacional adotado.
Modelo computacional

Salvo mencionado o contrrio, usaremos sempre o Modelo


Abstrato RAM (Random Access Machine):
Possui um nico processador;

Executa instrues seqencialmente;

Tipos bsicos so nmeros inteiros e reais;

Executa operaes aritmticas, comparaes, movimentao de


dados de tipo bsico e fluxo de controle (teste if / else, chamada
e retorno de rotina) em tempo constante.

Veja maiores detalhes do modelo RAM no Livro Texto.


Complexidade de algoritmos

Agora, vamos analisar a eficincia (ou complexidade no tempo) do


algoritmo que encontra o maior elemento em um vetor.

Basicamente, vamos encontrar o tempo de execuo de cada passo


do algoritmo em funo do tamanho da entrada.

MAXIMO (A, n) Custo #execues


max = A[1] c1 1
para i = 2 at n faa c2 n
se max < A[i] c3 n-1
ento max = A[i] c4 0t n-1
escreve (mximo: max) c5 1
Complexidade de algoritmos

Portanto, o tempo total de execuo T(n) do algoritmo dado por:

T (n) = c1 + c2 n + c3 (n 1) + c4 (n 1) + c5

Este tempo de execuo da forma an + b para constantes a e b que


dependem apenas dos custos.

Em outras palavras, o algoritmo tem como complexidade no tempo


uma funo linear no tamanho da entrada.
Complexidade de algoritmos

Mas em alguns problemas, nem sempre entradas de tamanho igual (i.e.,


mesmo valor de n) apresentam o mesmo tempo de execuo.

Veja o caso da busca linear, cujo algoritmo mostrado abaixo.

LINEAR (A, n, x) Custo #execues


i = 1 c1 1
enquanto ( i n e x A[i] ) faa c2 1tn+1
i = i + 1 c3 0tn
se ( i n ) c4 1
ento escreve (encontrado) c5 0 ou 1
seno escreve (ausente) c6 1 ou 0
Complexidade de algoritmos

No melhor caso, quando o elemento procurado encontra-se na primeira


posio do vetor, o tempo total de execuo T(n) dado por:

T (n) = c1 + c2 + c4 + c5 + c6

Neste caso, o tempo de execuo uma constante e, logicamente, no


depende do tamanho da entrada.

J no pior caso, quando o elemento procurado no encontra-se no


vetor, o tempo total de execuo T(n) dado por:

T (n) = c1 + c2 (n + 1) + c3 n + c4 + c5 + c6

Aqui o tempo de execuo da forma an + b , ou seja, uma funo


linear no tamanho da entrada.
Mtodo de ordenao Bubblesort

O algoritmo SORT para? Por qu?


Qual o loop invariante do algoritmo?
Descreva a complexidade no tempo do algoritmo? Apresente e explique o
grfico (valor de entrada (n) x tempo de execuo) .
Existe pior e melhor caso? Por exemplo, a ordenao inicial do vetor de
entrada influencia na eficincia do algoritmo?

SORT (A, n)
1 para i = 1 at n - 1 faa
2 para j = 1 at n - i faa
3 se A [ j ] > A [ j + 1 ] ento
4 temp = A [ j ]
5 A[j] =A[j+1]
6 A [ j + 1 ] = temp
Mtodo de ordenao Bubblesort
Mtodo de ordenao Bubblesort
Comparando algoritmos

Suponha que o Fulano desenvolveu um algoritmo para resolver o


problema da ordenao por insero, chamado order_Ful.
Agora, suponha que o Beltrano fez outro algoritmo para resolver o
mesmo problema, chamado order_Bel.
Como saber qual dos dois algoritmos mais eficiente?

Podemos cronometrar o tempo?

Sim! Mas no uma boa idia. Por que?


Porque teramos que medir o tempo de order_Ful e order_Bel para
1 elemento, 2 elementos, ..., 10 elementos, ..., 100 elementos, ...,
1000 elementos, ...
Comparando algoritmos

O que feito em geral?

Calcula-se para cada algoritmo quantas instrues so executadas


dado uma entrada de tamanho n (complexidade no tempo).

Suponha que o algoritmo order_Ful executa uma quantidade de


instrues de acordo com a funo: f(n) = n2 + 2n + 1 .

J o outro algoritmo order_Bel tem como complexidade no tempo a


funo: f(n) = 5n + 20 .

Por exemplo, se passarmos 50 elementos para order_Ful, ele far


f(50) = 502 + 2 . 50 + 1 = 2601 instrues. J o order_Bel mais
eficiente, pois executar apenas 270 instrues.
Comparando algoritmos
450

400 n2 + 2n + 1
5n + 20
Quantidade de instrucoes executadas

350

300

250

200

150

100

50

0
0 2 4 6 8 10 12 14 16 18 20
Quantidade de elementos no vetor de entrada
Exemplo
300

n2 + 2n + 1
250
2n
Quantidade de instrucoes executadas

200

150

100

50

0
0 1 2 3 4 5 6 7 8
Tamanho da entrada (n)
Exemplo
3000

n2 + 2n + 1
2500
n2
Quantidade de instrucoes executadas

2000

1500

1000

500

0
0 5 10 15 20 25 30 35 40 45 50
Tamanho da entrada (n)
Comportamento assinttico
Salvo contrrio, considera-se o pior caso, assim como o comportamento
assinttico dos algoritmos (instncias de tamanho grande).

O estudo assinttico nos permite jogar para debaixo do tapete os valores


das constantes e os termos no dominantes.

n 4n + 52 4n
64 308 256
512 2100 2048
2048 8244 8192
4096 16436 16384
8192 32820 32768
16384 65588 65536
32768 131124 131072
Comportamento assinttico
De um modo geral, podemos nos concentrar nos termos dominantes e
esquecer os demais.
Concluses

A complexidade no tempo (= eficincia) de um algoritmo


dado pelo nmero de instrues bsicas que ele executa
em funo do tamanho da entrada.

Adota-se uma atitude pessimista (anlise do pior caso).

A anlise concentra-se no comportamento do algoritmo


para entradas de tamanho GRANDE (anlise assinttica).

Um algoritmo chamado eficiente se a funo que mede


sua complexidade no tempo limitada por um polinmio.

Ex: n , 7n 3 , 14n2 + 4n - 8 , n5
Exerccios

1. Qual o menor valor de entrada n (considere n > 0) tal que um


algoritmo cujo tempo de execuo 10n2 mais rpido que um
algoritmo cujo tempo de execuo 2n na mesma mquina? Qual
dos dois algoritmos voc considera mais eficiente? Por qu?

2. Analise a finitude, a corretude e a complexidade no tempo do script


matlab/octave isprime.m que verifica se o valor de entrada , ou
no, um nmero primo. Existe pior e melhor caso? Quais so eles?

3. Analise a complexidade no tempo do algoritmo ORDENA-POR-


INSERO. Existe pior e melhor caso? Quais so eles? Dica: Esse
estudo feito no Captulo 2 do Livro Texto.
Exerccio 1
4500

4000
10n2
2n
Quantidade de instrucoes executadas

3500

3000

2500

2000

1500

1000

500

0
0 2 4 6 8 10 12
Tamanho da entrada (n)
Exerccio 2

PRIMO ( i )

j=2

enquanto ( j < i e mod ( i , j ) 0 ) faa

j=j+1

fim

se i = j

ento escreva ( primo )


seno escreva ( no primo )

fim
Tempo de execuo (seg)
Exerccio 2

Valor de entrada
Exerccio 3

No melhor caso (vetor totalmente ordenado):

f(n) = c1(n) + c2 (n 1) + c4 (n 1) + c5 (n 1) + c8 (n 1)

O tempo de execuo uma funo linear no tamanho da entrada.


Exerccio 3

No pior caso (vetor em ordem decrescente) o lao enquanto (linha 5)


ser executado j vezes em cada iterao do lao para (linha 1):

2 + 3 + 4 + 5 + ... + n =

O tempo de execuo uma funo quadrtica no tamanho da entrada.


Exerccio 3

Você também pode gostar