Anda di halaman 1dari 37

Aula 6: Introduo

Anlise de Algoritmos
PROF. MAURCIO DUARTE
UNIVEM

Introduo
Sabemos que um algoritmo um conjunto de passos para se
chegar com sucesso a um objetivo;
Para conhecermos um algoritmo, podemos analis-lo, ou seja,
estudar suas especificaes tais como:
o tempo de processamento de um programa como funo
de seus dados de entrada;
quantidade de memria total requerida para os dados do
programa;
comprimento total do cdigo do programa;
se o programa chega corretamente ao resultado desejado;
a complexidade do programa, se fcil de ler, entender e
modificar;
robustez do programa, ou seja, como ele lida com
entradas errneas ou inesperadas.

Introduo
O comportamento de um algoritmo
influencia o seu desempenho;
Basicamente existem dois tipos de
problemas distintos na anlise de algoritmos:

anlise de um algoritmo particular, ou seja, qual


o custo de se usar um determinado algoritmo
para resolver um problema especfico;
anlise de uma classe de algoritmos, ou seja,
qual o algoritmo que apresenta o menor custo na
resoluo de um determinado problema.

Introduo
Maneiras de avaliar o custo computacional de
um algoritmo:
executar o programa em um computador real e medir o
tempo de execuo (Emprica);
atravs de um modelo matemtico (Terica ou
Analtica);

Avaliao Emprica
Implementa-se o algoritmo em um computador e medese o seu tempo de execuo para a resoluo de
algumas instncias do problema.
Assim, pode-se determinar o pior, o caso mdio e o
melhor caso para o volume de dados testado
Entretanto, o tempo gasto vai depender:

Do processador (nmero de operaes executadas por


segundo)
Da linguagem de programao
Etc

Muito pouco usada atualmente

Avaliao Terica ou
Analtica
Consiste em encontrar uma frmula
matemtica que expresse o recurso (por
exemplo, o tempo ou o nmero de operaes
executadas) necessrio para o algoritmo
executar em funo do tamanho dos dados
de entrada.
Esta frmula retrata a ordem de
crescimento do tempo de execuo do
algoritmo em funo do tamanho da entrada

Funo de complexidade de
um algoritmo
Uma funo de complexidade f utilizada para
medir o custo de execuo de um algoritmo;
f(n) uma funo de custo para executar um
algoritmo de tamanho n;
As funes de complexidade podem ser:

Tempo: mede o tempo que um algoritmo leva para


resolver um problema de tamanho n;
Espao: mede o espao ocupado em memria para
resolver um problema de tamanho n;

Complexidade de tempo, no significa o tempo


propriamente dito e sim o nmero de vezes que uma
instruo ou conjunto de instrues so executadas;

Exemplo 1
int maior( int *vet, int n )
{
int j, aux = vet[0];
for( j = 1; j < n; j++ )
if( vet[j] > aux )
aux = vet[j];
return aux;
}

Vamos considerar uma


funo f(n) que o nmero
de comparaes entre os
elementos do vetor;
Dessa forma, o nmero
total de comparaes :
f(n) = n-1, para n > 0;

Funo de complexidade de
um algoritmo
Em anlise de algoritmos destacamos trs
situaes bsicas para determinar a
complexidade: melhor caso, pior caso e o
caso mdio ou esperado;
O melhor caso corresponde ao menor tempo de
execuo sobre todas a entradas possveis de
tamanho n;
O pior caso corresponde ao maior tempo de execuo;
O caso mdio mdia dos tempos de execuo de
todas as entradas de tamanho n;

Exemplo 2
Considere como exemplo a localizao de um
registro em um arquivo. Se f a funo de
complexidade de forma que f(n) representa o
nmero de registros consultados no arquivo,
temos os seguintes casos a considerar:
Melhor caso: f(n) = 1
Pior caso: f(n) = n
Caso mdio: f(n) = (n+1)/2

Exemplo 3
Considere o seguinte trecho de
algoritmo:
n = 1;
while( n <= 1000 )
{
(instrues);
n = n + 1;
}

Qual a funo de
complexidade?

Exemplo 4
Considere o seguinte trecho
de algoritmo:
n = 1;
while( n <= 1000 )
{
(instrues);
n = n + 2;
}

Qual a funo de
complexidade?

Exemplo 5
Considere o trecho de
algoritmo:

Considere o trecho de
algoritmo:

n = 1;

n = 1000;

while( n < 1000 )

while( n >= 1 )

(instrues);

(instrues);

n = n * 2;

n = n / 2;

