Você está na página 1de 47

Introduo Complexidade de Algoritmos

PUC Minas no So Gabriel Curso de Engenharia de Computao

Complexidade de Algoritmos

Estudo da complexidade de um algoritmo: previso dos recursos de que o mesmo necessitar:


Memria Largura de banda de comunicao Tempo de execuo

OBS: Compromisso Espao x Tempo

Complexidade de Algoritmos

Por que estudar complexidade de algoritmos?

A memria hoje ilimitada, certo? Errado: espao na memria um recurso limitado. Os processadores hoje so rpidos o bastante, certo?

Em parte: aumentou tambm o tamanho dos problemas a serem resolvidos.

Tempo de execuo cresce com o tamanho da entrada.

Complexidade de Algoritmos

Objetivos:

Comparar duas solues para o mesmo problema. Encontrar o algoritmo mais eficiente para resoluo de um problema (anlise da classe de complexidade).

Determinar se um dado algoritmo pode ser melhorado, baseado no conhecimento acima (anlise do custo do algoritmo).

Complexidade de Algoritmos
- No vale a pena garantir uma excelente eficincia se no se garante a correo do algoritmo. - Eficincia + correo = eficcia ( o esperado ). - Complexidade verifica: - a dificuldade em implementar um algoritmo; - a eficcia do algoritmo;

Complexidade de Algoritmos
- Em muitos casos, mais vale: algoritmo simples (+ recursos) X algoritmo + complicado ( - recursos) Ex Algoritmo da Potncia inteira de um nr real. - Algoritmo simples => Mtodo normal. -Algoritmo complicado => Mtodo Recursivo. Potencias pequenas => Economia pequena. Potencias grandes (65.536) => Simples ex. 65.535 mult. Complic. Ex 16 mult.
5

Complexidade de Algoritmos

Como investigar o custo de um algoritmo?

Execuo do programa em um computador e medio do tempo

Problemas: diferenas de compilador; dependncia do hardware, uso de memria virtual

Uso de um modelo matemtico

Definir o conjunto de operaes a ser executado e o custo de cada uma Costuma-se levar em considerao apenas a(s) operao(es) mais significativas

Complexidade de Algoritmos

Medida do custo de execuo: funo de complexidade


f(n) o tempo necessrio para execuo de um problema com entrada de dados de tamanho n Utilizaremos complexidade de tempo f(n): quantidade de vezes que a operao mais relevante executada

Complexidade de Algoritmos

Exemplo:
int max(int[] vetor){ int i, temp; temp = vetor[0]; for(i=0; i<vetor.Length; i++) if(temp < vetor[i]) temp = vetor[i]; return temp; }

Qual a operao mais relevante? Quanto tempo se gasta, em relao ao tamanho N do vetor?
8

Complexidade de Algoritmos

Resposta:
Para efeitos de clculos, vamos considerar relevante: As atribuies feitas, embora no o sejam. F(n) = n-1, para n>0 (depois faremos o correto)

Medida do custo depende fundamentalmente:


Tamanho da entrada Caractersticas peculiares da entrada Ex:


algoritmo de ordenao com dados j ordenados algoritmo de ordenao com dados em posio decrescente algoritmo de ordenao com dados aleatrios
9

Complexidade de Algoritmos

Existem trs cenrios


Melhor caso Pior caso Caso mdio

Diz-se que o algoritmo timo se seu custo igual ao menor custo possvel.

Exemplo: pesquisa em um vetor


Melhor caso: f(n) = 1 Pior caso: f(n) = n Caso mdio: f(n) = (n+1)/2
10

Complexidade de Algoritmos

Problema 2: Obter o mximo e o mnimo de um conjunto.


int[] maxMin_1(int[] vetor){ int i, int[] temp = new int[2]; temp[0] = vetor[0]; temp[1]=vetor[0]; for(i=1; i<vetor.Length; i++) { if(vetor[i] < temp[0]) temp[0] = vetor[i]; if(vetor[i] > temp[1]) temp[1] = vetor[i]; } return temp; }

