A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Análise de Complexidade

Apresentações semelhantes


Apresentação em tema: "Análise de Complexidade"— Transcrição da apresentação:

1 Análise de Complexidade
Algoritmos Avançados Análise de Complexidade

2 COMPLEXIDADE DE ALGORITMOS
Definição: A Complexidade de um Algoritmo consiste na quantidade de “trabalho” necessária para a sua execução, expressa em função das operações fundamentais, as quais variam de acordo com o algoritmo, e em função do volume de dados

3 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, já existem algoritmos prontos ou que podem ser adaptados O problema é: qual algoritmo escolher?

4 COMO COMPARAR DUAS SOLUÇÕES PARA UM MESMO PROBLEMA ?
Tomemos duas soluções para localizar um elemento em um vetor: LIN e BIN Temos dois computadores diferentes, A e B, sendo A um Core 2 Duo e B um Celeron. Tamanho (n) Tempo de execução de LIN em A Tempo de execução de BIN em B 16 8 ns ns 64 32 ns ns 256 128 ns ns 1024 512 ns ns Qual é a melhor solução? LIN ou BIN ?

5 COMO COMPARAR DUAS SOLUÇÕES PARA UM MESMO PROBLEMA ?
Tamanho (n) Tempo de execução de LIN em A Tempo de execução de BIN em B 16 8 ns ns 64 32 ns ns 256 128 ns ns 1024 512 ns ns ... ns ns ns ns ns ns 63,072 x 1012 31,536 x 1012 ns ou 1 ano ns ou cerca de 1,4 segundos

6 COMPLEXIDADE DE ALGORITMOS
Pode-se falar de dois tipos de complexidade de algoritmos : Complexidade Espacial: Quantidade de recursos utilizados para resolver o problema; Complexidade Temporal: Quantidade de tempo utilizado. 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!

7 COMPLEXIDADE DE ALGORITMOS
Existem três perspectivas para análise de complexidade: Melhor Caso Caso Médio Pior Caso Nas três perspectivas, a função f(n) retorna a complexidade de um algoritmo com entrada de tamanho n

8 ANÁLISE DO MELHOR CASO Definido pela letra grega Ω(Ômega)
Exprime o menor tempo de execução de um algoritmo para uma entrada de tamanho n É pouco usado, por ter aplicação em poucos casos. Ex.: O algoritmo de pesquisa sequêncial em um vetor tem complexidade f(n) = Ω(1) A análise assume que o número procurado seria o primeiro selecionado na lista. Abordagem otimista!

9 ANÁLISE DO CASO MÉDIO Definido pela letra grega θ (Theta)
Deve-se obter a média dos tempos de execução de todas as entradas de tamanho n, ou baseado em probabilidade de determinada condição ocorrer Ex.: O algoritmo de pesquisa sequêncial em um vetor tem complexidade f(n) = θ(n/2) Em média será necessário visitar n/2 elementos do vetor até encontrar o elemento procurado Melhor aproximação Muito difícil de determinar na maioria dos casos

10 ANÁLISE DO PIOR CASO Representado pela letra grega O
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 É o método mais fácil de se obter. Ex.: O algoritmo de pesquisa sequêncial em um vetor tem complexidade f(n) = O(n) No pior caso será necessário visitar todos os n elementos do vetor até encontrar o elemento procurado Abordagem pessimista!

11 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. 10n3 + 4n -10 à medida que n aumenta, o termo cúbico começa a dominar A constante do termo cúbico tem relativamente a mesma importância que a velocidade da CPU

12 A NOTAÇÃO O Desprezar constantes aditivas ou multiplicativas
Número de passos 3n será aproximado para n Interesse assintótico termos de menor grau podem ser desprezados n2 + n será aproximado para n2 6n3 + 4n - 9 será aproximado para n3

