Complexidade de Algoritmos

Slides:



Advertisements
Apresentações semelhantes
Métricas e Medição de Software
Advertisements

Estruturas de Dados e Algoritmos II
gerador de código intermediário
Analise de Algoritmos e Notação Assintótica
Amintas engenharia.
Amintas engenharia.
Arquitetura de Computadores
Ciclos, Vectores e Gráficos Simulação da Queda de Corpos II
Algoritmos e Estrutura de Dados I
1 MergeSort Seja uma lista A de n elementos. O algoritmo consiste das seguintes fases Dividir A em 2 sub-listas de tamanho n/2 Conquistar: ordenar cada.
Pesquisa em Memória Primária
Medida do Tempo de Execução de um Programa
Medida do Tempo de Execução de um Programa
Medida do Tempo de Execução de um Programa
Medida do Tempo de Execução de um Programa
Pesquisa em Memória Primária
Lógica de Programação Módulo II
Padrões GoF – Factory Method
UFPE - Centro de Ciências Exatas e da Natureza. Departamento de Informática Algoritmos e Estruturas de Dados - Turma if096B. SOMAS ADERVAL MENDONÇA MARIANO.
Complexidade de Algoritmos
Professor: Erivelto Tschoeke – UDESC/CEPLAN
Introdução a Análise de Complexidade de Algoritmos
Crescimento de Funções
Linguagens de Programação
Prof. Msc. Raul Paradeda Aula 2 Introdução
Threads sem Sincronização
Buscas em Grafos Prof. André Renato 1º Semestre/2012
HARDWARE do CLP Os controladores lógicos programáveis são equipamentos com uma aplicação muito vasta dentro dos diversos processos de automação. Desta.
Comparação entre os métodos de ordenação
Sistemas Operacionais
Exercícios Referentes à Prova P1
Algoritmos paralelos eficientes para alguns problemas de processamento de Cadeia de Caracteres Alunos: Diego Alencar dos Santos Melo Felipe Formagini Brant.
Tópicos em redes e sistemas distribuídos Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação.
Aula 03 – BCC202 Análise de Algoritmos (Parte 1) Túlio Toffolo www
Introdução a Programação
Aula T06 – BCC202 Análise de Algoritmos (Parte 4) Túlio Toffolo
Introdução a Linguagens de Programação
Algoritmos 1º Semestre Materia: Informática Profº: Cristiano.
SOMA  0 fim início Simulação do algoritmo que soma os valores dos primeiros números naturais até o número fornecido como entrada: leia N T
Trabalho Final de Fundamentos da Engenharia de Software Métrica de Pontos de Função André Costa de Jesus & Helena Prudente Bartholo.
Resolução de sistemas de equações lineares
Campus de Caraguatatuba Licenciatura em Matemática Semestre de 2013
Geração de Código aula-12-geração-de-código.pdf.
Algoritmos e Estruturas de Dados RECURSIVIDADE. O que é recursividade? Recursividade significa algo ser definido em termos de sí próprio. Em termos de.
Introdução a Sistemas de Informação
Algumas notas sobre a linguagem de programação C
Fontes de Erros Aula 1 Introdução; Erros em processos numéricos;
Estimativas de Custos e Orçamentação
Sistemas Operacionais
Microprocesadores x Microcontroladores
Como analisar um algoritmo
Engenharia de Software
Complexidade de Computação Katia Guimarães. Avaliando a Qualidade de um Algoritmo É preciso ter bem definido –O que é dado de entrada e –O que é esperado.
Analise de Algoritmos e Notação Assintótica
Introdução à Programação
INTRODUÇÃO AOS MÉTODOS NUMÉRICOS Professor: Dr. Edwin B. Mitacc Meza
Programação Computacional Aula 9: Meu primeiro programa em C
O que devem fazer os Microprocessadores ?
Transmissão de Dados O Modelo de Referência TCP/IP A Camada de Rede
Berilhes Borges Garcia Algoritmos Uma ferramenta para resolver um problema de computação bem- especificado (O espírito da computação) Exemplo: ordenação.
Interpolação Polinomial: Introdução; Lagrange.
Computadores vs. Programas / Algoritmos Computadores vs. Programas -> Algoritmos O tratamento de problemas através do computador geralmente envolve uma.
TÉCNICAS DE ESTIMATIVAS
LÓGICA DE PROGRAMAÇÃO Curso: Técnico em Informática Professor: Ronaldo Disciplina: Lógica de Programação.
Gerência de Memória. Memória Considerações: Recurso caro e escasso; Programas só executam se estiverem na memória principal; Quanto mais processos residentes.
Análise e Complexidade de Algoritmos
Introdução a Programação Aula 02 Jackson Eduardo
COMPILADORES 02 Prof. Marcos. COMPILADORES Do Programa à Execução Computadores das mais variadas arquiteturas têm funcionamento:
Comportamento Assintótico
Transcrição da apresentação:

Complexidade de Algoritmos

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.

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.

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:

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.

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

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; }

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;    }  

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

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.

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

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++) 3 - if(vetor[x] > vetor[y]) 4 - { 5 - aux = vetor[x]; 6 - vetor[x] = vetor[y]; 7 - vetor[y] = aux; 8 - }

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.

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.

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

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

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.

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.

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;

Vejamos o cálculo da ordem do algoritmo:

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

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;