Melhor, pior e caso mdio?


11

Complexidade de Algoritmos

Problema 2: Obter o mximo e o mnimo de um conjunto.


int[] maxMin_1(int[] vetor){ int i, int[] temp = new int[2]; temp[0] = vetor[0]; temp[1]=vetor[0]; for(i=1; i<vetor.Length; i++) { if(vetor[i] < temp[0]) temp[0] = vetor[i]; if(vetor[i] > temp[1]) temp[1] = vetor[i]; } return temp; }

Melhor caso: f(n) = 3 (crescente, M na seg pos) Pior caso: f(n) = n + 1 (cresc. ou decr.) Caso mdio: f(n) = n + 1 (aleatria) => 2* ((n-1)/2) + 2
11

Complexidade de Algoritmos

Problema 2: melhorando.
int[] maxMin_2(int[] vetor){ int i, int[] temp = new int[2]; temp[0] = vetor[0]; temp[1]=vetor[0]; for(i=1; i<vetor.Length; i++) if(vetor[i] < temp[0]) temp[0] = vetor[i]; else if(vetor[i] > temp[1]) temp[1] = vetor[i]; return temp; }

Melhor, pior e caso mdio?

12

Complexidade de Algoritmos

Problema 2: melhorando.
int[] maxMin_2(int[] vetor){ int i, int[] temp = new int[2]; temp[0] = vetor[0]; temp[1]=vetor[0]; for(i=1; i<vetor.Length; i++) if(vetor[i] < temp[0]) temp[0] = vetor[i]; else if(vetor[i] > temp[1]) temp[1] = vetor[i]; return temp; }

Melhor caso: f(n) = 3 Pior caso: f(n) = n + 1 Caso mdio: f(n) ~ 3(n + 1)/4 = (n-1)/2 + (n-1)/4 + 2
12

Complexidade de Algoritmos

At agora treinamos detalhamento de custos de execuo Para poder comparar algoritmos entre si, vamos considerar: Ordem crescente simples ou Ordem decrescente simples ou Distribuio Aleatria. Desconsideraremos qualquer outro caso particular Contaremos como custo cada comparao em si. Nesse caso, teremos: Sol 1: Melhor, Pior e Caso Mdio = 2(n-1). Sol 2: Melhor: n-1(decrescente); Pior: 2(n-1)(crescente); Caso Mdio: 3(n-1)/2 (aleatrio)

13

Complexidade de Algoritmos

Problema 2: Otimizando 3a Soluo.


Comparar aos pares, separando em dois subconjuntos
1. Compare os elementos de A aos pares, separando-os em dois subconjuntos (maiores em um e menores em outro), a um custo de teto(n/2) comparaes. 2. O mximo obtido do subconjunto que contm os maiores elementos, a um custo de teto(n/2) - 1 comparaes. 3. O mnimo obtido do subconjunto que contm os menores elementos, a um custo de teto(n/2) - 1 comparaes.

Considerando o nmero de comparaes realizadas, existe a possibilidade de obter um algoritmo mais eficiente:

13

Complexidade de Algoritmos

Problema 2: Otimizando 3a Soluo.


Comparar aos pares, separando em dois subconjuntos
Os elementos de vetor so comparados dois a dois e os elementos maiores so comparados com Max e os elementos menores so comparados com Min. Quando n mpar, o elemento que est na posio V[n] duplicado na posio V[n+1] para evitar um tratamento de exceo. Para esta implementao, f(n) = (n+1)/2 + (n-1)/2 + (n-1)/2 = (3n-1)/2, para n > 0, para o melhor caso, pior caso e caso mdio.

13

Complexidade de Algoritmos

Comparando as 3 Solues.

Resumindo os valores na tabela abaixo, observe: Os algoritmos MaxMin2 e MaxMin3 so superiores ao algoritmo MaxMin1 de forma geral. O algoritmo MaxMin3 superior ao algoritmo MaxMin2 com relao ao pior caso e bastante prximo quanto ao caso mdio.

13

