Vous êtes sur la page 1sur 5

Análise de Algoritmos e Estrutura de Dados – 1° Semestre de 2018

1 ª Lista de Exercícios

1) Análise de complexidade de algoritmos

a) 5n² + n é O(n²)?
5n² + n ≤ c.n²
para c = 6
5n² + n ≤ 6n²
5n² - 6n² + n ≤ 0
- n² + n ≤ 0
n² - n ≥ 0
Resolvendo a inequação de 2° grau temos que n pode ter como solução ( 0 ; 1 )
Então para c = 6 e n ≥ 1
5.1² + 1 ≤ 6.1
6 ≤ 6 Verdadeiro!
f(n) = O(n²)

b) 2n4 + 2n² é O(n4)?


2n4 + 2n² ≤ c.n4
para c = 3
2n4 + 2n² ≤ 3.n4
2n4 -3.n4 + 2n² ≤ 0
-n4 + 2n² ≤ 0
n4 - 2n² ≥ 0
assumindo uma possível solução de n ≥ 2 e c = 3:
2(2) 4 + 2(2²) ≤ 3(24)
40 ≤ 48 Verdadeiro
f(n) = O(n4)

c) 2n+1 é O(2n)?
2n+1 ≤ 2c.n
Analisando somente o expoente
n + 1 ≤ c.n
para c = 2;
n + 1 ≤ 2n
1 ≤ 2n – n
1≤n
Portanto para c = 2 e n ≥ 1 f(n) = O(2n)

22n é O(2n)?
22n ≤ 2c.n
Analisando somente o expoente
2n ≤ c.n
para c = 3;
2n ≤ 3n
1 ≤ 3n – 2n
1≤n
Portanto para c = 2 e n ≥ 1 f(n) = O(2n)

d) Ordenando as funções por crescimento de suas complexidades:


1 < 4n < 2n . log n < 22n < n.2n < (log n)! < (n+1)!
e) Busca binária em uma seqüência ordenada.
// n=tamanho da entrada ou do vetor
buscaBinaria (int valor, int n, int vetor[])
{
int esquerda, direita, índice; O(1)
esquerda = 0; O(1)
direita = n-1; O(1)
while (esquerda <= direita) O(n)
{
indice = (esquerda + direita)/2; O(n/2)
if ( vetor[indice] == valor ) O(1)
return m; O(1)
if (vetor[indice] < valor) O(1)
esquerda = indice + 1; O(1)
else
direita = índice – 1; O(1)
}
return(0); O(1)
}

f(n) = 3. O(1) + (n/2).(4.O(1)) + O(1) = (n/2) + O(1)


Como a cada iteração do “while” o espaço de busca é dividido pela metade, definimos
esta divisão (n/2) pela função log2 n.
Portanto, f(n) = O(log2 n ) + O(1)  f(n) = O(log n)
RESUMO
Complexidade de algoritmos

Análise de complexidade é o método utilizado para avaliar o desempenho de um


algoritmo, independentes das características do hardware e do software. Esta análise
fornece uma estimativa do comportamento de tempo necessário para a solução de
problemas que possuem um valor de entrada de dados elevado.
A tecnologia evolui cada vez mais rápido, novos processadores e memórias que permitem
um poder computacional elevado são desenvolvidos constantemente. Contudo, estes
recursos não são infinitos. Por isto deve-se utilizar de forma adequada e eficiente,
reduzindo os custos nas implementações de soluções computacionais.
Um mesmo problema pode ser codificado de formas diferentes e proverem uma solução
adequada, porém o tempo necessário para realizar esta tarefa pode ser muito diferente.
Alguns problemas computacionais comuns são exaustivamente estudados com a
finalidade de buscar uma alternativa menos complexa de algoritmo. Podemos citar como
exemplo os problemas de busca e ordenação de registros.
A medida da análise de complexidade que mede o custo de execução de um algoritmo é
definida por uma função de custo, também denominada função de complexidade. Esta
função mede o tempo necessário para um algoritmo executar as tarefas desejadas para
um problema de tamanho n.
Também é possível neste processo realizar a análise pela função de complexidade de
espaço, que visa medir a quantidade necessária de memória para este algoritmo executar
as operações.
As funções de complexidade podem se divididas em três sub-classes:
- Melhor caso, que é o menor tempo de execução do algoritmo para uma entrada n;
- Pior caso, que é o maior tempo de execução do algoritmo para uma entrada n;
- Caso médio, que é a média dos tempos de execução do algoritmo para uma entrada n.
Para facilitar o enquadramento da função de complexidade é utilizada a notação Big-O,
que apresenta uma hierarquia das funções, listadas abaixo na ordem da menos complexa
para a mais complexa:
- f(n) = O(1) -> complexidade constante;
- f(n) = O(log n) -> complexidade logarítmica;
- f(n) = O(n) -> complexidade linear;
- f(n) = O(n.logn) -> complexidade linear e logarítmica;
- f(n) = O(n²) -> complexidade quadrática;
- f(n) = O(n³) -> complexidade cúbica;
- f(n) = O(2n) -> complexidade exponencial;
- f(n) = O(n!) -> complexidade exponencial, porém com comportamento muito pior que
O(2n).
Com isto, dizemos que dadas duas funções f(n) que representa o problema e g(n) que
representa a classe da função de complexidade, podemos dizer que f(n) é O(g(n)) se
existirem duas constantes não negativas c e m tais que:
f(n) ≤ c.g(n),  n ≥ m.

Conclusões

Ao realizar a análise de um algoritmo busca-se conhecer seu comportamento geral, e não


considerando outros detalhes, como o hardware ou linguagem de programação.
A complexidade de um algoritmo é representada por uma função matemática que
geralmente depende do tamanho de sua entrada.
Desta forma considera-se a eficiência assintótica dos algoritmos quando executados para
um numero de entradas suficientemente grande.

Bibliografia
T.H. Cormen; Algoritmos: teoria e prática.
Ziviani, N; Projetos de algoritmos.

Vous aimerez peut-être aussi