Buscar

4-AlgorithmAnalysis

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 72 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 72 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 72 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Nuno Leite
AED: Algoritmos e Estruturas de Dados – Semestre de Inverno 2007/08
http://www.deetc.isel.ipl.pt/programacao/aed/
Capítulo 2 - Análise de Algoritmos e Complexidade
ISEL/LEIC - 2007/2008
2º ano, 1º Semestre 
* Estes acetatos foram parcialmente adaptados dos acetatos de AED da 
LEEC do Instituto Superior Técnico – Prof. Rui Gustavo Crespo
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 2
Análise de Algoritmos (1)
„ Para avaliar e comparar o desempenho de dois algoritmos:
„ Método empírico: executamos ambos (muitas vezes) para ver qual é
mais rápido
„ se o algoritmo for lento, o método empírico pode consumir 
demasiado tempo
„ não podemos esperar 2 horas até que o algoritmo produza a resposta!
„ ou se pretendermos afinar os vários parâmetros do algoritmo
„ testar várias variantes pode ser um processo moroso
„ é aqui que entra a análise matemática de algoritmos
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 3
Análise de Algoritmos (2)
„ É fundamental para se perceber e utilizar um algoritmo de forma 
efectiva/eficiente:
„ compararmos com outros
„ prevermos o desempenho
„ escolher correctamente os seus parâmetros 
„ Importante saber que há bases científicas irredutíveis para 
caracterizar, descrever e comparar algoritmos
„ Intenção nesta disciplina é
„ ilustrar o processo
„ introduzir alguma notação
„ introduzir este tipo de análise demonstrando a sua utilidade e 
importância
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 4
Análise de Algoritmos (3)
„ Análise precisa é uma tarefa complicada:
„ algoritmo é implementado numa dada linguagem
„ linguagem é compilada e o programa é executado num dado 
computador
„ difícil prever tempos de execução de cada instrução
„ muitos algoritmos são "sensíveis" aos dados de entrada
„ muitos algoritmos não são bem compreendidos
„ É em geral no entanto possível prever precisamente o tempo de 
execução de um programa,
„ ou que um algoritmo é melhor que outro em dadas circunstâncias 
(bem definidas)
„ apenas é necessário um pequeno conjunto de ferramentas matemáticas
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 5
Análise de Algoritmos (4)
„ Fundamental é separar a análise da implementação, i.e. 
identificar as operações de forma abstracta
„ é relevante saber quantas vezes id[p] é acedido
„ Uma propriedade (imutável) do algoritmo
„ não é tão importante saber quantos nanossegundos essa instrução 
demora no meu computador!
„ Uma propriedade do computador e não do algoritmo 
„ O número de operações abstractas pode ser grande, mas
„ o desempenho tipicamente depende apenas de um pequeno número 
de parâmetros
„ procurar determinar a frequência de execução de cada um desses 
operadores
„ Usar ferramentas de profiling para medir a frequência das instruções
„ Estabelecer estimativas
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 6
Tipos de dados de entrada (1)
„ Que dados usar?
„ dados reais: verdadeira medida do custo de execução
„ dados aleatórios: assegura-nos que as experiências testam o 
algoritmo e não apenas os dados específicos
„ Caso médio
„ dados perversos: mostram que o algoritmo funciona com qualquer 
tipo de dados
„ Pior caso!
„ dados benéficos:
„ Melhor caso
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 7
Tipos de dados de entrada (2)
„ Dependência nos dados de entrada
„ dados reais geralmente não disponíveis:
„ assumir que são aleatórios: caso médio
„ por vezes a análise é complicada
„ Pode ser uma ficção matemática não representativa da vida real
„ perversos: pior caso
„ por vezes difícil de determinar
„ podem nunca acontecer na vida real
„ benéficos: melhor caso
„ Em geral, qualquer destas análises fornece boas indicações 
quanto ao desempenho de um algoritmo
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 8
Análise: Crescimento de Funções (1)
„ O tempo de execução geralmente depende dum único parâmetro 
n
„ ordem de um polinómio
„ tamanho de um ficheiro a ser processado, ordenado, etc.
„ ou medida abstracta do tamanho do problema a considerar
„ usualmente relacionado com o número de dados a processar
„ Quando há mais de um parâmetro
„ procura-se exprimir todos os parâmetros em função de um só
„ faz-se uma análise em separado para cada parâmetro
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 9
Análise: Crescimento de Funções (2)
„ Os Algoritmos têm tempo de execução proporcional a:
„ 1
„ muitas instruções são executadas uma só vez ou poucas vezes
„ se isto for verdade para todo o programa diz-se que o seu tempo de 
execução é constante
„ log2 n
„ tempo de execução é logarítmico
„ cresce ligeiramente à medida que n cresce
„ usual em algoritmos que resolvem um grande problema reduzindo-o a 
problemas menores e resolvendo estes
„ quando n duplica, log2 n aumenta mas muito pouco; apenas duplica 
quando n aumenta para n2
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 10
Análise: Crescimento de Funções (3)
„ n 
„ tempo de execução é linear 
„ típico quando algum processamento é feito para cada dado de entrada
„ situação óptima quando é necessário processar n dados de entrada (ou 
produzir n dados na saída)
„ n log2 n
„ típico quando se reduz um problema em sub-problemas, se resolvem 
estes separadamente e se combinam as soluções
„ Ex: algoritmo de ordenação Mergesort
„ se n é 1 milhão, n log2 n é perto de 20 milhões
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 11
Análise: Crescimento de Funções (4)
„ n2
„ tempo de execução quadrático
„ típico quando é preciso processar todos os pares de dados de entrada
„ prático apenas em pequenos problemas (ex: produto matriz -vector)
„ n3
„ tempo de execução cúbico
„ para n = 100, n3 = 1 milhão (ex: produto de matrizes)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 12
Análise: Crescimento de Funções (5)
„ 2n
„ tempo de execução exponencial
„ algoritmos com esta ordem de complexidade geralmente não são úteis 
sob o ponto de vista prático
„ típico em soluções de força bruta
„ para n = 20, 2n = 1 milhão; n duplica, tempo passa a ser o quadrado
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 13
Análise: Crescimento de Funções (6)
„ Convenção:
„ lg n é equivalente a log2 n
Valores típicos de várias funções
lg n sqrt(n) n n lg n n(lg n)2 n3/2 n2
3 3 10 33 110 32 100
7 10 100 664 4414 1000 10000
10 32 1000 9966 99317 31623 1000000
13 100 10000 132877 1765633 1000000 100000000
17 316 100000 1660964 27588016 31622777 10000000000
20 1000 1000000 19931569 397267426 1000000000 1000000000000
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 14
Análise: Resolução de grandes problemas (1)
„ Relação do tempo de execução
„ conversão para unidades de tempo mais familiares
segundos unidades de tempo mais familiares
102 1.7 minutos
104 2.8 horas
105 1.1 dias
106 1.6 semanas
107 3.8 meses
108 3.1 anos
109 3.1 décadas
1010 3.1 séculos
1011 nunca
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 15
Análise: Resolução de grandes problemas (2)
tamanho do problema - 1 milhão tamanho do problema - 1 bilião*
n n lg n n2 n lg n n2
106 segundos segundos semanas horas horas nunca
109 instantâneo instantâneo horas segundos segundos décadas
1012 instantâneo instantâneo segundos instantâneo instantâneo semanas
n
operações 
por 
segundo
* 1 bilião (1 billion) = mil milhões
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 16
Análise: Complexidade
„ Complexidade refere-seao tempo de execução
„ usualmente o termo de maior ordem domina (para n elevado)
„ comum todos os termos serem multiplicados por uma constante
„ para n pequeno vários termos podem ser igualmente relevantes
„ ex: 0.1 n3 +100 * n2 para 1 ≤ n ≤ 1000
„ base do logaritmo não é muito relevante
„ mudar de base é um factor constante
„ bases mais comuns são 2 (lg n), 10 (log n) e e (ln n)
„ (e = número de Neper)
„ Análise de complexidade é muito importante quando n aumenta
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 17
Análise: Funções Relevantes
∑
=
=
n
1i
n i
1H
função nome valores típicos aproximação
⎣x⎦ função floor (chão) ⎣3.14⎦ = 3 x
⎡x⎤ função ceiling (tecto) ⎡3.14⎤ = 4 x
lg n logaritmo binário lg 1024 = 10 1.44 ln n
Fn números de Fibonacci F10 = 55 φn / sqrt(5)
Hn números harmónicos H10 ≈ 2.9 ln n + γ
n ! função factorial 10! = 3628800 (n / e)n
lg (n!) lg(100!) ≈ 520 n lg n – 1.44 n 
e = 2.71828 …
γ = 0.57721 …
, para n ≥ 2 com F0 = 0 e F1 = 1 φ = (1+ sqrt(5)) / 2 = 1.61803 …
ln 2 = 0.693147 …
lg e = 1 / ln 2 = 1.44269 …
2n1nn FFF −− +=
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 18
Algoritmos – Síntese da Aula 1
„ Análise de Algoritmos
„ Aspectos essenciais da análise
„ empírica, teórica; estratégias de melhoria de algoritmos; comparação 
de algoritmos
„ Crescimento de funções
„ Resolução de grandes problemas
„ Complexidade e funções relevantes
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 19
Análise: Notação "O grande" (1)
„ A notação matemática que nos permite suprimir detalhes na 
análise de algoritmos
„ A notação “O grande” fornece um limite assimptótico superior 
(não o menor limite superior) de uma dada função
„ Definição: Para uma dada função g(n), denota-se por O(g(n))
(pronuncia-se “ó grande de g de n”) o conjunto de funções
O(g(n)) = { f(n) : existem constantes positivas c e n0
tal que 0 ≤ f(n) ≤ c.g(n) para todo o n ≥ n0 }
„ Utiliza-se a notação “O grande” para encontrar um limite 
superior duma função, a menos de um factor constante
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 20
Análise: Notação "O grande" (2)
„ Escreve-se f(n) = O(g(n)) se existirem constantes c e n0 tal que, 
para todos os valores à direita de n0, o valor de f(n) é menor ou 
igual a c.g(n)
n0
f(n)
cg(n)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 21
Análise: Notação "O grande" (3)
„ A notação é usada com três objectivos: 
„ limitar o erro que é feito ao ignorar os termos menores nas fórmulas 
matemáticas 
„ limitar o erro que é feito na análise ao desprezar parte de um 
programa que contribui de forma mínima para o 
custo/complexidade total
„ permitir-nos classificar algoritmos de acordo com limites superiores 
no seu tempo de execução
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 22
Análise: Notação "O grande" (4)
„ Escreve-se f(n) = O(g(n)) para indicar que a função f(n) é um 
membro do conjunto O(g(n))
„ f(n) = O(g(n)) significa f(n) ∈ O(g(n))
„ Quando a notação assimptótica é usada em equações ou 
inequações, utilizam-se as seguintes convenções:
„ 1) O(n) significa O(g(n)); o argumento de O(.) é sempre uma função
„ p.ex.: O(1) significa O(f(n)), sendo f(n) uma função constante 
„ 2) notação assimptótica aparece isolada do lado direito da equação 
ou inequação
„ p.ex.: n = O(n2) significa n ∈ O(n2), ou mais precisamente f(n) = n∈
O(g(n)), onde g(n)=n2
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 23
Análise: Notação "O grande" (5)
„ Convenções (continuação)
„ 3) notação assimptótica aparece numa fórmula
„ p.ex.: 2n2 + 3n + 1 = 2n2 + O(n) significa
2n2 + 3n + 1 = 2n2 + f(n), em que f(n) = 3n+1 ∈ O(n)
„ Usando a definição, provar que:
„ 3n = O(n)
„ 2n + 3 = O(n)
„ 3n2 + 5n + 3 = O(n2)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 24
Análise: Notação "O grande" (6)
„ Os resultados da análise não são exactos
„ são aproximações tecnicamente bem caracterizadas
„ Manipulações com a notação "O grande”
„ permitem-nos ignorar termos de menor importância de forma 
precisa. Podem ser feitas como se o "O" não estivesse lá
Ex: (n + O(1)) (n + O(lg n) = 
usando distributividade e o facto de que
f(n) . O(g(n)) = O(f(n) . g(n)) se f(n) não for constante,
e
O(1) . g(n) = O(g(n)), fica:
= n2+ O(n) + O(n lg N) + O(lg n) = 
e como O(n lg n) > O(n) > O(lg n) 
= n2 + O(n lg n)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 25
Análise: Notação "O grande" (7)
„ Manipulações com a notação "O grande”: alguns exemplos
„ 1) f(n) = O(f(n))
„ 2) c . O(f(n)) = O(c . f(n)) = O(f(n))
„ 3) O(f) + O(g) = O(f+g) = O(max(f,g))
„ 4) O(f) . O(g) = O(f . g)
„ 5) O(f) + O(g) = O(f) sse g(n) ≤ f(n) para ∀ n >n0
„ Exercício: provar as relações 1), 2) e 5)
Fórmula com termo contendo O(...) diz-se expressão assimptótica
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 26
Exemplo: vantagens da notação (1)
„ Dado um problema para análise
„ verifica-se ter um ciclo interno iterado 2nHn vezes em média
„ cada iteração requer execução de a0 instruções (ou demora a0 ns)
„ secção interna iterada n vezes
„ requer execução de a1 instruções (ou demora a1 ns)
„ inicialização feita uma vez
„ requer execução de a2 instruções (ou demora a2 ns)
„ Complexidade (tempo médio de execução) é
2 a0 n Hn + a1 n + a2 = 2 a0 n Hn + O(n)
„ Para n grande não é preciso calcular a1 ou a2
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 27
Exemplo: vantagens da notação (2)
„ Usando a notação O() temos Hn = ln n + O(1)
logo 
2 a0 n Hn + a1 n + a2 = 2 a0 n ln n + O(n) ≈ 2 a0 n ln n
„ E se se duplicar n?
„ O tempo de execução também duplica
„ Conclui-se que também não é preciso conhecer a0 !
2
ln(n)
1
O2
O(1)ln(n)
O(1)2ln(2n)
O(n)(n)ln(n)2a
O(2n)(2n)ln(2n)2a
0
0 ≈⎟⎟⎠
⎞⎜⎜⎝
⎛+=+
+=+
+
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 28
Algoritmos – Síntese da Aula 2
„ Notação “O grande”
„ Conceito
„ Definições
„ Propriedades
„ Exercícios
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 29
Operações sobre dados - Complexidade
„ As operações sobre dados mais usadas são quatro:
1. Acesso
„ Ver se existe, e recolher, o valor do conteúdo de um elemento
2. Modificação
„ Alterar o valor do conteúdo de um elemento
3. Inserção
„ Acrescentar um novo elemento e/ou componente a uma estrutura já
existente
4. Remoção
„ Apagar um elemento e/ou componente de uma estrutura já existente
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 30
Acesso e modificação de variáveis
„ Na operação de acesso a dados organizados em array ou lista 
pode-se querer:
„ Aceder ao primeiro elemento
„ Aceder ao último elemento
„ Aceder a um elemento específico
„ Aceder ao próximo (pressupõe a existência de um iterador) 
„ Em operações de modificação pode-se também querer
„ Modificar o conteúdo do primeiro elemento
„ Modificar o conteúdo do último elemento
„ Modificar o conteúdo de um elemento específico
„ Modificar o próximo (pressupõe a existência de um iterador)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 31
Eficiência no acesso e modificação
„ A eficiência nas operações de acesso e modificação é
condicionada pela estrutura escolhida para armazenar os dados
„ Assim
Acesso/Modificação Array Lista
Primeiro O(1) O(1)
Último O(1) O(size)
Próximo O(1) O(1)
Específico O(1) O(k)
Assume-se 
que apenas 
existe um 
ponteiro 
para o início 
da lista
- size é o número de elementos existente
- k é a posição do elemento a aceder ou modificar (1≤ k ≤ size)LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 32
Inserção de componentes
„ Na operação de inserção de novos elementos em arrays, ou em 
listas, pode pretender-se
„ Inserir um novo elemento na primeira posição, deslocando todos os 
outros para a frente
„ Inserir um novo elemento na última posição sem afectar os já
existentes
„ Inserir um novo elemento numa posição intermédia pré-especificada, 
sem afectar os anteriores e deslocando os posteriores para a frente
„ Inserir um novo elemento de acordo com o seu valor ou em função 
do valor de algum qualificador associado com esse elemento (p. ex.: 
inserção ordenada)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 33
Eficiência na inserção
„ A eficiência da operações de inserção é condicionada pela 
estrutura escolhida para armazenar os dados
„ Assim
Inserção Array Lista
Primeiro O(size) O(1)
Último O(1) O(size)
Pré-especificado O(size-k) O(k)
Condicional O(size) O(k)
Assume-se 
que apenas 
existe um 
ponteiro 
para o início 
da lista
- size é o número de elementos existente antes da inserção
- k é a posição onde ficará o elemento a inserir (1≤ k ≤ size)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 34
Remoção de componentes
„ Na operação de remoção de elementos de tabelas ou de listas 
pode pretender-se
„ Apagar o primeiro elemento da primeira posição, deslocando todos os 
outros para trás.
„ Apagar o último elemento sem afectar os já existentes.
„ Apagar o elemento situado numa posição intermédia pré-especificada, 
sem afectar os anteriores e deslocando os posteriores para trás.
„ Apagar o elemento que possuir determinado valor, propriedade, etc.
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 35
Eficiência na remoção
„ A eficiência da operação de remoção é condicionada pela 
estrutura escolhida para armazenar os dados
„ Assim
Remoção Array Lista
Primeiro O(size) O(1)
Último O(1) O(size)
Pré-especificado O(size-k) O(k)
Condicional O(size) O(k)
Assume-se 
que apenas 
existe um 
ponteiro 
para o início 
da lista
- size é o número de elementos existente antes da remoção
- k é a posição onde está o elemento a remover (1≤ k ≤ size)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 36
Metodologia para determinação de complexidade (1)
„ Suponha o seguinte código
for (i = 0; i < n; ++i) { instruções; }
„ contabilização do número de instruções é simples: n iterações e em 
cada uma são executadas um número constante de instruções: O(n)
„ Suponha o código seguinte:
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
instruções;
}
}
„ contabilização do número de instruções é ainda simples: ciclo 
interno é O(n) e é executado n vezes: O(n2)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 37
Metodologia para determinação de complexidade (2)
„ Suponha o código seguinte:
for (i = 0; i < n; ++i) {
for (j = i; j < n; ++j) {
instruções;
}
}
„ contabilização do número de instruções é ainda simples: ciclo 
interno é executado 
n + (n-1) + (n-2) + … + 3 + 2 + 1 = n(n+1)/2 ∈ O(n2)
„ Infelizmente nem sempre a contabilização é assim tão simples...
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 38
Metodologia para determinação de complexidade (3)
„ Suponha o seguinte código
public static int func (int a[], int n) {
várias instruções;
b = func(a, n-1); return b; 
}
„ contabilização do número de instruções não parece ser simples
„ numa chamada à função executamos
„ algumas instruções sobre n objectos (digamos O(f(n)); pode ser 
constante, n, etc.)
„ depois voltamos a chamar a mesma função agora apenas com n-1
objectos
„ Número total de instruções executadas é
„ C(n) = C(n-1)+ O(f(n)) uma recorrência!
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 39
Recorrência e Funções recorrentes (1)
„ Um algoritmo recorrente é aquele que resolve um dado 
problema resolvendo uma ou mais instâncias de menor dimensão 
do mesmo problema
„ Para implementar algoritmos recorrentes em Java, utilizam-se 
métodos recorrentes – métodos em cujo corpo é invocado o 
próprio método
„ os métodos recorrentes em Java são especificados de forma 
equivalente às definições recorrentes de funções matemáticas
„ p. ex.: definição recorrente da função factorial
n! = n.(n-1)!, para n ≥ 1 com 0! = 1 
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 40
Recorrência e Funções recorrentes (2)
„ Implementação em Java:
„ Algoritmo recorrente
static int factorial(int n) { 
if (n == 0) return 1; 
return n*factorial(n-1); 
}
„ Algoritmo iterativo
static int factorial(int n) { 
int fact = 1;
for (int i = 1; i <= n; ++i) 
fact *= i;
return fact; 
}
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 41
Recorrência e Funções recorrentes (3)
„ É sempre possível transformar um programa recorrente num 
programa equivalente não recorrente
„ Inversamente, também é possível converter um programa 
iterativo num programa recorrente, expressando a computação 
sem usar ciclos 
„ A recorrência permite-nos expressar algoritmos complexos de 
uma forma compacta, sem contudo sacrificar a eficiência
„ Por forma a garantir que um algoritmo recorrente termina a 
execução é necessário garantir três condições:
1. recorrência deve ser sempre feita com instâncias do problema de 
menor dimensão
2. deve existir um caso base
3. o caso base tem que ser alcançável
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 42
Análise: Recorrências básicas (1)
„ Muitos algoritmos são baseados na ideia de "dividir para 
conquistar” (divide and conquer)
„ dividir recorrentemente um problema grande em vários problemas 
menores
„ Análise de algoritmos recorrentes
„ a cada algoritmo recorrente está associado uma função de 
complexidade f(n) desconhecida, onde n é a dimensão dos 
argumentos do algoritmo
„ de seguida, obtém-se a equação de recorrência, que define uma 
função por uma expressão que envolve a mesma função
„ resolvendo a equação de recorrência, obtém-se a medida de 
complexidade do algoritmo
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 43
Análise: Recorrências básicas (2)
„ Problema: encontrar o máximo de um array
„ Algoritmo iterativo
static int maxIterative(int array[]){
int max = array[0]; // Assume-se que o array não está vazio
int n = array.length;
for (int i = 1; i < n; ++i) {
if (array[i] > max) max = array[i];
}
return max;
}
„ Este algoritmo executa em tempo proporcional a O(n)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 44
Análise: Recorrências básicas (3)
„ Algoritmo recorrente
static int maxRecursive(int array[], int n, int maxActual) {
if (n == 0) return maxActual;
if (array[n-1] > maxActual) {
return maxRecursive(array, n-1, array[n-1]);
}
else {
return maxRecursive(array, n-1, maxActual);
}
}
„ Em cada passo executa O(1) instruções somadas às instruções 
realizadas na recorrência com n-1 elementos
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 45
Análise: Recorrências básicas (4)
Programa recorrente que calcula o máximo
Equação de recorrência: C(n)=C(n-1)+O(1) para n ≥ 2 com C(1)=O(1)
Solução: 
C(n) = O(n)
Demonstração: usar a
propriedade telescópica e
aplicar a fórmula a si própria
Importante: O carácter recorrente 
de um algoritmo reflecte-se 
directamente na sua análise 
C(n) = C(n-1) + O(1) 
= C(n-2) + O(1) + O(1)
= C(n-3) + O(1) + O(1) + O(1)
. . . 
= C(1) + O(1) + ... + O(1) 
= O(1) + O(1) + ... + O(1) 
= O(n)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 46
Análise:Recorrências básicas (5)
„ Problema: listar na saída os pares de índices cuja soma de 
valores é igual a x
„ Algoritmo iterativo
static void pairsIterative(int array[], int x) {
int n = array.length;
for (int i = 0; i < n; ++i) {
for (int j = i+1; j < n; ++j) {
if (array[i]+array[j]==x) 
System.out.println(i + “ " + j);
}
}
}
„ Este algoritmo executa em tempo proporcional a O(n2)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 47
Análise: Recorrências básicas (6)
„ Algoritmo recorrente
static void pairsRecursive(int array[], int x, int n) {
if (n == 0) return;
for (int i = 0; i < n-1; ++i) {
if (array[n-1] + array[i] == x) {
System.out.println(n-1 + “ " + i);
}
}
pairsRecursive(array, x, n-1);
}
„ Em cada passo executa O(n) instruções somadas às instruções 
realizadas na recorrência com n-1 elementos
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 48
Análise: Recorrências básicas (7)
Programa recorrente que lista na saída os pares de índices cuja soma 
de valores é igual a x
Equação de recorrência: C(n)=C(n-1)+O(n) para n ≥ 2 com C(1)=O(1)
Solução: 
C(n) = O(n2)
Demonstração: usar a
propriedade telescópica e
aplicar a fórmula a si própria
Importante: O carácter 
recorrente de um algoritmo 
reflecte-se directamente 
na sua análise 
C(n) = C(n-1) + O(n) 
= C(n-2) + O(n – 1) + O(n)
= C(n-3) + O(n–2)+O(n–1) + O(n)
. . . 
= C(1)+O(2)+...+O(n–2)+O(n–1)+O(n) 
= O(1)+O(2)+...+O(n–2)+O(n–1)+O(n) 
= ⎟⎠
⎞⎜⎝
⎛ +
2
1)n(n
O
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 49
Algoritmos – Síntese da Aula 3
„ Operações sobre dados
„ determinação da complexidade
„ Metodologia para determinação de complexidade 
„ Recorrência e Funções recorrentes
„ Recorrências básicas 
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 50
Pesquisa binária
„ Problema: pesquisa binária ou dicotómica num array ordenado
„ Pesquisa binária - Algoritmo
„ se os números no array estão ordenados podemos eliminar metade 
deles comparando o que procuramos com o que está na posição do 
meio
„ se for igual temos sucesso
„ se for menor, aplicamos o mesmo método à primeira metade da 
tabela
„ se for maior aplicamos o mesmo método à segunda metade da 
tabela
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 51
Pesquisa binária
„ Algoritmo iterativo
static int binarySearchIterative(int a[], int v, int l, int r) { 
while (r >= l) {
int mid = (l+r)/2; 
if (v == a[mid]) return mid; 
if (v < a[mid]) r = mid-1; 
else l = mid+1; 
} 
return -1;
}
„ Função de complexidade do tempo de execução?
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 52
Pesquisa binária - Exemplo
5 7 9 13 32 33 42 54 56 88
0 1 2 3 4 5 6 7 8 9
Valor v a procurar é o 33
O array tem o seguinte conteúdo:
mid = (0 + 9) / 2 (que é 4)
33 > a[mid] (ou seja, 33 > a[4])
Então, se 33 se encontra no array, é um dos elementos:
33 42 54 56 88
5 6 7 8 9
Metade dos elementos são ignorados dado que o array 
está ordenado.
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 53
mid = (5 + 6) / 2 (que é 5)
33 == a[mid]
Encontrámos 33 no índice 5:
33
5
mid = (5 + 9) / 2 (que é 7)
33 < a[mid] (ou seja, 33 < a[7])
Então, se 33 se encontra no array, é um dos elementos:
33 42
5 6
Elimina
metade dos 
restantes
elementos
Pesquisa binária - Exemplo
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 54
Pesquisa binária
„ Algoritmo recorrente
static int binarySearchRecursive(int a[], int v, int l, int r) {
int result = -1, mid;
if (l > r) result = -1;
else { mid = (l + r)/2;
if (v == a[mid]) result = mid; 
else if (v < a[mid])
result = binarySearchRecursive (a, v, l, mid - 1);
else //(v > a[mid])
result = binarySearchRecursive (a, v, mid + 1, r);
}
return result; }
„ Em cada passo executa O(1) instruções (ver se encontrou) 
somadas às instruções realizadas na recorrência com n/2
elementos
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 55
Análise: Equação de recorrência
Programa recorrente que, em cada passo, divide em dois os dados de 
entrada
Equação de recorrência: C(n)=C(n/2)+O(1) para n ≥ 2 com C(1)=O(1)
Solução: C(n) = O(lg n)
Demonstração: 
considerar n = 2p (p = lg n) e
usar a propriedade telescópica e
aplicar a fórmula a si própria
C(2p) = C(2p-1) + O(1) 
= C(2p-2) + O(1) + O(1)
= C(2p-3) + O(3)
. . . 
= C(20) + O(p) 
= O(p + 1)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 56
Merge Sort – Um método de ordenação recorrente
„ Exemplo de algoritmo que usa a técnica “divide and conquer”
„ Divide o array ao meio e ordena as duas metades de forma 
recorrente
„ Combina as duas metades ordenadas, resultando no array
ordenado
„ Algoritmo:
Se o array a contém apenas um elemento, pára (caso base).
Senão, faz o seguinte (caso de recorrência):
Copia a primeira metade dos elementos de a para um array
chamado front.
Copia os restantes elementos de a para outro array chamado 
tail.
Ordena o array front com uma chamada recorrente.
Ordena o array tail com uma chamada recorrente. 
Combina os elementos dos arrays front e tail no array a.
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 57
Merge Sort – Um método de ordenação recorrente
public static void sort(int[] a) {
if (a.length >= 2) {
int middle = a.length/2;
int[] front = new int[middle];
int[] tail = new int[a.length-middle];
divide(a, front, tail);
/* ordenar o array front */
sort(front);
/* ordenar o array tail */
sort(tail);
/* junta os arrays no array a, ordenando-os */
merge(a, front, tail);
}
}
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 58
Merge Sort – Um método de ordenação recorrente
public static void divide(int[] a, int[] front, int[] tail) 
{
int i;
for (i = 0; i < front.length; ++i) 
front[i] = a[i];
for (i = 0; i < tail.length; ++i) 
tail[i] = a[front.length+i];
}
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 59
Merge Sort – Um método de ordenação recorrente
public static void merge(int[] a, int[] front, int[] tail) {
int indexF = 0, indexT = 0, indexA = 0;
while (indexF < front.length && indexT < tail.length) {
if (front[indexF] < tail[indexT]) { a[indexA] = front[indexF]; 
++indexF; }
else { a[indexA] = tail[indexT]; ++indexT; }
++indexA;
}
/* Se existir, copiar o resto de front */
while (indexF < front.length) {
a[indexA] = front[indexF]; ++indexF; ++indexA;
}
/* Se existir, copiar o resto de tail */
while (indexT < tail.length) {
a[indexA] = tail[indexT]; ++indexT; ++indexA;
}
}
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 60
Programa recorrente que, em cada passo, tem de examinar todos os
dados de entrada antes, durante ou depois de os dividir em duas 
metades
Equação de recorrência: C(n)=2C(n/2)+O(n) para n ≥ 2 com 
C(1)=O(1)
Solução: C(n) = O(n lg n)
Demonstração: 
considerar n = 2p (p = lg n) e
usar a propriedade telescópica e
aplicar a fórmula a si própria
Análise: Equação de recorrência
O(1)
2
)C(2
2
)C(2
)O(2)2C(2)C(2
1p
1p
p
p
p1pp
+=
+=
−
−
−
O(p)
O(1)O(1)
2
)C(2
2p
2p
=
=
++= −
−
K
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 61
Análise: Procura sequencial e procura binária
„ Dois algoritmos básicos que nos permitem ver se um elemento de 
uma sequência de objectos aparece num conjunto de objectos 
previamente guardados
„ permite ilustrar o processo de análise e comparação de algoritmos
„ Exemplo de aplicação:
„ companhia de cartões de crédito quer saber se as últimasM 
transacções envolveram algum dos N cartões dados como 
desaparecidos ou de maus pagadores 
„ Pretende-se estimar o tempo de execução dos algoritmos
„ N é muito grande (ex: 104 a 106) e M enormíssimo (106 a 109)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 62
Procura Sequencial - Solução trivial
„ Assumir que
„ os objectos são representados por números inteiros
„ dados armazenados num array
„ procura é sequencial no array
static int search(int a[], int v, int l, int r) { 
int i; 
for (i = l; i <= r; i++) {
if (v == a[i]) 
return i; 
}
return -1; 
} 
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 63
Procura Sequencial - Análise (1)
„ O tempo de execução depende se o objecto está ou não no array
„ se não estiver percorremos o array todo (N elementos)
„ se estiver podemos descobrir logo no início (ou no fim)
„ tempo depende dos dados! 
„ a melhor garantia que podemos dar é que não examinados mais do 
que N elementos
„ Para realizar previsões temos que assumir algo sobre os dados:
„ números são aleatórios (não relacionados entre si) ?
„ esta propriedade é crítica! 
„ Assumir algo sobre a procura
„ estudar o caso de sucesso e o de insucesso separadamente
„ tempo de comparação assumido constante
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 64
Procura Sequencial - Análise (2)
„ Propriedade: na procura sequencial o número de elementos do 
array que são examinados é:
„ N em caso de insucesso
„ em média aproximadamente N/2 em caso de sucesso
„ Tempo de execução é portanto proporcional a N (linear)!
„ Isto para cada elemento de entrada
„ Custo total é O(MN) que é enorme 
„ Como melhorar o algoritmo?
„ manter os números ordenados no array
„ na procura sequencial num array ordenado o custo é N no pior caso e 
N/2 em média (quer haja sucesso ou não)
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 65
Procura Binária
„ Se demorar c microsegundos a examinar um número e M =109, 
N =106
„ tempo total de verificação são 16c anos !!
„ Melhoramento: usar procura binária
„ Propriedade: A procura binária nunca examina mais do que 
⎣lg n⎦ + 1 números (propriedade demonstrada anteriormente 
com resolução de equação de recorrência)
„ Mostra que este tipo de pesquisa permite resolver problemas até
um milhão de dados com cerca de 20 comparações por procura
„ possivelmente menos do que o tempo que demora a ler ou escrever 
os números num computador real 
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 66
Estudo empírico de algoritmos de procura
S - Procura Sequencial B - Procura binária
M = 1000 M = 10000 M = 100000 
N S B S B S B
125 3 3 36 12 357 126
250 6 2 63 13 636 130
500 13 1 119 14 1196 137
1250 28 1 286 15 2880 146
2500 57 1 570 16 154
5000 113 1 1172 17 164
12500 308 2 3073 17 173
25000 612 1 19 183
50000 1217 2 20 196
100000 2682 2 21 209
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 67
Conclusões da análise do exemplo
„ Identificação de operações básicas de forma abstracta 
„ Utilização de análise matemática para estudar a frequência com 
que um algoritmo executa essas operações 
„ Utilizar resultados para deduzir uma estimativa funcional do 
tempo de execução 
„ Verificar e estender estudos empíricos 
„ Identificar e eventualmente optimizar as características mais 
relevantes de um dado algoritmo
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 68
Garantias, Previsões e Limitações (1)
„ O tempo de execução dos algoritmos depende criticamente dos 
dados.
„ Objectivo da análise é
„ eliminar essa dependência
„ inferir o máximo de informação assumindo o mínimo possível
„ O estudo do pior caso é importante:
„ permite obter garantias sobre o tempo de execução do programa
„ se o resultado no pior caso é aceitável, então a situação é favorável
„ é desejável utilizar algoritmos com bom desempenho no pior caso
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 69
Garantias, Previsões e Limitações (2)
„ O estudo do pior caso é importante:
„ se o resultado no pior caso for mau, pode ser problemático
„ não sabemos quão provável será aparecerem dados que levem a esse 
desempenho
„ p.ex. demonstra-se que o algoritmo de união rápida é O(M lg N) para 
dados típicos e O(MN) para o pior caso
„ importante não sobrevalorizar obtenção de valores baixos para o 
pior caso
„ não é relevante melhorar o desempenho no pior caso à custa de piorar o 
desempenho global do algoritmo em dados típicos
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 70
Garantias, Previsões e Limitações (3)
„ O estudo do desempenho no caso médio é atractivo: 
„ permite fazer previsões
„ bom quando é possível caracterizar muito bem os dados de entrada 
(tipo, frequência, etc.)
„ mau quando tal não é possível/fácil
„ ex: processar texto aleatório num ficheiro versus processar o texto de 
um livro de Eça de Queiroz!
„ análise pode ser não trivial em termos matemáticos
„ ex: no algoritmo de união rápida
„ saber o valor médio pode não ser suficiente
„ podemos ter de saber o desvio padrão ou outras características
„ na análise do caso médio estamos interessados em saber a 
probabilidade de o algoritmo ser dramaticamente mais lento que o
esperado
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 71
Garantias, Previsões e Limitações (4)
„ Análise descrita permite obter limites superiores ou valores 
esperados (em certos casos)
„ por vezes é relevante obter também limites inferiores! 
„ Se os limites inferiores e superiores forem próximos
„ é infrutífero tentar optimizar mais um algoritmo ou processo
„ mais vale tentar optimizar a implementação
„ Análise pode dar indicações preciosas sobre como e onde 
melhorar o desempenho de um algoritmo
„ nem sempre é o caso no entanto!
LEIC – AED – Inverno 2007/08 Análise de Algoritmos e Complexidade 72
Algoritmos – Síntese da Aula 4
„ Recorrências básicas (continuação)
„ Procura binária
„ Ordenação MergeSort
„ Exemplo: Procura
„ Procura sequencial versus Procura binária
„ Estudo empírico de métodos de procura
„ Conclusões do exemplo
„ Garantias, previsões e limitações
	Capítulo 2 - Análise de Algoritmos e Complexidade
	Análise de Algoritmos (1)
	Análise de Algoritmos (2)
	Análise de Algoritmos (3)
	Análise de Algoritmos (4)
	Tipos de dados de entrada (1)
	Tipos de dados de entrada (2)
	Análise: Crescimento de Funções (1)
	Análise: Crescimento de Funções (2)
	Análise: Crescimento de Funções (3)
	Análise: Crescimento de Funções (4)
	Análise: Crescimento de Funções (5)
	Análise: Crescimento de Funções (6)
	Análise: Resolução de grandes problemas (1)
	Análise: Resolução de grandes problemas (2)
	Análise: Complexidade
	Análise: Funções Relevantes
	Algoritmos – Síntese da Aula 1
	Análise: Notação "O grande" (1)
	Análise: Notação "O grande" (2)
	Análise: Notação "O grande" (3)
	Análise: Notação "O grande" (4)
	Análise: Notação "O grande" (5)
	Análise: Notação "O grande" (6)
	Análise: Notação "O grande" (7)
	Exemplo: vantagens da notação (1)
	Exemplo: vantagens da notação (2)
	Algoritmos – Síntese da Aula 2
	Operações sobre dados - Complexidade
	Acesso e modificação de variáveis
	Eficiência no acesso e modificação
	Inserção de componentes
	Eficiência na inserção
	Remoção de componentes
	Eficiência na remoção
	Metodologia para determinação de complexidade (1)
	Metodologia para determinação de complexidade (2)
	Metodologia para determinação de complexidade (3)
	Recorrência e Funções recorrentes (1)
	Recorrência e Funções recorrentes (2)
	Recorrência e Funções recorrentes (3)
	Análise: Recorrências básicas (1)Análise: Recorrências básicas (2)
	Análise: Recorrências básicas (3)
	Análise: Recorrências básicas (4)
	Análise: Recorrências básicas (5)
	Análise: Recorrências básicas (6)
	Análise: Recorrências básicas (7)
	Algoritmos – Síntese da Aula 3
	Pesquisa binária
	Pesquisa binária
	Pesquisa binária - Exemplo
	Pesquisa binária - Exemplo
	Pesquisa binária
	Análise: Equação de recorrência
	Merge Sort – Um método de ordenação recorrente
	Merge Sort – Um método de ordenação recorrente
	Merge Sort – Um método de ordenação recorrente
	Merge Sort – Um método de ordenação recorrente
	Análise: Equação de recorrência
	Análise: Procura sequencial e procura binária
	Procura Sequencial - Solução trivial
	Procura Sequencial - Análise (1)
	Procura Sequencial - Análise (2)
	Procura Binária
	Estudo empírico de algoritmos de procura
	Conclusões da análise do exemplo
	Garantias, Previsões e Limitações (1)
	Garantias, Previsões e Limitações (2)
	Garantias, Previsões e Limitações (3)
	Garantias, Previsões e Limitações (4)
	Algoritmos – Síntese da Aula 4

Continue navegando