Complexidade de Algoritmos
!
Uma característica importante de qualquer
algoritmo é seu tempo de execução
! é possível determiná-lo através de métodos
empíricos, considerando-se entradas diversas
! é também possível obter este tempo a partir
de métodos analíticos
1
Complexidade de Algoritmos
!
Métodos analíticos
! objetivo: determinar uma expressão
matemática que traduza o comportamento
de tempo de um algoritmo.
! o tempo de execução independente:
!
!
!
do método utilizado
da linguagem e compiladores empregados
e das condições locais de processamento
2
Complexidade de Algoritmos
!
!
obter uma expressão matemática não é
simples, mesmo considerando uma expressão
aproximada
Várias simplificações são introduzidas
! quantidade de dados a serem manipulados
pelo algoritmo é suficientemente grande
! quantidade de dados de entrada reduzida
não serão considerados
3
Complexidade de Algoritmos
!
!
somente o comportamento assintótico é
avaliado
não serão consideradas constantes aditivas
ou multiplicativas na expressão considerada
4
Complexidade de Algoritmos
!
Qual a variável em relação à qual a expressão
matemática avaliará o tempo de execução?
!
!
Um algoritmo funciona a partir de uma entrada para
produzir uma saída dentro de um tempo
fornecer o tempo de execução em função da entrada
5
Complexidade de Algoritmos
!
O processo de execução de um algoritmo pode
ser dividido em etapas elementares - passos
! um número fixo de operações básicas cujo
tempo de execução é considerado constante
! a operação básica de maior freqüência de
execução do algoritmo é denominada
operação dominante
6
Complexidade de Algoritmos
!
expressão de tempo de execução
!
!
obtida a menos de constantes aditivas e multiplicativas:
número de passos
!
!
≅ número de execuções da operação dominante
A expressão matemática de avaliação do tempo de
execução de um algoritmo
!
função que fornece o número de passos efetuados no algoritmo
a partir de uma certa entrada
7
Complexidade de Algoritmos
!
Por exemplo: algoritmos para ordenar
elementos de uma seqüência dada
!
!
os
cada passo corresponde a comparação entre dois
elementos da seqüência
O número de passos de um algoritmo
!
informação
necessária
comportamento no tempo
para
avaliar
8
seu
Complexidade de Algoritmos
!
Inversão de uma seqüência
fim = n/2;
for (i=0; i<fim; i++)
{
temp = S[i];
S[i] = S[n-1-i];
S[n-1-i] = temp;
}
9
Complexidade de Algoritmos
!
n = 5 ⇒ troca S[i] por S[n-1-i]
fim = 2
! i = 0 ⇒ troca S[0] por S[5-1-0] (S[4])
! i = 1 ⇒ troca S[1] por S[5-1-1] (S[3])
!
inicial
0
1
final
2
3
4
0
1
2
3
M A R
I
A
A I
R
A M
10
4
Complexidade de Algoritmos
!
n = 6 ⇒ troca S[i] por S[n-1-i]
!
!
!
!
fim = 3
i = 0 ⇒ troca S[0] por S[6-1-0] (S[5])
i = 1 ⇒ troca S[1] por S[6-1-1] (S[4])
i = 2 ⇒ troca S[2] por S[6-1-2] (S[3])
inicial
final
0
1
2
3
4 5
E
S
T
A D O
0
1
2
O D A
3
4
5
T S
E
11
Complexidade de Algoritmos
!
n = 50 ⇒ troca S[i] por S[n-1-i]
fim = 25
! i = 0 ⇒ troca S[0] por S[50-1-0] (S[49])
! i = 1 ⇒ troca S[1] por S[50-1-1] (S[48])
! i = 2 ⇒ troca S[2] por S[50-1-2] (S[47])
.........
! i = 23 ⇒ troca S[23] por S[50-1-23] (S[26])
! i = 24 ⇒ troca S[24] por S[50-1-24] (S[25])
!
12
Complexidade de Algoritmos
!
o algoritmo executa extamente as mesmas
operações para seqüências de tamanho n
! cada passo corresponde à troca de posição
entre dois elementos da seqüência
!
!
a execução das três atribuições
o número de passos é igual ao número de
vezes que executa o bloco for ⇒ n/2, n>1
13
Complexidade de Algoritmos
!
Problema: determinar a soma C e o produto
D de duas matrizes dadas A e B.
A = (aij) e B = (bij) ambas n x n
! C e D também serão matrizes n x n
! seus elementos podem ser calculados como:
⇒ cij = aij + bij
!
⇒ dij = ∑aik * bkj
1≤k ≤ n
14
Complexidade de Algoritmos
!
Soma
for(i=0; i<n; i++)
for(j=0; j<n; j++)
cij = aij + bij ;
!
Produto
for(i=0; i<n; i++)
for(j=0; j<n; j++){
dij = 0;
for(k=0; k<n; k++)
dij = dij + aik* bkj;
}
15
Complexidade de Algoritmos
!
Seja A um algoritmo
!
!
{E1, ....Em} o conjunto de todas as entradas
possíveis de A
seja ti o número de passos efetuados por A
quando a entrada for Ei
16
Complexidade de Algoritmos
!
Complexidade do pior caso:
max
!
{ti }
Complexidade do melhor caso:
min
!
Ei ∈ E
{ti }
Ei ∈ E
Complexidade do caso médio:
Σ
!
1≤i ≤ m
piti
pi é a probabilidade de ocorrência da entrada Ei
17
Complexidade de Algoritmos
!
De forma análoga podem ser definidas
complexidades de espaço de um algoritmo
!
complexidade tem por objetivo avaliar a eficiência
de tempo ou espaço
18
Complexidade de Algoritmos
!
Complexidade de tempo do pior caso
!
para a entrada mais desfavorável
!
é a mais importante das três mencionadas
!
fornece um limite superior para o número de
passos
19
Complexidade de Algoritmos
!
Complexidade de pior caso
!
Complexidade de melhor caso
!
!
de uso bem menos freqüente
!
em algumas situações específicas
Complexidade de caso médio
!
!
menos utilizada apesar de importante
difícil conhecer a distribuição de probabilidades
das diferentes entradas
20
Recursividade
!
!
um procedimento recursivo é aquele que contém
uma ou mais chamadas a si mesmo
a todo procedimento recursivo corresponde um não
recursivo
!
os programas recursivos são mais concisos
!
relação direta com a prova por indução matemática
21
Recursividade
!
Cálculo de fatorial
x! = se (x <=0) então 1 senão x * (x-1)!
22
Recursividade
Implementação não recursiva
x! = se x <=0 1 senão x * (x-1)!
int fatorial (int N)
{
int result = 1;
for (i=1; i<=N; i++)
result = result * i;
return (result);
}
23
Recursividade
Implementação recursiva
x! = se x <=0 1 senão x * (x-1)!
int fatorial (int N)
{
if (N<= 1)
return(1);
else
return( N * fatorial(N-1));
}
24
Recursividade
!
X= fatorial (4)
return(
! return(
! return(
! return(
!
4* fatorial(3) )
3* fatorial(2) )
2* fatorial(1) )
1 )
25
Análise de Recursividade
!
relação de recorrência
!
!
a função é definida em termos dela própria, recursivamente
substituição repetida
int fatorial (int N)
{
if (N<= 1)
return(1);
else
return( N * fatorial(N-1));
}
26
Análise de Recursividade
int fatorial (int N)
{
if (N<= 1)
return(1);
else
return( N * fatorial(N-1));
}
27
Análise de Recursividade
T(n)
!
!
tempo de processar o algoritmo para entrada n
número de passos ou operações dominantes
Fatorial
T(n) = 1,
= T(n-1) + 1,
mas quanto é T(n-1) ?
se n = 0
se n > 0
int fatorial (int N)
{
if (N<= 1)
return(1);
else
return( N * fatorial(N-1));
}
28
T(n) - Fatorial
Passos
= (T(n-1)) + 1
iteração
- 1ª substituição
= (T(n-2) + 1) + 1
= T(n-2) + 2
29
T(n) - Fatorial
Passos
= (T(n-1)) + 1
iteração
- 1ª substituição
= (T(n-2) + 1) + 1
= T(n-2) + 2
- 2ª substitição
= (T(n-3) + 1) + 2
= T(n-3) + 3
30
T(n) - Fatorial
Passos
= (T(n-1)) + 1
iteração
- 1ª substituição
= (T(n-2) + 1) + 1
= T(n-2) + 2
- 2ª substitição
= (T(n-3) + 1) + 2
= T(n-3) + 3
- 3ª substituição
31
T(n) - Fatorial
Passos
= (T(n-1)) + 1
iteração
- 1ª substituição
= (T(n-2) + 1) + 1
= T(n-2) + 2
- 2ª substitição
= (T(n-3) + 1) + 2
= T(n-3) + 3
- 3ª substituição
.....
....
= T(n-k) + k
- k-ésima substituição
32
T(n) - Fatorial
!
!
Então, T(n) = T(n-k) + k, 1 ≤ k ≤ n
se a k-ésima interação é a última, então:
!
n-k = 0 e T(0) = 1
!
Assim, n = k, e T(n) = n + 1
33
Maior elemento de uma lista
maior = a[0];
for ( i =0; I < N; i++)
if (maior < a[i]) maior = a[i];
return (maior);
34
Resolva as recorrências
!
T(n)
!
T(n)
!
T(n)
=
=
=
=
=
=
1,
2 T(n-1) + 1,
1
T(n/2) + 1
1
2T(n/2) - n
se
se
se
se
se
se
35
n=0
n >0
n=1
n>1
n=1
n>1
Qual melhor algoritmo?
!
!
Sejam A e B dois algoritmos que o resolvem o
problema P, cujos tempos de execução são
TA(n) e TB(n)
comportamento assintótico – tamanho da
entrada arbitrariamente grande
!
caracterizado pela notação O (big O)
36
A notação
!
Ο
Sejam f(n) e h(n) funções reais não negativas
da variável inteira n ≥ 0
! f(n)
= O (h(n)) quando existir uma
constante c> 0 e um valor inteiro no tal
que
n > no ⇒ f(n) ≤ c.h(n)
37
A notação
Ο
f(n) = 8n + 128 ⇒ é O (n2)?
f(n) ≤ c.n2 ?
! Seja c =1
8n + 128 ≤ n2, então
0 ≤ n2 – 8n – 128
0 ≤ (n – 16)(n+8) ⇒ n0 = 16
⇒ c =1, no = 16, f (n) ≤ c.n2 para todo n ≥ n0
38
A notação
!
!
Ο
Tempo (ou espaço) é contabilizado em número de
passos do algoritmo (unidade de armazenamento)
Análise do algoritmo determina uma função que
depende do tamanho da entrada n.
10n3 + 4n -10
! à medida que n aumenta, o termo cúbico começa
a dominar
! A constante do termo cúbico tem relativamente a
mesma importância que a velocidade da CPU
39
A notação
!
Ο
Complexidade de pior caso
!
desprezar constantes aditivas ou multiplicativas
!
!
número de passos 3n será aproximado para n
interesse assintótico: termos de menor grau
podem ser desprezados:
!
!
n2 + n será aproximado para n2
6n3 + 4n - 9 será aproximado para n3
40
A notação
!
Ο
A função atua como um limite
assintótico da função f
2
! f = n -1
⇒
2
! f = n -1
⇒
! f = 403
⇒
2
! f = 5+2logn +3log n
⇒
2
! f = 5+2 log n +3log n ⇒
n
10
! f = 5.2 +5n
⇒
superior
f
f
f
f
f
f
=
=
=
=
=
=
41
Ο(n2)
Ο(n3)
Ο(1)
Ο(log2n)
Ο(n)
Ο(2n)
A notação
!
!
!
Ο
g(n), h(n) - funções reais positivas
k - constante
f1(n) = g(n) e f2(n) = h(n)
O(g+h) = O(g) + O(h)
! O(k*g) = k O(g) = O(g)
! f1(n) + f2(n) = O(max {g(n), h(n)})
! f1(n) * f2(n) = O(g(n) * h(n))
!
42
A notação
!
Ο
O algoritmo de inversão de uma seqüência:
!
!
!
o número de passos se mantém o mesmo para o
mesmo valor de n
variável independente é n
as complexidades de pior, melhor e pior casos são
iguais
43
A notação
!
Para a inversão
!
!
Ο
efetua sempre n/2 passos então sua
complexidade é Ο(n)
Para a soma e o produto de matrizes n x n
verifica-se complexidades
2
3
! Ο(n ) e Ο(n ) respectivamente
44
A notação
!
Ο
Para procedimentos recursivos pode-se
aplicar a seguinte técnica
! determina-se o número total de chamadas
ao procedimento recursivo
! calcula-se a complexidade de execução de
uma única chamada
! complexidade
número de chamadas × complexidade de uma chamada
45
A notação
!
Ο
por outro lado, um outro exemplo:
! duas matrizes A e B de dimensões n x n
! um parâmetro x, com valores 0 ou 1
! dependendo do valor de x
!
!
calcula a soma: se x =0 " A + B
ou o produto das matrizes: se x = 1" A * B
46
A notação
!
!
entrada: n2+1 informações - tamanho O(n2)
se x =0 então complexidade: O(n2)
!
!
Ο
complexidade do melhor caso
se x = 1 então complexidade: O(n3)
!
complexidade do pior caso
47
Alguns conceitos
!
!
!
!
!
!
!
!
T
T
T
T
T
T
T
T
(n)
(n)
(n)
(n)
(n)
(n)
(n)
(n)
=
=
=
=
=
=
=
=
O
O
O
O
O
O
O
O
(1) : constante
(log log n) : super-rápido
(log n) : logarítmico – muito bom
(n) : linear – toda a entrada é visitada
(n log n) : limite de muitos problemas
(n2) : quadrático
(nk) : polinomial no tamanho da entrada
(kn), O (n!), O (nn) : exponencial – ruim!
48