Projeto e Análise de Algoritmos

Propaganda
Crescimento de Funções
PPGI/2009
Prof. Lucídio Cabral - Estrutura de Dados e Complexidade de Algoritmos
1
Análise de Algoritmos
– tempo de processamento em função dos dados de
entrada;
– espaço de memória total requerido para os dados;
– comprimento total do código;
– correcta obtenção do resultado pretendido;
– robustez (como comporta-se com as entradas
inválidas ou não previstas).
– quantidade de "trabalho" necessária para a sua
execução, expressa em função das operações
fundamentais, as quais variam de acordo com o
algoritmo, e em função do volume de dados.
Complexidade
• Porquê o estudo da Complexidade?
– Performance
• Escolher entre vários algoritmos o mais eficiente
para implementar;
• Desenvolver novos algoritmos para problemas que
já têm solução;
• Desenvolver algoritmos mais eficientes (melhorar os
algoritmos), devido ao aumento constante do
"tamanho" dos problemas a serem resolvidos.
– Complexidade Computacional - torna possível
determinar se a implementação de determinado
algoritmo é viável.
Complexidade
• Tipos de Complexidade
– Espacial
• Este tipo de complexidade representa, por exemplo, o
espaço de memória usado para executar o algoritmo.
– Temporal
• Este tipo de complexidade é o mais usado podendo
dividir-se em dois grupos:
– Tempo (real) necessário à execução do algoritmo.
(como podemos medir?)
– Número de instruções necessárias à execução.
Analise de Algoritmos
• Medidas de Análise
– Devem ser independentes da tecnologia
(hardware/software)
– Modelos Matemáticos simplificados baseados nos fatores
relevantes:
• Tempo de Execução
Uma função que relaciona o tempo de execução com o
tamanho de entrada:
t = F(n)
– Conjunto de operações a serem executadas.
– Custo associado à execução de cada operação.
• Ocupação de Espaço em Memória
Complexidade
• Exemplo
– Sejam 5 algoritmos A1 a A5 para resolver um mesmo
problema, de complexidades diferentes. (Supomos que uma
operação leva 1 ms para ser efetuada.)
– Tk(n) é a complexidade ou seja o número de operações que o
algoritmo efetua para n entradas
n
16
32
512
A1
A2
T1(n)= n
T2(n)=nlog n
0.016s
0.032s
0.512s
0.064s
0.16s
9s
tempo necessário para o algoritmo em função de n entradas
A3
T3
(n)=n2
0.256s
1s
4m22s
A4
T4
(n)=n3
4s
33s
1 Dia 13h
A5
T5(n)=2n
1m4s
46 Dias
10137 Séculos
Operações primitivas
•
•
•
•
•
•
Atribuição de valores a variáveis
Chamadas de métodos
Operações aritméticas
Comparação de dois números
Acesso a elemento de um array
Seguir uma referência de objeto (acesso a
objeto)
• Retorno de um método
Complexidade de
Algoritmos
• Complexidade de pior caso – big-Oh O(g(n))
• Complexidade de melhor caso – big-Omega W(g(n))
– de uso bem menos freqüente
– em algumas situações específicas
• Complexidade de caso médio – big-Theta Q(g(n).)
– menos utilizada apesar de importante
– difícil conhecer a distribuição de probabilidades das diferentes
entradas
Notações assintóticas




Q - Limite assintótico apertado ou exato
O - Limite assintótico superior
W - Limite assintótico inferior
o - Limite superior que não é
assintoticamente apertado
 w - Limite inferior que não é