Complexidade de Algoritmos
Importncia do Tamanho da Entrada

Valores pequenos de n: qualquer algoritmo custa pouco; Logo, a anlise de algoritmos realizada para valores grandes de n. Ex: Problema de complexidade 2

Computador que faa 109 (1 bilho!) de operaes por segundo


Tamanho 10 20 30 40 50 60 Tempo 0,001s 1,07s 1099s = 18:20min 312h = 13 dias 36,5 anos 374 sculos (!!!)
14

Complexidade de Algoritmos
Importncia do Tamanho da Entrada

Dependendo da quantidade n (valor), alguns termos da funo so insignificantes F(n) = n2 + 100n + log10 n + 1000 n < 10, 1000 o maior termo. n = 10, 100n e 1000 so os maiores n= 100, n2 e 100n so os maiores n >> 100, os outros termos contribuem pouco, sendo n2 basicamente o fator de relevncia e os outros termos podem ser desprezados. (explicar)

14

Complexidade de Algoritmos
Custo Assinttico

O custo assinttico de uma funo f(n) representa o limite do comportamento de custo quando n cresce. Em geral, o custo aumenta com o tamanho n do problema. Observao: Para valores pequenos de n, mesmo um algoritmo ineficiente no custa muito para ser executado.

15

Complexidade de Algoritmos
Dominao Assinttica

Comportamento assinttico: Comportamento das funes de custo para valores grandes de n. Dadas as funes: GV n 3
n
2 n

2 4 8 1024

1 8 27 1000

PV

2 3 10

15

Complexidade de Algoritmos
Dominao Assinttica

Dizemos que g(n) domina assintoticamente a f(n) porque: Existem c e m, tais que para n >= m temos c*|g(n)| >= |f(n)| ==> m = 10 e c = 1

15

Complexidade de Algoritmos
Dominao Assinttica
Ex 2) g(n) = (n+1)2 f(n) = n2 Para n >= 1 Para Ambas se dominam assintoticamente, j que: e...

|(n+1)2| <= 4* |n2|

0 <= n < 1 |n2| <= |(n+1)2|

16

Complexidade de Algoritmos

Para expressar que g(n) domina assintoticamente f(n) escrevemos f(n) = O(g(n))

Notao O (Knuth, 1968)

Exemplo:

f(n) = (n+1)

2.

Para m=1 e c=4, f(n) = O(n2)

18

Complexidade de Algoritmos
Notao O (n)

A notao O define um limite superior para a funo, por um fator constante. Escreve-se f(n) = O(g(n)), se existirem constantes positivas c e m tais que para n m, o valor de f(n) menor ou igual a c*g(n). Neste caso, pode-se dizer que g(n) um limite assinttico superior para f(n). Escrevemos f(n) = O(g(n)) para expressar que g(n) domina assintoticamente f(n). L-se f(n) da ordem no mximo g(n).

19

Complexidade de Algoritmos
Exemplo:

Mostre que g(n) = 3n3 +2n2 +n O(n3). Basta mostrar que 3n3 +2n2 +n 6n3, para n 0 e c=6. A funo g(n) = 3n3 + 2n2 + n tambm O(n4), entretanto esta afirmao mais fraca do que dizer que g(n) O(n3). Mostre que f(n) = n2 no O(n). Basta mostrar que para n m, n2 c n, c deve ser n. E no existe uma constante c que possa ser maior ou igual a n para todo n.

19

Complexidade de Algoritmos

Complexidade Constante

f(n) = O(1)

O uso do algoritmo independe do tamanho de n As instrues do algoritmo so executadas um nmero fixo de vezes.

20

Complexidade de Algoritmos

Complexidade Logartmica

f (n) = O(log n)

Ocorre tipicamente em algoritmos que resolvem um problema transformando-o em problemas menores. Nestes casos, o tempo de execuo pode ser considerado como sendo menor do que uma constante grande. Supondo que a base do logaritmo seja 2: Para n = 1.000, log = 10 2

Para n = 1.000.000, log2

