análise de algoritmos · • típico em algoritmos que quebram um problema em outros menores,...
Post on 19-Aug-2020
6 Views
Preview:
TRANSCRIPT
Análise de Algoritmos Parte 3 Prof. Túlio Toffolo http://www.toffolo.com.br
BCC202 – Aula 06
Algoritmos e Estruturas de Dados I
Como escolher o algoritmo mais adequado para uma situação?
(continuação)
Exercício da última aula teórica
• Obtenha a função de complexidade f(n) dos algoritmos abaixo. Considere apenas as operações envolvendo as variáveis x e y. Para cada algoritmo, responda:
• Qual o valor da variável x ao final da execução do algoritmo?
• O algoritmo é O(n2)? É Ω(n3)?
• O algoritmo é Ө(n3)?
void exercicio1(int n) { int i, j, x, y; x = y = 0; for (i = 1; i <= n; i++) { for (j = i; j <= n; j++) x = x + 1; for (j = 1; j < i; j++) y = y + 1; }}
void exercicio2(int n) { int i, j, k, x; x = 0; for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= j; k++) x = x + j + k; x = i;}
Perguntas?
Comportamento Assintótico de Funções
• Nas aulas passadas aprendemos:
• Como calcular a função de complexidade f(n).
Ø Melhor caso x Caso médio x Pior caso
Ø Qual a influência desta função em algoritmos aplicados sobre problemas de tamanho pequeno?
Ø E sobre problemas grandes?
Ø Estuda-se o comportamento assintótico das funções de custo. O que isto significa?
5
void MaxMin1(int* A, int n, int* pMax, int* pMin) { int i; *pMax = A[0]; *pMin = A[0]; for (i = 1; i < n; i++) { if (A[i] > *pMax) *pMax = A[i]; if (A[i] < *pMin) *pMin = A[i]; } }
2*(n-1)
Qual a ordem de complexidade?
6
void MaxMin2(int* A, int n, int* pMax, int* pMin) { int i; *pMax = A[0]; *pMin = A[0]; for (i = 1; i < n; i++) { if (A[i] > *pMax) *pMax = A[i]; else if (A[i] < *pMin) *pMin = A[i]; } }
2*(n-1)
Qual a ordem de complexidade?
7
Comportamento Assintótico de Funções
• Nas aulas passadas também aprendemos:
• Comportamento assintótico das função de complexidade f(n).
Ø Dominação Assintótica
Ø Notação O
Ø Notação Ω e Notação Ө.
8
Operações com a Notação O
9
Dominação Assintótica
• f(n) domina assintoticamente g(n) se:
Ø Existem duas constantes positivas c e m tais que, para n ≥ m, temos |g(n)| ≤ c|f(n)|.
10
Notação O
• O valor da constante m mostrado é o menor valor possível, mas qualquer valor maior também é válido.
• Definição: uma função g(n) é O(f(n)) se existem duas constantes positivas c e m tais que g(n) ≤ c f(n), para todo n ≥ m.
11
Notação Ω
• Especifica um limite inferior para g(n).
• Definição: Uma função g(n) é Ω(f(n)) se:
Ø Existem duas constantes positivas c e m tais que, para n ≥ m, temos |g(n)| ≥ c|f(n)|.
12
Notação Ө
• Exemplo gráfico de dominação assintótica que ilustra a notação Ө.
• Especifica um limite assintótico firme para g(n).
Ø Para ser Ө(f(n)), uma função deve ser ao mesmo tempo O(f(n)) e Ω(f(n)).
13
Notação Ө
Ø Para mostrar que g(n) = 3n3 + 2n2 é Ω(n3) basta fazer: c = 1, e então 3n3 + 2n2 ≥ n3 para n ≥ 0.
Ø Seja g(n) = n2 para n par (n ≥ 0) g(n) = n para n ímpar (n ≥ 1).
Neste caso g(n) poderá ser:
Ω(n2), se considerarmos apenas entradas pares
Ω(n), se considerarmos apenas entradas ímpares
Se considerarmos qualquer entrada possível, então g(n) é Ω(n)
14
Perguntas....
• n é O(n log n)? Esta afirmação é útil?
• n3 é Ω(n)? Esta afirmação é útil?
• n é O(n)?
• n é Ω(n)?
• n é Ө(n)?
• n é Ө(n log n)?
15
Comparação de Programas
• Um programa com tempo de execução O(n) é melhor que outro com tempo O(n2).
• Porém, as constantes de proporcionalidade podem alterar esta consideração.
• Exemplo: um programa leva 100n unidades de tempo para ser executado e outro leva 2n2. Qual dos dois programas é melhor?
• Depende do tamanho do problema.
• Para n < 50, o programa com tempo 2n2 é melhor do que o que possui tempo 100n.
16
• f(n) = O(1) • Algoritmos de complexidade O(1) são ditos de complexidade
constante.
• Uso do algoritmo independe de n.
• As instruções do algoritmo são executadas um número fixo de vezes.
Principais Classes de Problemas
17
• f(n) = O(log n) • Um algoritmo de complexidade O(log n) é dito ter complexidade
logarítmica.
• Típico em algoritmos que transformam um problema em outros menores.
• Pode-se considerar o tempo de execução como menor que uma constante grande.
• Quando n é mil, log2n 10, quando n é 1 milhão, log2n 20.
• Para dobrar log n temos que elever n ao quadrado….
• A base do logaritmo muda pouco estes valores: quando n é 1 milhão, o log2n é 20 e o log10n é 6.
Principais Classes de Problemas
18
Principais Classes de Problemas
• f(n) = O(n) • Um algoritmo de complexidade O(n) é dito ter complexidade
linear
• Em geral, um pequeno trabalho é realizado sobre cada elemento de entrada
• É a melhor situação possível para um algoritmo que tem de processar/produzir n elementos de entrada/saída.
• Cada vez que n dobra de tamanho, o tempo de execução dobra.
19
• f(n) = O(n log n) • Típico em algoritmos que quebram um problema em outros
menores, resolvem cada um deles independentemente e juntando as soluções depois.
• Quando n é 1 milhão, nlog2n é cerca de 20 milhões.
• Quando n é 2 milhões, nlog2n é cerca de 42 milhões, pouco mais do que o dobro.
Principais Classes de Problemas
20
Principais Classes de Problemas
• f(n) = O(n2) • Um algoritmo de complexidade O(n2) é dito ter complexidade
quadrática.
• Ocorrem quando os itens de dados são processados aos pares, muitas vezes em um anel dentro de outro.
• Quando n é mil, o número de operações é da ordem de 1 milhão.
• Sempre que n dobra, o tempo de execução é multiplicado por 4.
• Úteis para resolver problemas de tamanhos relativamente pequenos.
21
Principais Classes de Problemas
• f(n) = O(n3) • Um algoritmo de complexidade O(n3) é dito ter complexidade
cúbica.
• Úteis apenas para resolver pequenos problemas.
• Quando n é 100, o número de operações é da ordem de 1 milhão.
• Sempre que n dobra, o tempo de execução fica multiplicado por 8.
22
Principais Classes de Problemas
• f(n) = O(2n) • Um algoritmo de complexidade O(2n) é dito ter complexidade
exponencial.
• Geralmente não são úteis sob o ponto de vista prático.
• Ocorrem na solução de problemas quando se usa força bruta para resolvê-los.
• Quando n é 20, o tempo de execução é cerca de 1 milhão. Quando n dobra, o tempo fica elevado ao quadrado.
23
Principais Classes de Problemas
• f(n) = O(n!) • Um algoritmo de complexidade O(n!) é dito ter complexidade
exponencial, apesar de O(n!) ter comportamento muito pior do que O(2n).
• Geralmente ocorrem quando se usa força bruta para resolver o problema.
• n = 20 → 20! = 2.432.902.008.176.640.000, um número com 19 dígitos.
• n = 40 → um número com 48 dígitos.
24
25
26
Algoritmo Polinomial
• Algoritmo exponencial no tempo de execução tem função de complexidade O(cn); c > 1.
• Algoritmo polinomial no tempo de execução tem função de complexidade O(p(n)), onde p(n) é um polinômio.
• A distinção entre estes dois tipos de algoritmos torna-se significativa quando o tamanho do problema a ser resolvido cresce.
• Por isso, os algoritmos polinomiais são muito mais úteis na prática do que os exponenciais.
27
Quem vê, entende...
Mas é quem faz que aprende!
28
Exercício 1
• Indique se as afirmativas a seguir são verdadeiras ou falsas e justifique a sua resposta
• É melhor um algoritmo que requer 2n passos do que um que requer 10n10 passos.
• 2n+1 = O(2n).
• f(n) = O(u(n)) e g(n) = O(v(n)) => f(n) + g(n) = O(u(n) + v(n))
• f(n) = O(u(n)) e g(n) = O(v(n)) => f(n) - g(n) = O(u(n) - v(n))
29
Exercício 2
// Considere A, B e C vetores globaisvoid p1 (int n) { int i, j, k; for (i=0; i<n; i++) for (j=0; j<n; j++) { C[i][j]=0; for (k=n-1; k>=0; k--) C[i][j]=C[i][j]+A[i][k]*B[k][j]; }}
30
• Calcule a função de complexidade e a complexidade assintótica de p1
Exercício 3
void p2 (int n){ int i, j, x, y; x = y = 0; for (i=1; i<=n; i++) { for (j=i; j<=n; j++) x = x + 1; for (j=1; j<i; j++) y = y + 1; }}
31
void p3 (int n){ int i, j, x, y; x = y = 0; for (i=1; i<=n; i++) { for (j=i; j<=n; j++) x = x + 1; }}
• Calcule a função de complexidade e a complexidade assintótica de p2 e p3. Qual é mais rápido?
Perguntas?
top related