assintoticamente apertado
Por que as notações assintóticas são importantes?
•
Elas fornecem uma caracterização simples da eficiência de um
algoritmo.
•
Elas permitem a comparaçãode desempenho entre vários algoritmos.
•
Para valores elevados de componentes/entradas, as constantes
multiplicativas e termos de baixa ordem de um tempo de execução
exato são dominados pelo efeito do tamanho de entrada (o número
de componentes).
–
O tempo de execução de uma algoritmo sobre uma entrada particular, é o número de operações
primitivas ou “passos” executados.
–
O tamanho da entrada depende problema sendo estudado. Mas na maioria dos casos este é o
número de itens na entrada, por exemplo: o número total de bits.
Resumindo, em geral, quando observamos
tamanhos de entrada suficientemente grandes
para tornar a ordem de crescimento do tempo de
execução relevante para um algoritmo, nós
estamos estudando a eficiência assintótica de
um algoritmo.
E um algoritmo que é assintoticamente mais
eficiente será efetivamente a melhor escolha.
Isto pode não ser verdade para todas as
entradas consideradas pequenas!
Q - Limite assintótico
apertado ou exato
OBS:
Q - Limite assintótico
apertado ou exato
Eg.
Q - Limite assintótico apertado
ou exato
Eg.
O - Limite assintótico superior
O - Limite assintótico superior
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)
Diagrama
Definição do Big-Oh
Ordens mais comuns
2n
(exponencial)
n2
(quadrática)
n log n
f
n (linear)
log n (logarítmica)
1 (constante)
n
Fonte: Sahni, "Data Structures, Algorithms and Applications in C++"
Alguns conceitos
•
•
•
•
•
•
•
•
T (n) = O (1) : constante
T (n) = O (log log n) : super-rápido
T (n) = O (log n) : logarítmico – muito bom
T (n) = O (n) : linear – toda a entrada é visitada
T (n) = O (n log n) : limite de muitos problemas
T (n) = O (n2) : quadrático
T (n) = O (nk) : polinomial no tamanho da entrada
T (n) = O (kn), O (n!), O (nn) : exponencial – ruim!
Teoremas
1. Comportamento assintótico da soma de duas
funções cujos comportamentos assintóticos
particulares são conhecidos:
Se f1(n) = O(g1(n)) e f2(n) = O(g2(n)), então:
f1(n) + f2(n) = O(max(g1(n)) , g2(n)))
2. O(k f(n)) = O(f(n))
3. O(f(n)) O(g(n)) = O(f(n) g(n))
Eficiência de um Algoritmo, mais um
exemplo
Três algoritmo para calcular
1 + 2 + … n para um n > 0
Eficiência de um Algoritmo
O(n)
O(n2)
O(1)
Número de operações necessárias
A notação 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
A notação O
• A função atua como um limite superior
assintótico da função f
– f = n2 -1

f = O(n2)
– f = n2 -1

f = O(n3)
– f = 403

f = O(1)
– f = 5+2logn +3log2n

f=
O(log2n)
– f = 5+2 log n +3log2n

f = O(n)
– f = 5.2n +5n10

f = O(2n)
W - Limite assintótico inferior
o - Limite superior que não é
assintoticamente apertado
w - Limite inferior que não é
assintoticamente apertado
Notações assintóticas em equações
Relações de Funções Assintóticas
Limites podem ser usados para
determinar a ordem de complexidade

c então f (n) = Q ( g (n)) se c > 0
se lim f (n) / g (n) = 0 or c > 0 então f (n) = o ( g(n))
n
 or c > 0 então f (n) = W ( g (n))
Exemplo usando limites
5n  3n  W(n ) dado que ,
3
2
5n  3n
5n
3n
lim
 lim 2  lim 2  
2
n 
n  n
n  n
n
3
3
Regra de L’Hopital
Se f(x) e g(x) são ambas funções diferenciáveis
com derivadas f’(x) e g’(x), respectivamente, e
se
lim g ( x)  lim f ( x)   então
x 
x 
f ( x)
f ' ( x)
lim
 lim
x  g ( x )
x  g ' ( x )
sempre que o limite a direita existe
Exemplos usando limites
10n 3 - 3n  Q(n 3 ) dado que ,
10n 3 - 3n
10n 3
3n
lim
 lim 3 - lim 3  10
3
n 
n  n
n  n
n
n log e n  O (n 2 ) dado que ,
n log e n
log e n
lim
 lim
 ? Use a Regra de L' Hopital
2
n 
n 
n
n
(log e n)'
1/ n
lim
 lim
0
n 
n  1
(n)'
Exemplo usando limites
lg n  O (n )
ln n
lg n 
ln 2
 ln n 
1
(lg n)'  
 '=
 ln 2  nln2
lg n
(lg n)'
1
 lim
 lim
0
lim
n  n
n 
n  n ln 2
n'
Exemplo usando limites
n k  O (2n )
onde k é uma constante inteira positiva
2 n  e n ln 2
n ln 2
n ln 2
n


( 2 )' (e
)'= ln2 e
2 ln 2
n
-
nk
kn k 1

lim n  lim n
n  2
n   2 ln 2
k -2
k ( k 1)n
k!
 lim


... lim n k  0
2
n
n 
n   2 ln 2
2 ln 2
Download