13 CÁLCULO DA COMPLEXIDADE
Foi visto que, para calcular a complexidade de um algoritmo, deve-se analisar o pior caso A análise deve ser feita de acordo com a tabela a seguir Número de Operações Complexidade f(n) O(f(n)) c x f(n) f(n) + f(n) f(n) + g(n) O(max(f(n),g(n)) f(n) x g(n) O(f(n) x g(n))

14 CÁLCULO DA COMPLEXIDADE: ALGORITMO ITERATIVO
void FloidWarshall(int dist[][]) { int i; int j; int k; for ( k = 0; k < n; k++ ) { for ( i = 0; i < n; i++ ) { for ( j = 0; j < n; j++ ) { int a = dist[i][j]; int b = dist[j][k]; int c = dist[k][j]; dist[i][j] = min(a, b + c ); } int min(int a, int b) { if(a < b) return a; return b; 1 + 1 + 1 + n * ( n * ( n * ( n * ( n * ( ) ) ) 3 + n * n * n * 6 3 + 6n3 O(n3) n * ( 1 + 1 + 1 + 3 ) ) ) 1 + 1 + 1

15 CÁLCULO DA COMPLEXIDADE: ALGORITMO RECURSIVO
A questão se complica um pouco quando se trata de algoritmos recursivos Embora não haja um método único para esta avaliação, a complexidade de um algoritmo recursivo é definida em função de componentes como: Complexidade da base Complexidade do núcleo Profundidade da recursão Número de vezes que o procedimento recursivo é invocado Depende do tamanho do problema e da taxa de redução do tamanho do problema É justamente em sua determinação que reside o problema!

16 CÁLCULO DA COMPLEXIDADE: ALGORITMO RECURSIVO
int fatorial( int n ) { if( n == 0 ) { return 1; //Base } else { return n * fatorial( n – 1 ); // Núcleo } A redução se dá de uma em uma unidade, de n até chegar a 0 Logo, a profundidade da recursão é n Tanto o núcleo quando a base executam apenas uma operação A base é executada uma única vez e o núcleo n - 1 vezes Logo, o número de operações executadas é ((n – 1) * 1) + 1, resultando em uma complexidade O(n)

17 ORDENS DE ALGORITMOS Complexidade Constante Complexidade Linear
Complexidade Logarítmica Complexidade Log Linear Complexidade Quadrática Complexidade Cúbica Complexidade Exponencial Complexidade Fatorial

18 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 } else {

19 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 = i + 1 ) { if (condição == true) then { realiza alguma operação em tempo constante } else {

20 COMPLEXIDADE LOGARÍTMICA - O(LOGN)
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

21 COMPLEXIDADE LOG LINEAR – O(NLOGN)
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(meio + 1, fim); mesclar(inicio, meio, fim); }

22 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-1; j++) { if (a[j] > a[j+1]) { swap(a, j, j+1); }

23 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; for ( k = 0; k < N; k++ ) for ( i = 0; i < N; i++ ) for ( j = 0; j < N; j++ ) dist[i][j] = min( dist[i][j], dist[i][k] + dist[k][j] );

24 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.: Utilizando apenas números é possível criar 10n senhas de n dígitos Um algoritmo de força bruta para quebrar uma dessas senhas tem complexidade O(2n)

25 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.: Problema do Caixeiro Viajante Encontrar a rota mínima para visitar várias cidades sem repetir nenhuma É um problema base para o projeto de microchips, sequênciamento de genôma e muitas outras aplicações Não possui solução exata eficiente (Problema NP) Utilização de heurísticas para aproximar a solução ótima

26 ORDENS DE COMPLEXIDADE
Imagine um computador que leva 1ms 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) Log(n) nLog(n) O(n2) O(n3) O(2n) O(n!) 16 0.016s 0.004s 0.064s 0.256s 4s 1m5s 663 anos 32 0.032s 0.005s 0.16s 1s 33s 49 dias 1023 sec 512 0.512s 0.009s 4.608s 4m22s 37h 10143 sec ...

27 LIMITES SUPERIOR E INFERIOR
Todas as ordens de complexidade vistas definem o Limite Superior (Upper Bound) dos Algoritmos Qualquer que seja o tamanho da entrada, o tempo de execução crescerá com velocidade igual ou inferior a apontada pela análise de complexidade. Algumas otimizações podem ser feitas para melhorar o limite superior; Existem, porém, os Limites Inferiores (Lower Bound) para certos problemas, que são pontos a partir dos quais não é mais possível otimizar uma solução algorítmica

28 LIMITES SUPERIOR E INFERIOR
Dado um problema de Multiplicação de 2 matrizes N X N. A solução trivial tem complexidade O(n3); Sabemos assim que a complexidade deste problema não deve superar O(n3), uma vez que existe um algoritmo com está ordem complexidade que o resolve; Este limite superior de um algoritmo pode mudar se alguém descobrir um algoritmo melhor.

29 LIMITES SUPERIOR E INFERIOR
Strassen resolveu o problema com uma complexidade de O(nlog 7) Outros pesquisadores melhoraram ainda mais este resultado. Atualmente o melhor resultado é o de Coppersmith e Winograd de O(n2.376). O limite superior de um algoritmo é parecido com o recorde mundial de uma modalidade de atletismo. Ele é estabelecida pelo melhor atleta (algoritmo) do momento. Assim como o recorde mundial, o limite superior pode ser melhorado por um algoritmo (atleta) mais veloz.

30 LIMITES SUPERIOR E INFERIOR
Às vezes é necessário mostrar que, para um dado problema, qualquer que seja o algoritmo a ser usado, requer um certo número mínimo de operações: o Limite Inferior Para o problema de multiplicação de matrizes de ordem n, apenas para ler os elementos das duas matrizes de entrada leva O(n2). Assim uma cota inferior trivial é Ω(n2).

31 LIMITES SUPERIOR E INFERIOR
Na analogia anterior, o limite inferior não dependeria mais do atleta. Seria algum tempo mínimo que a modalidade exige, qualquer que seja o atleta. Um limite inferior trivial para os 100 metros seria o tempo que a velocidade da luz leva para percorrer 100 metros no vácuo. Se um algoritmo tem uma complexidade que é igual ao limite inferior do problema então o algoritmo é ótimo. O algoritmo de CopperSmith e Winograd é de  O(n2.376) mas o limite inferior é de Ω(n²). Portanto não é ótimo. Este limite superior ainda pode ser melhorado


Carregar ppt "Análise de Complexidade"

Apresentações semelhantes


Anúncios Google