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

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

Complexidade de Algoritmos

Apresentações semelhantes


Apresentação em tema: "Complexidade de Algoritmos"— Transcrição da apresentação:

1 Complexidade de Algoritmos

2 Introdução Analisar um algoritmo significa prever os recursos que o algoritmo necessitará. Podem ser recursos de memória, largura de banda, hardware ou tempo. Podemos analisar • O tempo de processamento em função de seus dados de entrada; • A memória total utilizada pelo programa; • O número de linhas do código do programa; • Se o programa chega corretamente ao resultado; • Se o programa é fácil de entender e de ser alterado; • Se os erros causados por dados incorretos ou inesperados são tratados corretamente.

3 Usar o método empírico possui os seguintes problemas:
Entretanto uma análise detalhada da performance de um algoritmo, que leve em consideração todos esses fatores, é muito complicada e não muito significativa. De todos estes fatores tempo é o recurso mais freqüentemente medido. Em geral pela análise podemos indicar se um algoritmo é mais eficiente que o outro. Esta análise pode ser feita a partir de dois processos: pelo método empírico e pelo método analítico. Usar o método empírico possui os seguintes problemas: Os resultados são dependentes do compilador Os resultados são dependentes do hardware Quando grandes quantidades de memória são usadas os resultados podem depender deste aspecto Apesar dos problemas acima o método empírico é útil quando temos vários algoritmos distintos, que resolvem o mesmo problema, de mesma ordem de grandeza.

4 No método analítico procura-se determinar uma expressão que nos forneça o tempo de execução em função da quantidade de dados processados, isto é: Tempo = f(N) A complexidade de um algoritmo é o termo normalmente utilizado para se fazer referência à sua eficiência Para se encontrar a expressão que nos dá o tempo de execução de um algoritmo teremos que determinar a quantidade de operações que serão executadas para um conjunto de dados de tamanho N. Como exemplo, vamos determinar o tempo de execução para o cálculo do somatório de uma série aritmética simples:

5 1 I    := 1; 2 Soma := 0; 3 while I <= N do begin 4    Soma := Soma + I; 5    I    := I + 1; 6 end; Na análise do programa acima vamos considerar que os tempos necessários para realizar as operações de atribuição, comparação e adição são dados por T:=, T<= e T+, respectivamente.

6 Na análise anterior os tempos das operações depende dos fatores listados anteriormente. Dessa forma, fica bastante difícil comparar a eficiência de dois algoritmos usando esse mecanismo uma vez que teremos que especificar também o ambiente em que a medição foi feita. Para simplificar iremos usar um computador idealizado que executaria qualquer instrução em um mesmo tempo T. Em nosso modelo também não tentaremos modelar a hierarquia de memória. Esta análise convencional permite previsões excelentes do desempenho em máquinas reais. O efeito de tal simplificação resulta em que não precisamos mais considerar as operações separadamente. Dessa forma, para determinar o tempo de processamento de um programa basta simplesmente contar o número total de operações