Exemplo: Algoritmo de pesquisa binria. Ex: Adivinhar um nr entre 1 e 120

21

Complexidade de Algoritmos

Complexidade Linear

f (n) = O(n)

Um pequeno trabalho realizado sobre cada elemento de entrada Cada vez que n dobra de tamanho, o tempo de execuo tambm dobra. Exemplo: Algoritmo de pesquisa seqencial

22

Complexidade de Algoritmos

Complexidade Linear - Logartmica

f (n) = O(n log n)

Tpico de algoritmos que resolvem um problema quebrando-o em problemas menores, resolvendo cada um deles independentemente e depois agrupando as solues. Supondo que a base do logaritmo seja 2: Para n = 1.000.000, n*log 2 = 20.000.000

Para n = 2.000.000, n* log2 = 42.000.000 Ex: Algoritmo de Ordenao MergeSort.

23

Complexidade de Algoritmos

Complexidade Quadrtica

f (n) = O(n2)

Os itens de dados so processados aos pares, tipicamente em um anel dentro do outro. Algoritmos deste tipo so teis para resolver problemas de tamanhos relativamente pequenos Exemplos: Algoritmos de ordenao simples como Seleo, insero ou bolha. OBS: Sempre que n dobra, o tempo de execuo multiplicado por ???

24

Complexidade de Algoritmos

Complexidade Cbica

f (n) = O(n3)

teis apenas para resolver problemas relativamente pequenos Sempre que n dobra o tempo de execuo multiplicado por 8 Exemplo:Algoritmo para multiplicao de matrizes.

25

Complexidade de Algoritmos

Complexidade Exponencial

f (n) = O(2n)

No so teis sob o ponto de vista prtico Ocorrem na soluo de problemas por fora bruta Sempre que n dobra, o tempo de execuo fica elevado ao quadrado.

Exemplo: Algoritmo do Caixeiro Viajante

26

Complexidade de Algoritmos

Complexidade tambm Exponencial

f (n) = O(n!)

O(n!) dita complexidade exponencial, apesar de O(n!) ter comportamento muito pior do que O(2n). n = 20, temos que 20! = 2432902008176640000, um nmero com 19 dgitos. n = 40, temos aproximadamente 816000000000000000000000000000000000000000000000 um nmero com 48 dgitos!

27

Complexidade de Algoritmos

Algoritmos polinomiais

Um algoritmo cuja funo de complexidade O(p(n)), onde p(n) um polinmio de grau n, chamado de algoritmo polinomial no tempo de execuo.
Algoritmos tratveis ou razoveis

Algoritmos exponenciais

Um algoritmo cuja funo de complexidade O(n!) ouO(cn) chamado de algoritmo exponencial ==> esses crescem extremamente medida em que n cresce.
Algoritmos intratveis ou irrazoveis

29

Complexidade de Algoritmos

Algoritmos polinomiais

Mais teis na prtica. Tempo de execuo menor em relao a algoritmos exponenciais, para entradas n grandes.

Tratabilidade:

Problema tratvel: Existe algoritmo polinomial. Problema intratvel: No existe algoritmo polinomial para resolv-lo.

31

Complexidade de Algoritmos
Comparao entre Algoritmos Polinomiais e Exponenciais
Complexidade do Algoritmo 10 20 Tamanho n 30 40 50 60 Polinomial 0,00001 s. 0,00002 s. 0,00003 s. 0,00004 s. 0,00005 s. 0,00006 s. 0,0001 s. 0,001 s. 0,1 s. 0,001 s. 0,059 s. 3,63 s. 0,0004 s. 0,008 s. 3,2 s. 1,0 s. 58 m. 771 sc 0,0009 s. 0,027 s. 0,0016 s. 0,064 s. 0,0025 s. 0,125 s. 5,2 m. 0,0036 s. 0,216 s. 13,0 m.

n n2 n3 n5 2n 3n n!

24,3 s. 1,7 m. Exponencial 17,9 m. 12,7 dias

