Área que visa determinar a complexidade (custo) de um algoritmo

Propaganda
Introdução à Complexidade de Algoritmos
Área que visa determinar a complexidade (custo) de
um algoritmo, com isso é possível:
y Comparar algoritmos: existem algoritmos que
resolvem o mesmo tipo de problema.
y Determinar
D t
i
se o algoritmo
l it
é “óti
“ótimo”:
” os algoritmos
l it
apresentam um limite inferior para a sua
complexidade (definido matematicamente).
|Se a complexidade é ótima então está abaixo
deste limite.
Fonte: UFPB (http://www.slideshare.net/alexandrend/anlise-de-complexidade-de-algoritmos)
Introdução à Complexidade de Algoritmos
Um algoritmo serve para resolver um determinado
problema, e todos os problemas têm sempre uma
entrada de dados
| O tamanho dessa entrada (N) tem geralmente
efeito direto no tempo de resposta de um algoritmo
| Dependendo do problema a ser resolvido
resolvido, já
existem algoritmos prontos ou que podem ser
adaptados
|
|
O problema é: qual algoritmo escolher?
Introdução à Complexidade de Algoritmos
|
Pode-se falar de dois tipos de complexidade de
algoritmos :
Complexidade Espacial: Quantidade de recursos
utilizados p
para resolver o p
problema;;
y Complexidade Temporal: Quantidade de tempo utilizado.
y
|
Pode ser vista também como o número de instruções
necessárias para resolver um determinado problema;
Em ambos os casos, a complexidade é medida de
acordo com o tamanho dos dados de entrada (n)
| Estamos mais interessados em calcular a
Complexidade Temporal de um algoritmo!
|
Introdução à Complexidade de Algoritmos
|
Existem três perspectivas para análise de
complexidade:
Melhor Caso (Ω)
y Caso Médio (θ)
y Pior Caso
(O)
y
|
Nas três perspectivas
perspectivas, a função f(n) retorna a
complexidade de um algoritmo com entrada de
tamanho n
Introdução à Complexidade de Algoritmos
ANÁLISE DO MELHOR CASO
Definido pela letra grega Ω(Ômega)
| Exprime o menor tempo de execução de um
algoritmo
g
p
para uma entrada de tamanho n
| É pouco usado, por ter aplicação em poucos
casos.
casos
| Ex.:
|
O algoritmo de pesquisa sequêncial em um vetor tem
complexidade f(n) = Ω(1)
y A análise assume que o número procurado seria o
primeiro selecionado na lista.
y
|
Abordagem otimista!
Introdução à Complexidade de Algoritmos
ANÁLISE DO CASO MÉDIO
Definido p
pela letra g
grega
g θ ((Theta))
| Deve-se obter a média dos tempos de execução
de todas as entradas de tamanho n
n, ou baseado
em probabilidade de determinada condição ocorrer
| Ex.:
Ex :
|
O algoritmo de pesquisa sequêncial em um vetor tem
complexidade f(n) = θ(n/2)
y Em média será necessário visitar n/2 elementos do vetor
até encontrar o elemento procurado
p
y
Melhor aproximação
| Muito difícil de determinar na maioria dos casos
|
Introdução à Complexidade de Algoritmos
ANÁLISE DO PIOR CASO
|
Representado pela letra grega O (big O)
y
Big O maiúsculo. Trata-se da letra grega ômicron
maiúscula
Baseia-se no maior tempo de execução sobre
todas as entradas de tamanho n (ordem de
grandeza)
| É o método mais fácil de se obter ((o mais usado).
)
| Ex.:
|
O algoritmo de pesquisa sequêncial em um vetor tem
complexidade f(n) = O(n)
y No p
pior caso será necessário visitar todos os n
elementos do vetor até encontrar o elemento procurado
y
|
Abordagem pessimista!
Introdução à Complexidade de Algoritmos
A Notação
ç O
| Tempo (ou espaço) é contabilizado em número de
passos do algoritmo (unidade de armazenamento)
| Análise do algoritmo determina uma função que
depende do tamanho da entrada n
n.
| à medida que n aumenta, aumenta a
complexidade do algoritmo (esforço
computacional)
8
Introdução à Complexidade de Algoritmos
A Notação
ç O
| Desprezar constantes aditivas ou multiplicativas
y
|
Número de passos 3n será aproximado para n
Interesse assintótico
y
termos de menor grau podem ser desprezados
n2 + n será aproximado para n2
| 6n3 + 4n - 9 será aproximado para n3
|
9
Introdução à Complexidade de Algoritmos
Cálculo da complexidade
p
do algoritmo
g
| Foi visto que, para calcular a complexidade de um
algoritmo, deve-se
deve se analisar o pior caso (O(x))
| A análise deve ser feita de acordo com a tabela a
seguir
Nú
Número
de
d Operações
O
õ
C
Complexidade
l id d
f(n)
O(f(n))
c x f(n)
O(f(n))
f(n) + f(n)
O(f(n))
f(n) + g(n)
O(max(f(n),g(n))
f(n) x g(n)
O(f(n) x g(n))
Introdução à Complexidade de Algoritmos
Técnicas de análise da complexidade do algoritmo
Alguns princípios podem ser seguidos:
1. O tempo de execução de um comando de atribuição, de
leitura ou de escrita pode ser considerado como O(1).
2. O tempo de execução de um comando de decisão é O(1);
3 O tempo para executar um looping é a soma do tempo de
3.
execução do corpo do looping, multiplicado pelo número de
iterações do looping
looping.
4. Quando o programa possui funções não recursivas, o tempo
de execução de cada função deve ser computado
separadamente um a um, iniciando com funções que não
chamam outras funções
funções.
|
Introdução à Complexidade de Algoritmos
Cálculo da complexidade
p
do algoritmo
g
– Ex1
f(x)=1
f(x)
1+1+1+n*(n*(n*(1+1+1+3
)))
3+n*n* n*6
3 + 6n3
f(x) = O(n3)
Desprezouse os
termos de
menor grau
ORDENS DE ALGORITMOS
Complexidade Constante
| Complexidade Linear
| Complexidade Logarítmica
| Complexidade Log Linear
| Complexidade Quadrática
| Complexidade Cúbica
| Complexidade Exponencial
| Complexidade Fatorial
|
COMPLEXIDADE CONSTANTE - O(1)
São os algoritmos onde a complexidade independe
do tamanho n de entradas
| É o único em que as instruções dos algoritmos são
executadas um número fixo de vezes
|
if (condição == true) then {
realiza alguma operação em tempo constante
1
}
)
else {
1+(
g
operação
p ç em tempo
p constante
realiza alguma
}
|
1+(
f( ) = 1
f(x)
1+(1)*1+(1)
(1)*1 (1) = 4 => O(1)
1
)
COMPLEXIDADE LINEAR – O(N)
|
Uma operação é realizada em cada elemento de
entrada, ex.: pesquisa de elementos em uma lista
for (i = 0; i < N; i++) {
if (condição == true){
comandos de leitura, escrita ou condicionais;
1
)
else {
1+(
}
|
1+(
}
comandos de leitura, escrita ou condicionais;
}
n*(
1
)
)
f(x) = n*(1+(1)*1+(1))=> n*(2*2) = n(4) =>O(n)
COMPLEXIDADE LOGARÍTMICA O(LOG2N)
|
Ocorre tipicamente em algoritmos que dividem o problema em problemas
menores
int PesquisaBinaria ( int array[], int chave , int N){
int inf = 0;
int sup = N - 1;
int meio;
while (inf <= sup) {
meio = (inf+sup)/2;
if (chave == array[meio]){
return meio;
}
else{
if (chave < array[meio]){
sup = meio-1;
}
else{
inf = meio+1;
}
}
}
return -1; // não encontrado
}
|
(
1+
1+
1
n*(
1+
1+(
1
)
1+(
1+(
1
)
1+(
1
)
)
)
1
)
f(x) = (1+1+1*n*(1+1+(1)*1+(1+(1)*1+(1)))*1) = 3*n(6). Como Log2(6) = 3 => (Log2(n))
COMPLEXIDADE LOG LINEAR –
O(NLOG2N)
|
Ocorre tipicamente em algoritmos que dividem o
problema em problemas menores, porém juntando
posteriormente a solução dos problemas menores.
void merge(int inicio, int fim) {
if (inicio < fim) {
int meio = (inicio + fim) / 2;
merge(inicio meio);
merge(inicio,
merge(meio + 1, fim);
mesclar(inicio, meio, fim);
}
}
COMPLEXIDADE QUADRÁTICA – O(N²)
|
Itens são processados aos pares, geralmente com
um loop dentro do outro
void bubbleSort(int[] a) {
for (int i = 0; i < a.length-1; i++) {
for (int j = 0; j < a.length
a length-1;
1; jj++)) {
if (a[j] > a[j+1]) {
swap(a, j, j+1);
}
}
}
}
|
(
n*(
n*((
n
1+(
3
)
)
)
)
f(x) = (n*(n*(1+(3)))) = (n*(n+4)) = n2+4n => O(n2)
COMPLEXIDADE CÚBICA – O(N³)
|
|
Itens são processados três a três, geralmente com
um loop dentro do outros dois
int dist[N][N];
int i, j, k;
1
1+
1+
for ( k = 0; k < N; k++ )
f ( i = 0; i < N; i++ )
for
for ( j = 0; j < N; j++ )
dist[i][j] = min( dist[i][j], dist[i][k] + dist[k][j] );
n*(
n*(
*(
n*(
1)))
f(x) = 1+1+n*(n*(n*(1))) = 4+n3 => O(n3)
COMPLEXIDADE EXPONENCIAL – O(2N)
Utilização de “Força Bruta” para encontrar a
solução de um problema.
| A solução geralmente é baseada diretamente no
enunciado do problema e nas definições dos
conceitos envolvidos
| Ex.:
Ex :
|
Utilizando apenas números é possível criar 10n senhas
de n dígitos
y Um algoritmo de força bruta para quebrar uma dessas
senhas tem complexidade O(2n)
y
COMPLEXIDADE FATORIAL – O(N!)
Também é baseada na utilização de força bruta
para encontrar a solução de um problema
| Consiste em testar todas as possíveis
permutações existentes na solução à procura da
solução ótima para o problema
| Ex.:
Ex : Problema do Caixeiro Viajante
|
Encontrar a rota mínima para visitar várias cidades sem
repetir nenhuma
y É um problema base para o projeto de microchips,
sequênciamento de genôma e muitas outras aplicações
y Não possui solução exata eficiente (Problema NP)
y Utilização de heurísticas para aproximar a solução ótima
y
22
ORDENS DE COMPLEXIDADE
Imagine um computador que leva 1ms (0,00s) para
executar uma operação.
| A tabela abaixo indica o tempo aproximado de
execução de um algoritmo com diferentes ordens
de complexidades para 3 tamanhos de entrada
|
n
O(n)
Log2(n)
nLog2(n)
O(n2)
O(n3)
O(2n)
16
0.016s
0.004s
0.064s
0.256s
4s
32
0.032s
0.005s
0.16s
1s
33s
512
0.512s
0.009s
4.608s
4m22s
37h
h
O(n!)
1m5s 663 anos
49 dias
10143 sec
1023 sec
...
23
Introdução à Complexidade de Algoritmos
Exemplo de estudo comparativo da complexidade de algoritmos:
- Dado 3 algoritmos
algoritmos, verificar
erificar q
qual
al deles demanda maior ccusto,
sto
seguindo o princípio do pior caso.
| Algoritmo
1: Soma de vetores:
for(i=0;i<n;i++){
for(i
0;i n;i ){
S[i] = X[i] + Y[i];
}
f(x) = n*(1) => f(x) = O(n)
E ã complexidade
Então,
l id d lilinear (O(
(O(n))
))
n(
n*(
1
)
Introdução à Complexidade de Algoritmos
Exemplo de estudo comparativo da complexidade de algoritmos - continuação
| Algoritmo
2: Soma de matrizes:
for(i=0;i<n;i++){
n*(
for(j=0;j<n;j++){
for(j
0;j n;j ){
n*((
n
C[i,j] =A[i,j] + B[i,j];
1
}
)
}
)
g(x) = n*(n*(1)) => h(x) = O(n2)
Então, grau de complexidade quadrática (O(n2))
Introdução à Complexidade de Algoritmos
Exemplo de estudo comparativo da complexidade de algoritmos - continuação
| Algoritmo
3: Produto de matrizes:
f (i 0 i< i++){
for(i=0;i<n;i++){
for(j=0;j<n;j++){
P[i,j] =0;
for(k=0;k<n;k++){
(
;
;
){
P[i,j] = P[i,j] + A[i,k] * B[k,j]
}
}
}
n*(
*(
n*(
1+
n*((
1
)
)
)
h(x) = n*(n*(1+n*(1))) = n*(n*(1+n)) = n*(n+n2) = n*(n2)=>h(x)=
) >h(x) O(n3)
Então, grau de complexidade cúbica (O(n3))
Introdução à Complexidade de Algoritmos
Exemplo de estudo comparativo da complexidade de algoritmos - continuação
|
Comparando agora os três algoritmos dos
exemplos anteriores, temos:
f(x)+g(x)+h(x)
f(
)+ ( )+h( ) = max(O(n),O(n
(O( ) O( 2),O(n
) O( 3))
| Dessa forma, concluímos que o algoritmo que teve
o maior custo foi o do exemplo 3 (h(x) = O(n3)),
pois o expoente do grau de complexidade (n) é o
maior
i é o maior
i d
deles
l ((expoente
t 3)
3).
| Então, seu grau de complexidade resultante é
cúbico.
|
27
Introdução à Complexidade de Algoritmos
Exercícios
|
1.
Informe a complexidade dos algoritmos abaixo:
i t a,b,
int
b aux;
scanf(“%d%d”,&a,&b);
aux = a;
a = b;
b = aux;
printf(“%d , %d”
%d”,a,b);
a b);
Introdução à Complexidade de Algoritmos
Exercícios
2.
float media, notas[100];
int ii, soma = 0
0, media;
for(i=0;i<=100;i++)
{
printf(“entre com a nota”);
scanf(“%d”,&notas[i]);
soma = soma + notas[i];
}
media
ed a = so
soma/100;
a/ 00;
printf(“A media é: %d”, media);
Introdução à Complexidade de Algoritmos
Exercícios
3.
for(i=0;i<=N_LIN1;i++)
{
for(j=0;j<=N_COL2;j++)
{
C[i,j] = 0;
for(k=0;k<=N_COL1;k++)
{
C[i,j] = C[i,j] + A[i,k] * B[k,j];
}
}
}
Introdução à Complexidade de Algoritmos
Exercícios
4.
for(j=1;j<=n;j++){
for(k=1;k<=n;k++){
p=p+1;
}
}
Introdução à Complexidade de Algoritmos
Exercícios
|
Faça agora um estudo comparativo e determine qual ou
quais dos 4 algoritmos do exercícios anterior tem a maior
complexidade
Introdução à Complexidade de Algoritmos
Exercícios
Prova de concursos:
(ENADE-2005-Q15) - Considere o algoritmo que implementa o
seguinte processo: uma coleção desordenada de elementos
é dividida em duas metades e cada metade é utilizada como
argumento
t para a reaplicação
li
ã recursiva
i d
do procedimento.
di
t O
Os
resultados das duas reaplicações são, então, combinados
pela intercalação dos elementos de ambas
ambas, resultando em
uma coleção ordenada. Qual é a complexidade desse
algoritmo?
(A) O(n2)
(B) O(n2n)
(C) O(2n)
(D) O(log n × log n)
(E) O(n × log n)
|
UNIDADE II
Introdução à Complexidade
p
de Algoritmos
g
FIM
Download