7 Análise dos Tempos de Processamento
Consideremos o problema de se determinar o maior valor de um vetor fazendo uma busca seqüencial no vetor: public class Max{ public static int max(int v[ ], int n){ int max = v[0]; for (int i = 1; i<n; i++) if (max < v[i]) max = v[i]; return max; }

8 Tempos de processamento do melhor caso, do pior caso e do caso médio
Consideremos o problema de se determinar o maior valor de um vetor fazendo uma busca seqüencial no vetor: 1 max = A[0]; 2 i = 0; 3 while (i < N) { 4    if (A[i] > max) 5     max = A[i]; 6 i = i + 1;    }  

9 Agora surge um problema: quantas vezes a linha 5 será executada
Agora surge um problema: quantas vezes a linha 5 será executada? Neste caso não sabemos pois depende dos valores existentes no vetor. O que fazer então? Três estratégias são adotadas: • Determinar o tempo do pior caso • Determinar o tempo do melhor caso • Determinar o tempo do caso médio

10 O pior caso: Ordem crescente
O pior caso: Ordem crescente. Linha 5 é executada em todas as iterações do laço. Dessa forma, o tempo de processamento para o pior caso é dado por: T(N) = 5N + 3 O melhor caso: Ordem decrescente. Linha 5 nunca é executada. O tempo de processamento será então: T(N) = 4N + 3 O cálculo do tempo médio de processamento exige o prévio conhecimento da distribuição de probabilidades das diferentes entradas. Na maioria dos casos essa distribuição é desconhecida e freqüentemente é de tratamento matemático complexo. Como a análise do pior caso nos dá um limite superior do tempo de processamento, ela é a mais utilizada.

11 Exercício Considere o seguinte algoritmo ... 1 - soma = 0;
2 - for(x = 0; x < N; x++) 3 - { 4 - if (vetor[x] % 2 == 0) soma = soma + vetor[x]; 6 - } 7 - media = soma / N;

12 Exercício 2 Calcule, usando a simplificação vista, a complexidade do seguinte algoritmo 1 - for(x = 0; x < N-1; X++) 2 - for( y = 0; y < N; y++) if(vetor[x] > vetor[y]) { aux = vetor[x]; vetor[x] = vetor[y]; vetor[y] = aux; 8 - }

13 Notação O Quando estamos analisando a ordem de crescimento de um algoritmo normalmente estamos interessados em se ter uma idéia de como o método se comporta quando alteramos o valor de N. Para isso precisamos apenas analisar o termo de maior valor da expressão, ou seja o termo que cresce mais rápido. Exemplo: T(N) = N2+2N O termo representativo da expressão nos dá a sua ordem, sendo representado pela notação O, a qual é escrita colocando-se a letra O e, entre parênteses, o termo representativo da expressão.

14 Assim, o algoritmo acima seria expresso na notação O como sendo O(N2), que se lê da seguinte forma: o algoritmo tem complexidade O(N2) ou sua complexidade é de ordem N2. A notação O pode ser derivada a partir de T(N) da seguinte maneira: • Fazer o coeficiente de cada termo igual a um; • Tomar o maior termo da função como sendo a ordem do algoritmo, descartando os termos restantes.

15 Normalmente dividem-se as complexidades dos algoritmos em sete categorias como mostradas na tabela abaixo:

16 Gráficos de cada complexidade em função de N
Exemplo: Obtenha a notação O para:

17 Regras Para a Notação O A seguir apresentamos algumas regras simples para a determinação da complexidade do tempo de processamento de algumas composições básicas de comandos em um programa. Regra 1: Tempo constante A ordem de um algoritmo cujo tempo independe de N é constante e igual a O(1). Regra 2: Composição seqüencial O tempo de processamento para o pior caso de uma seqüência de comandos, tais como: S1; S2; ... S3; é igual à ordem do maior tempo entre todos os comandos.

18 Regras Para a Notação O Regra 3: Iteração
O tempo de processamento para o pior caso de um laço do tipo: for I := 1 to N    S; é igual ao tempo de execução de S multiplicado pelo número de vezes que ele será executado no pior caso, isto é, a ordem é O(N x Ts(N)), onde Ts(N) é o tempo máximo de execução de S. Regra 4: Execução condicional O tempo de processamento para o pior caso de um comando if-then-else if S1 then   S2 else   S3; é igual ao maior tempo de execução entre os comandos S2 e S3.

19 Exemplo Seja o problema para calcular a série de somas S1, S2, ..., Sn, obtidas por: cujo algoritmo é: 1  J := 1; 2  while J <= N do begin 3     S[J] := 0; 4     I    := 1; 5     while I <= J do begin 6        S[J] := S[J] + A[I]; 7        I := I + 1; 8     end; 9     J := J + 1; 10 end;

20 Vejamos o cálculo da ordem do algoritmo:

21 Exercícios 1) Cada uma das seguintes fórmulas representa o número de operações de determinado algoritmo. Exprimir cada uma delas usando a notação O: a) n2 + 5n b) 3n2 + 5n c) (n + 7)(n – 2) d) 100n + 5 e) 6Log2N + 9N f) 3N4 + NLog2N g) 5N2 + N3/2

22 3) Calcular a complexidade do seguinte trecho de programa:
2) Escrever um trecho de programa contendo um laço para calcular a soma de todos os números inteiros de 1 a n. Fazer uma análise do tempo requerido, contando o número de somas e atribuições efetuadas e a seguir concluir qual a ordem do algoritmo. 3) Calcular a complexidade do seguinte trecho de programa: I := 1; while I <= N do begin    J := 1;    while J <= N do begin       K := 1;       while K <= N do begin          Writeln(I, J, K);          K := K + 1;       end;       J := J + 1;    end;    I := I + 1; end;


Carregar ppt "Complexidade de Algoritmos"

Apresentações semelhantes


Anúncios Google