Upload
arnaldo-jr
View
1.251
Download
0
Embed Size (px)
DESCRIPTION
Material sobre a analise da complexidade de algoritmos segundo a notação O ( O grande )
Citation preview
Análise de Algoritmos
Wilson Rubens Galindo
ATENÇÃO!!!
Utilizarei a linguagem
PORTHONMistura de
Português com Python
Introdução
Preocupação com o tempo de execução do algoritmoDois métodos:
Empírico (relacionado ao tempo de execução)Analítico (através de expressões matemáticas)
VantagensAnalítico independe de computadorEmpírico é fácil de analisar
Função de Complexidade
TempoRegistra a quantidade de tempo necessário para executar um algoritmo para resolver um determinado problema. (nosso foco)
EspaçoNeste caso, mede-se a quantidade de memória necessária para executar um dado algoritmo.
Método Analítico
Considerações:Dados suficientemente grandes.
Comportamento assintóticoNão são consideradas constantes aditivas ou multiplicativas na expressão matemática obtida.
Objetivo: Obter estruturas simples.
Método Analítico
A execução é dividida em passosCada passo contém operações consideradas constantesImportância
Facilidade na comparação de tempos de algoritmos diferentes com mesmo objetivo.
Determinação de limite assintótico para determinados algoritmos.
Exemplo
Algoritmo que faz a soma de matrizes
a=[], b=[], c=[] 1
for i in range(0,n): c1 n
for j in range(0,n): c2 n
c[i][j]=a[i][j]+b[i][j] 1
Análise de custo: 1 + c1 * c2 * 1= 1 + n * n= n2
Exemplo 2
Algoritmo que faz o produto de matrizes
for i in range(0,n) c1 n
for j in range(0,n): c2 n
c[i][j]=0 1
for k in range(0,n): c3 n
c[i][j]=c[i][j] + a[i][j] * b[i][j] 1
Análise de custo: c1 * c2 * c3= n * n * n= n3
Análise do pior caso
Imagine um algoritmo que execute em tempo n, onde n é o tamanho da entrada, a maioria de suas entradas, mas para um determinado tipo de n, o algoritmo é n10. Qual o custo do algoritmo?Resposta: n10
Por quê?
Análise de pior caso.
Análise de caso médio
ProbabilísticoNo pior caso é pouco eficiente mas utiliza outros métodos que compensam sua complexidade.Ex:Algoritmo1: 5000n2+160n3+100n4+1000n5
Algoritmo2: n5
Comportamento Assintótico
O comportamento assintótico de f(n) representa o limite do custo quando n cresce.
Definição: Uma função f(n) domina assintoticamente outra função g(n) se existem duas constantes positivas c e m tais que, para n ≥ m, temos
|g(n)| ≤ c.|f(n)|
Comportamento assintótico
Graficamente temos:
f, g
n
g(n)
c . f(n)
m
Comportamento Assintótico
Exemplo: Seja g(n) = n e f(n) = -n2, com n pertencente a Z+. Por definição, temos:
|g(n)| ≤ c.|f(n)|| n | ≤ c . |- n2 |
n ≤ c . n2
Note que, fazendo c=1 e m=1, f(n) domina assintoticamente g(n).
Comportamento Assintótico
Graficamente temos:
f, g
m = 1
g(n) = n
|f(n)| = c . n2, com c=1
n
Notação O
Definição:Sejam f, h funções positivas de variávelinteiras.Diz-se que f é O(h), escrevendo-se f = O(h), quando existir uma constante c > 0 e um valor inteiro n0, tal que:
n > n0 => f(n) ≤ c . h(n)
Classes de Comportamento Assintótico
As principais classes de problemas possuem as seguintes funções de complexidade:
f(n)=O(1): São algoritmos de complexidade constante. O uso desses algoritmos independem do tamanho de n. Neste caso, as instruções do algoritmo são executadas um número fixo de vezes.
Classes de Comportamento Assintótico
f(n)=O(log n): São algoritmos de complexidade logarítmica. Este tempo de execução ocorre tipicamente em algoritmos que resolvem um problema transformando-o em problemas menores.f(n)=O(n): São algoritmos de complexidade linear. Em geral, um pequeno trabalho érealizado sobre cada elemento de entrada.
Classes de Comportamento Assintótico
f(n)=O(n .log n): Este tempo de execução ocorre tipicamente em algoritmos que resolvem um problema quebrando-o em problemas menores, resolvendo cada um deles independentemente e depois junta-se as soluções.f(n)=O(n2): São algoritmos de complexidade quadrática. Geralmente isto ocorre quando háprocessamento com um laço dentro do outro. São úteis quando n é relativamente pequeno.
Classes de Comportamento Assintótico
f(n)=O(n3): São algoritmos de complexidade cúbica. Úteis apenas para resolver pequenos problemas.f(n)=O(2n): São algoritmos de complexidade exponencial. Tais algoritmos geralmente não são úteis para resolver problemas do ponto de vista prático. Ocorrem em problemas quando se usa “força bruta” para resolvê-los.
Classes de Comportamento Assintótico
Sobre classes de comportamento assintótico destacam-se:
f(n)=O(cn), c>1: Algoritmos com essa função de complexidade são chamados de algoritmos exponenciais no tempo de execução.f(n)=O(p(n)), p(n) é um polinômio: Já algoritmos cuja função de complexidade é um polinômio são conhecidos por algoritmos polinomiais no tempo de execução.
Classes de Comportamento Assintótico
Algoritmos ExponenciaisQuando o tamanho de n é grande, tornam-se bastante ineficientes na prática;São geralmente simples variações de pesquisa exaustiva;Problemas solucionados apenas por tais algoritmos são considerados intratáveis, isto é, não existe solução por algoritmo polinomial.
Classes de Comportamento Assintótico
Algoritmos PolinomiaisQuando o tamanho de n é grande, tornam-se muito úteis na prática;São geralmente obtidos através de um entendimento mais profundo da estrutura do problema;Apresentam boa solução, isto é, um problema éconsiderado bem resolvido quando existe um algoritmo polinomial para resolvê-lo.
Comparação entre Funções de Complexidade
Funçãode
Custon=10 n=20 n=30 n=40 n=50 n=60
n 10-5 s 2.10-5 s 3.10-5 s 4.10-5 s 5.10-5 s 6.10-5 s
n2 10-4 s 4.10-4 s 9.10-4 s 16.10-4 s 25.10-4 s 36.10-4 s
n3 10-3 s 8.10-3 s 27.10-3 s 64.10-3 s 125.10-3 s 216.10-3 s
n5 0,1 s 3,2 s 24,3 s 1,7 min 5,2 min 13 min
2n 10-3 s 1 s 17,9 min 12,7 dias 35,7 anos 366 séc.
3n 59.10-3 s 58 min 6,5 anos 3855 séc. 108 séc. 1013 séc.
Segundo Garey e Johnson (1979, pág. 7), temos:
OBS.: Um algoritmo linear executa em 1s um milhão de operações.
Técnicas de Análise de Algoritmos
Determinar a ordem de tempo de execução de um algoritmo (notação O) é em geral mais simples do que encontrar a expressão matemática exata da função de complexidade.
Técnicas de Análise de Algoritmos
Tentando tornar mais simples a tarefa de obter tal expressão matemática, Aho, Hopcroft e Ullman (1983) enumeraram alguns princípios a serem seguidos:
1. Operação de atribuição, leitura ou escrita são consideradas como O(1).Exceções: Chamada de função em comando de atribuição e atribuições que envolvem vetores de tamanho arbitrariamente grandes.
Técnicas de Análise de Algoritmos
2. O tempo de execução de uma seqüência de comandos é determinado pelo maior tempo de execução de qualquer comando dessa seqüência (operação dominante).3. O tempo de execução de um comando de decisão é composto pelo tempo de execução dos comandos executados dentro do comando condicional mais o tempo para avaliar a condição, que é O(1).
Técnicas de Análise de Algoritmos
4. O tempo para executar um laço é a soma do tempo de execução do corpo do laço mais o tempo de avaliar a condição de parada (geralmente é O(1)), multiplicado pelo número de iterações do laço.5. Quando o algoritmo possui procedimentos não recursivos, o tempo de execução de cada procedimento deve ser computado separadamente um a um, iniciando com os procedimentos que não chamam outros procedimentos.
Técnicas de Análise de Algoritmos
5. (Continuação) Depois, avalia-se os procedimentos que chamam os procedimentos que não chamam outros procedimentos, utilizando os tempos dos procedimentos jáavaliados. Este processo é repetido até chegar no algoritmo principal.
Técnicas de Análise de Algoritmos
6. Quando o algoritmo possui procedimentos recursivos, para cada procedimento éassociada uma função de complexidade f(n) desconhecida, onde n mede o tamanho dos argumentos para o procedimento. Outra opção é determinar o número total de chamadas recursivas, calcular a complexidade de uma dessas chamadas recursivas (sem considerar outras chamadas), e efetuar esse produto.
notação Ω
Definição: Sejam f,h funções positivas de variável inteiras. Diz-se que f é Ω(h), escrevendo-se f = Ω(h), quando existir umaconstante c > 0 e um valor inteiro n0, tal que:n > n0 => f(n) ≥ c . h(n)
notação θ
Definição: Sejam f,h funções positivas de variável inteiras. Diz-se que f é θ(h), escrevendo-se f = θ(h), quando ambas as condições acontecem: f = O(h) e f = Ω(h).