35,7 anos 366 sc 6,5 anos 3855 sc. 2. 108 sc. 1. 1013 sc. 8. 1016 sc.3. 1032 sc.1. 1049 sc.3. 1066 sc.

Tempos de execuo em funo de n. Assume-se que cada unidade da funo de complexidade tarda 10-6 seg para executar-se.
28

Complexidade de Algoritmos
Operaes com a notao O() 1) f(n) = O(f(n)) 2) c x O(f(n)) = O(f(n)) se c = constante. 3) O(f(n))+O(g(n)) = O(max(f(n), g(n))) 4) O(f(n))+O(f(n)) = O(f(n)) 5) O(O(f(n)) = O(f(n)) 6) f(n)xO(g(n)) = O(f(n)xg(n)) 7) O(f(n))xO(g(n)) = O(f(n)xg(n))
28

Complexidade de Algoritmos
Operaes com a notao O()

Regra da soma O(f(n))+O(g(n)) = O(max(f(n), g(n))) .

Suponha trs trechos cujos tempos de execuo so O(n), O(n2) e O(n log n). O tempo de execuo dos dois primeiros trechos O(max(n, n2)), que O(n2). O tempo de execuo de todos os trs trechos ento O(max(n2; n log n)), que O(n2).

28

Complexidade de Algoritmos
Determinando a Complexidade
Considere-se o seguinte cdigo: for (i = 0; i < n; i++) { Instrues; } A contabilizao do numero de instrues e simples: n iteraes e, em cada uma, so executadas um numero constante de instrues O(n)

28

Complexidade de Algoritmos
Determinando a Complexidade
Considere-se o seguinte codigo: for (i = 0; i < n; i++) for (j = 0; j < n; j++) { Instrues; } A contabilizao do numero de instrues e ainda simples: o ciclo interno (for j) O(n) e executado n vezes O(n2)

28

Complexidade de Algoritmos
Determinando a Complexidade em um algoritmo de busca
Eficincia da Pesquisa Sequencial int PesquisaSequencial (int x, int V[], int n) { int i = 0, k = -1; // k = posicao onde se encontra x em V while ( (i < n) && (k == -1) ) if (x == V[i]) k = i; else if (V[i] < x) // considera-se o vetor em ordem crescente i = i + 1; else k = -2; return (k); }
28

Complexidade de Algoritmos
Determinando a Complexidade em um algoritmo de busca

PESQUISA SEQUENCIAL Eficincia em termos de tempo de processamento: A operao realizada mais vezes o teste da condio de continuidade do ciclo for, que no maximo n+1 vezes (no caso de nao encontrar x o pior caso) Se x existir no array, o teste realizado aproximadamente n/2 vezes (no caso medio) e 1 vez (no melhor caso) Logo, T(n) = O(n) (linear) no pior caso e no caso medio

28

Complexidade de Algoritmos
Determinando a Complexidade em um algoritmo de busca

PESQUISA BINRIA (Explicar) Eficincia em termos de tempo de processamento: As operaes realizadas mais vezes (dentro do for) so os testes de busca frustrada, valor encontrado e de rea de seguimento de busca. So 3 testes realizados no mximo log2n vezes (no caso de no encontrar x ou encontr-lo na ltima tentativa vlida) - No melhor caso, x existindo no vetor, ser encontrado em um nr qualquer menor que log2n. Logo, T( n) = O(log2n) (logaritmica) no pior caso e no caso mdio.

28

Complexidade de Algoritmos
Comparando Programas

Podemos avaliar programas comparando as funes de complexidade, negligenciando as constantes de proporcionalidade. Um programa com tempo de execuo O(n) melhor que outro com tempo O(n2). Porm, as constantes de proporcionalidade podem alterar esta considerao. 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. Para problemas com entrada de dados pequena prefervel usar o programa cujo tempo de execuo O(n2). Entretanto, quando n cresce, o programa com tempo de execuo O(n 2) leva muito mais tempo que o programa O(n). RATIFICAMOS: Estudo de Complexidade para atender a grandes volumes de dados.
28