Qual a funo de complexidade para os trechos acima?

Exemplo 6
Considere o trecho de algoritmo
abaixo:
n = 1;
while( n <= 10 )
{
k = 1;
while( k <= 10 )
{
(instrues);
k = k * 2;
}
n = n + 1;
}

Qual a funo de complexidade?

Exemplo 7
Considere o trecho de algoritmo:
n = 1;
while( n <= 10 )
{
k = 1;
while( k <= 10 )
{
(instrues);
k = k + 1;
}
n = n + 1;
}

Qual a funo de
complexidade?

Exerccio
1.) Para o algoritmo abaixo, escreva a funo de complexidade.
Inicio
inteiro a, b, c=0;
leia (%d, &a);
para (b=1; b<=a; b++)
inicio
c += b;
escreva(%d , b);
fim
escreva(%d, c);
fim

Exerccio
2.) Para o algoritmo abaixo, escreva a funo de complexidade.
Inicio
inteiro a[10][10], i, j, soma=0;
para(i=0; i<10; i++)
para(j = 0; j<10; j++)
inicio
leia (%d, &a[i][j]);
soma += a[i][j];
fim
escreva(%d, soma);
fim

Notao O (micron
Big O)
Em 1968 foi sugerida uma notao para
caracterizar a complexidade de um
algoritmo. Essa inveno ficou conhecida
como notao O;
Para representarmos uma expresso
(composta por vrios termos) em notao
O, devemos levar em considerao a
parte que cresce mais rpido em funo
do argumento da funo. As constantes
so desprezadas na representao;

Comportamento
assinttico de funes
Parmetro n fornece uma medida da
dificuldade para resolver um problema;
Para valores pequenos de n qualquer
algoritmo custa pouco para ser executado;
A anlise de algoritmos leva em
considerao valores grandes de n;
Comportamento assinttico de uma
funo de custo o limite do
comportamento do custo quando n cresce;

Comportamento
assinttico de funes
Relata o crescimento assinttico das operaes consideradas
na anlise de algoritmos;
Uma funo f(n) domina assintoticamente outra funo
g(n) se existem duas constantes positivas c e m tais que,
para n m, tem-se que |g(n)| c|f(n)|.

Notao O
Notao utilizada para representar a dominao assinttica;
Para dizer que uma funo f(n) domina assintoticamente
uma funo g(n) pode-se escrever: g(n) = O(f(n));
A expresso deve ser lida: g(n) da ordem no mximo f(n);
Dizer que o tempo de execuo y(n) de um algoritmo
O(n2) significa que existem constantes c e m tais que, para
valores de n m, |y(n)| c|n2|;

Exemplos
Seja g(n) = n+10 e f(n) = n2
A pergunta : g(n) O(f(n2))? Ou seja, f(n) domina
assintticamente g(n)?
A resoluo consiste em
Intuitivamente pode-se perceber que uma equao
quadrtica e a outra linear
Assim, sabemos (intuitivamente) que a quadrtica domina a
linear.
Entretanto, precisamos encontrar m e a constante c

Exemplos
Uma das formas de resolver atribuir valores s duas funes
e averiguar o comportamento delas

(n+10)

1
2
3
4
5

11
12
13
14
15

Note-se que a funo n2 maior


que (n+10) apenas a partir do n=4

n2
1
4
9
16
25

Assim, pode-se dizer que:

g(n) c.f(n) para c = 1 e m 4


Portanto, g(n) O(f(n)).

Exemplos

g(n)*1000

f(n2)

100

110000

10000

150

160000

22500

Vamos tentar verificar se


g(n+10) domina
assintoticamente f(n2)

200

210000

40000

250

260000

62500

300

310000

90000

350

360000

122500

Isso consiste em encontrar


uma constante c, em que
sua multiplicao por
g(n+10) a torna sempre
maior que n2

400

410000

160000

450

460000

202500

500

510000

250000

550

560000

302500

600

610000

360000

650

660000

422500

700

710000

490000

750

760000

562500

800

810000

640000

850

860000

722500

900

910000

810000

950

960000

902500

1000

1010000

1000000

1050

1060000

1102500

1100

1110000

1210000

1150

1160000

1322500

1200

1210000

1440000

1250

1260000

1562500

1300

1310000

1690000

Mesmo se uma constante grande for


utilizada, por exemplo, 1000, em algum
momento f(n) ser maior
Portanto, f(n) no O(g(n)!

Exemplos de expresses em
notao O
G(n) = n2 + 2n + 1 = O(n2)
G(n) = 3n3 + 2n2 + n = O(n3)
H(n) = n2 + nlogn + n = O(n2)
X(n) = 3n3 = O(n3)
Observao: As funes de complexidade
de tempo so definidas sobre os inteiros no
negativos, ainda que possam ser no
inteiros.

Expresses mais comuns


em notao O
Expresso

Nome

O(1)

Constante

O(log n)

Logartmica

O(n)

Linear

O(n log n)

Linear logartmica

O(n2)

Quadrtica

O(n3)

Cbica

O(2n)

Exponencial

Principais funes de
complexidade
1. f(n) = O(1): O seu uso independe do valor n;
2. f(n) = O(log n): este tipo de execuo ocorre
tipicamente em algoritmos que resolvem um
problema transformando-o em problemas
menores;
3. f(n) = O(n): em geral, um pequeno trabalho
realizado sobre cada elemento de entrada;
4. f(n) = O(n2): ocorre tipicamente em algoritmos
que processam os dados de entrada em pares,
muitas vezes um lao dentro do outro;

Principais funes de
complexidade
5.

O(n log n): ocorre em algoritmos que resolvem


um problema quebrando-o em problemas menores,
resolvendo cada um deles independente e depois
juntando as partes;
f(n) =

6. f(n) = O(n3): so teis apenas para resolver pequenos


problemas;
7. f(n) = O(2n): no so teis do ponto de vista prtico.
Ocorre na soluo de problemas quando se usa a fora
bruta;
8. f(n) = O(n!): o mesmo que O(2n) apesar de ser pior;

Exemplo de crescimento
das funes
n

log2n

n log2n

n2

n3

2n

10

3,32

33

100

1000

1024

100

6,64

664

10.000

1.000.000 1,26x1030

1000

9,97

9970

1.000.000

109

1,07x10301

Tcnicas de Anlise de
Algoritmos
Infelizmente no existe um conjunto de regras
para analisar um programa. Segue alguns
princpios:
O tempo de execuo de um comando de atribuio,
leitura ou de escrita pode ser considerado como O(1);
O tempo de execuo de uma seqncia de comandos
determinado pelo maior tempo de execuo de qualquer
comando da seqncia;

Tcnicas de Anlise de
Algoritmos
O tempo de execuo de um comando de deciso
composto pelo tempo de execuo dos comandos
executados dentro do comando condicional, mais o tempo
para avaliar a condio, que O(1);
O tempo para executar um lao a soma do tempo de
execuo do corpo do lao mais o tempo de avaliar a
condio de trmino, que O(1); multiplicado pelo
nmero de iteraes do lao;

Tcnicas de Anlise de
Algoritmos
Para programas que apresentam procedimentos no
recursivos, o tempo de execuo calculado separadamente
para cada procedimento. O clculo deve iniciar pelos
procedimentos que no chamam outros procedimentos;
Para programas com procedimentos recursivos, para cada
procedimento associado uma funo de complexidade;

Operaes com a
notao O
1.

f(n) = O(f(n))

2.

c O(f(n)) = O(f(n)), onde c uma constante

3.

O(f(n)) + O(f(n)) = O(f(n))

4.

O(O(f(n))) = O(f(n))

5.

O(f(n)) + O(g(n)) = O(max(f(n), g(n)))

6.

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

7.

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

Exemplo 8
Determine a complexidade da funo abaixo:
void f( int a[], int n )
{
int i, j, min, x;
for( i = 0; i <= n 1; i++ )
{
min = i;
for( j = i+1; j <= n; j++ )
if( a[j] < a[min] )
min = j;
x = a[min]; a[min] = a[i]; a[i] = x;
}
}

Soluo...
O primeiro for executado n vezes e o for mais interno
(no pior caso), n-1 vezes. Ento, tem-se:
Pior caso n.(n-1) = n2 - n

Portanto, O (n2)

Complexidade em
procedimentos recursivos
Se existirem procedimentos recursivos em
um algoritmo, o problema deve ser tratado
de forma diferente;
Para cada procedimento recursivo
associada uma funo de complexidade
(f(n)) desconhecida, onde n mede o tamanho
dos argumentos para o procedimento;
Em seguida obtida uma equao de
recorrncia, ou seja, uma expresso
envolvendo a mesma funo;

Exemplo 9
Determine a complexidade do procedimento abaixo:
void pesquisa( int n )
{
if( n <= 1 )
//inspecione elemento e termine
else
for( int i = 1; i <= n; i++ )
{
//inspecione cada um dos elementos
pesquisa( n/3 );
}
}

Anda mungkin juga menyukai