Análise de complexidade



Documentos relacionados
Análise de complexidade

Sistemas Distribuídos: Princípios e Algoritmos Introdução à Análise de Complexidade de Algoritmos

ANÁLISE DE COMPLEXIDADE DOS ALGORITMOS

Análise de Algoritmos: Melhor caso, pior caso, caso médio

Universidade Federal de Mato Grosso do Sul Faculdade de Computação Disciplina de Verão: Algoritmos e Programação II

Métodos de Pesquisa em Memória Primária

BCC202 - Estrutura de Dados I

Complexidade de Algoritmos. Edson Prestes

Projeto e Análise de Algoritmos. Profa. Juliana Kaizer Vizzotto. Projeto e Análise de Algoritmos - Aula 1

Aula 03 Custos de um algoritmo e funções de complexidade

Algoritmos 3/17/ Algoritmos como área de estudo e investigação

Pesquisa Sequencial e Binária. Introdução à Programação SI2

Algoritmos de Busca em Tabelas

Pesquisa Sequencial e Binária

Pesquisa em Memória Primária. Prof. Jonas Potros

Índice. Capítulo 2 Estrutura de Dados sequencial com armazenamento sequencial

5. Análise de Complexidade de Algoritmos. João Pascoal Faria (versão original) Ana Paula Rocha (versão 2003/2004) Luís Paulo Reis (versão 2005/2006)

Possui como idéia central a divisão de um universo de dados a ser organizado em subconjuntos mais gerenciáveis.

MC102 Algoritmos e Programação de Computadores

Jorge Figueiredo, DSC/UFCG. Análise e Técnicas de Algoritmos Jorge Figueiredo, DSC/UFCG. Análise e Técnicas de Algoritmos 2005.

EFICIÊNCIA DE ALGORITMOS E

Análise de Complexidade de Algoritmos

ESTRUTURAS DE INFORMAÇÃO E ANÁLISE DE ALGORITMOS

Pesquisa Sequencial e Binária

Estrutura de Dados Básica

Métodos de Pesquisa 472

Faculdade de Engenharia Optimização. Prof. Doutor Engº Jorge Nhambiu

Pragmática das Linguagens de Programação 2004/2005

Tabela de símbolos: tabelas de espalhamento

Complexidade de algoritmos Notação Big-O

BUSCA EM LISTAS LISTAS SEQÜENCIAIS, LISTAS SIMPLESMENTE E DUPLAMENTE ENCADEADAS E LISTAS CIRCULARES

Cap.2.5: Design de Algoritmos e Programação Estruturada. Algoritmos, fluxogramas e pseudo-código

Computação Paralela. Desenvolvimento de Aplicações Paralelas João Luís Ferreira Sobral Departamento do Informática Universidade do Minho.

Programação. MEAer. Bertinho Andrade da Costa. Instituto Superior Técnico. Introdução ao Pré-Processador. 2011/2012 1º Semestre

Busca. Pesquisa sequencial

Árvores Binárias e Busca. Jeane Melo

Universidade Federal de Alfenas

Recursividade. Túlio Toffolo BCC202 Aula 08 Algoritmos e Estruturas de Dados I

Árvores Binárias de Busca

Prof. Dr. Abel Gomes Cap.4: Design de Algoritmos e Programação Estruturada. Algoritmos, fluxogramas e pseudo-código

Faculdade de Engenharia Optimização. Prof. Doutor Engº Jorge Nhambiu

Tabela de Símbolos. Análise Semântica A Tabela de Símbolos. Principais Operações. Estrutura da Tabela de Símbolos. Declarações 11/6/2008

Hashing. Estruturas de Dados. Motivação

Arquiteturas RISC. (Reduced Instructions Set Computers)

Desempenho de Computadores

Árvores Binárias de Busca

Pesquisa em Memória Primária. Algoritmos e Estruturas de Dados II

Pointer Jumping. odg(v) e idg(v): graus de saída e entrada do vértice v V. um vértice r tal que. O vértice r é dita raíz de T

Programação Recursiva versão 1.02

Dadas a base e a altura de um triangulo, determinar sua área.

Geração de código intermediário. Novembro 2006

Geração de código. Ivan Ricarte INTRODUÇÃO À COMPILAÇÃO

Algoritmos de pesquisa

OTIMIZAÇÃO VETORIAL. Formulação do Problema

Cálculo Numérico. ECA / 4 créditos / 60 h Introdução, Erros e Matlab. Ricardo Antonello.

Cálculo Aproximado do número PI utilizando Programação Paralela

Algoritmos de pesquisa. Tabelas de dispersão/hash

Conjunto de instruções do CPU. Arquitectura de um computador. Definição das instruções (1) Definição das instruções (2)

ALGORITMOS E ESTRUTURAS DE DADOS CES-11 CES-11 CES-11

Aula 4 Pseudocódigo Tipos de Dados, Expressões e Variáveis

Estruturas de entrada e saída

Programação. Folha Prática 3. Lab. 3. Departamento de Informática Universidade da Beira Interior Portugal Copyright 2010 All rights reserved.

Algoritmo. Prof. Anderson Almeida Ferreira. Agradeço ao prof. Guilherme Tavares de Assis por fornecer slides que fazem parte desta apresentação

CES-11. Noções de complexidade de algoritmos. Complexidade de algoritmos. Avaliação do tempo de execução. Razão de crescimento desse tempo.

Computação e Programação Aula prática nº 5. Enunciados dos problemas

INTRODUÇÃO ÀS LINGUAGENS DE PROGRAMAÇÃO

Algoritmo. Exemplo. Definição. Programação de Computadores Comparando Algoritmos. Alan de Freitas

CAP. I ERROS EM CÁLCULO NUMÉRICO

BC0501 Linguagens de Programação

Organização de Computadores

Variáveis e estruturas de controlo. Introdução à Programação André L. Santos

Computers do not solve problems, People do! E.R.Davidson

Análise e Complexidade de Algoritmos

Tabelas (arrays) (vetores, matrizes, etc) Algoritmos de pesquisa Algoritmos de ordenação

Module Introduction. Programação. Cap. 4 Algoritmos e Programação Estruturada

ARQUITETURA DE COMPUTADORES

Estruturas de Dados. Prof. Gustavo Willam Pereira Créditos: Profa. Juliana Pinheiro Campos

Algoritmos de Pesquisa e Ordenação em Vectores

Algoritmos Genéticos (GA s)

28/9/2010. Paralelismo no nível de instruções Processadores superescalares

O que é um programa? Programa é uma lista de instruções que descrevem uma tarefa a ser realizada pelo computador.

É interessante comparar algoritmos para valores grandes de n. Para valores pequenos de n, mesmo um algoritmo ineficiente não custa muito para ser

Universidade da Beira Interior Cursos: Matemática /Informática e Ensino da Informática

Capítulo 2: Introdução à Linguagem C

MC102 Algoritmos e Programação de Computadores 1ª Aula Introdução à Programação de Computadores

Medida do Tempo de Execução de um Programa. David Menotti Algoritmos e Estruturas de Dados II DInf UFPR

2. OPERADORES ALGORITMOS, FLUXOGRAMAS E PROGRAMAS FUNÇÕES... 10

DICIONÁRIOS. template<class K,class T> class Par { public: K chave; T valor; Par():chave(),valor()

Análise de Algoritmos

3 Sistemas de Numeração:

Programas simples em C

Área que visa determinar a complexidade (custo) de um algoritmo, com isso é possível:

Hashing. Rafael Nunes LABSCI-UFMG

Aluísio Eustáquio da Silva

Pipeline. Todos os estágios devem estar prontos ao mesmo tempo para prosseguir.

Aula 1. Teoria da Computação III

Programação Paralela e Distribuída (DCC/UFRJ)

Transcrição:

Introdução Algoritmo: sequência de instruções necessárias para a resolução de um problema bem formulado (passíveis de implementação em computador) Estratégia: especificar (definir propriedades) arquitectura (algoritmo e estruturas de dados) análise de complexidade (tempo de execução e memória) implementar (numa linguagem de programação) testar (submeter entradas e verificar observância das propriedades especificadas)

Análise de algoritmos Provar que um algoritmo está correcto Determinar recursos exigidos por um algoritmo (tempo, espaço, etc.) comparar os recursos exigidos por diferentes algoritmos que resolvem o mesmo problema (um algoritmo mais eficiente exige menos recursos para resolver o mesmo problema) prever o crescimento dos recursos exigidos por um algoritmo à medida que o tamanho dos dados de entrada cresce

Análise de algoritmos Que dados usar? dados reais: verdadeira medida do custo de execução dados aleatórios: assegura-nos que as experiências testam o algoritmo e não apenas os dados específicos Caso médio dados perversos: mostram que o algoritmo funciona com qualquer tipo de dados Pior caso! dados benéficos: Melhor caso

Complexidade espacial e temporal Complexidade espacial de um programa ou algoritmo: espaço de memória que necessita para executar até ao fim S(n) : espaço de memória exigido em função do tamanho n da entrada Complexidade temporal de um programa ou algoritmo: tempo que demora a executar (tempo de execução) T(n) : tempo de execução em função do tamanho n da entrada Complexidade vs. Eficiência Por vezes estima-se a complexidade para o melhor caso (pouco útil), o pior caso (mais útil) e o caso médio (igualmente útil)

Complexidade temporal Análise precisa é uma tarefa complicada algoritmo é implementado numa dada linguagem a linguagem é compilada e o programa é executado num dado computador difícil prever tempos de execução de cada instrução e antever optimizações muitos algoritmos são sensíveis aos dados de entrada muitos algoritmos não são bem compreendidos Para prever o tempo de execução de um programa apenas é necessário um pequeno conjunto de ferramentas matemáticas

Crescimento de funções O tempo de execução geralmente dependente de um único parâmetro n ordem de um polinómio tamanho de um ficheiro a ser processado, ordenado, etc. ou medida abstracta do tamanho do problema a considerar (usualmente relacionado com o número de dados a processar) Quando há mais do que um parâmetro procura-se exprimir todos os parâmetros em função de um só faz-se uma análise em separado para cada parâmetro

Ordens de complexidade mais comuns Os Algoritmos têm tempo de execução proporcional a 1 : muitas instruções são executadas uma só vez ou poucas vezes (se isto acontecer para todo o programa diz-se que o seu tempo de execução é constante) log n : tempo de execução é logarítmico (cresce ligeiramente à medida que n cresce; quando n duplica log n aumenta mas muito pouco; apenas duplica quando n aumenta para n 2 ) n : tempo de execução é linear (típico quando algum processamento é feito para cada dado de entrada; situação óptima quando é necessário processar n dados de entrada, ou produzir n dados na saída)

Ordens de complexidade mais comuns n log n : típico quando se reduz um problema em subproblemas, se resolve estes separadamente e se combinam as soluções (se n é igual a 1 milhão, n log n é perto de 20 milhões) n 2 : tempo de execução quadrático (típico quando é necessário processar todos os pares de dados de entrada; prático apenas em pequenos problemas, ex: produto de vectores) n 3 : tempo de execução cúbico (para n = 100, n 3 = 1 milhão, ex: produto de matrizes) 2 n : tempo de execução exponencial (provavelmente de pouca aplicação prática; típico em soluções de força bruta; para n = 20, 2 n = 1 milhão; se n duplica, o tempo passa a ser o quadrado)

Ordens de complexidade mais comuns

Notação de O grande Na prática, é difícil (senão impossível) prever com rigor o tempo de execução de um algoritmo ou programa Para obter o tempo a menos de: constantes multiplicativas (normalmente estas constantes são tempos de execução de operações atómicas) parcelas menos significativas para valores grandes de n Identificam-se as operações dominantes (mais frequentes ou muito mais demoradas) e determina-se o número de vezes que são executadas (e não o tempo de cada execução, que seria uma constante multiplicativa) Exprime-se o resultado com a notação de O grande

Notação de O grande Definição: T(n) = O(f(n)) (lê-se: T(n) é de ordem f(n)) se e só se existem constantes positivas c e n 0 tal que T(n) c.f(n) para todo o n > n 0 Esta notação é usada com três objectivos: limitar o erro que é feito ao ignorar os termos menores nas fórmulas matemáticas limitar o erro que é feito na análise ao desprezar parte do programa que contribui de forma mínima para o custo/complexidade total permitir-nos classificar algoritmos de acordo com limites superiores no seu tempo de execução

Notação de O grande Exemplos: c k n k + c k-1 n k-1 +...+ c 0 = O(n k ) (c i - constantes) log 2 n = O(log n) (não se indica a base porque mudar de base é multiplicar por uma constante) 4 = O(1) (usa-se 1 para ordem constante)

Metodologia para determinar a complexidade Considere-se o seguinte código: for (i = 0; i < n; i++) { Instruções; } A contabilização do número de instruções é simples: n iterações e, em cada uma, são executadas um número constante de instruções O(n)

Metodologia para determinar a complexidade Considere-se o seguinte código: for (i = 0; i < n; i++) for (j = 0; j < n; j++) { Instruções; } A contabilização do número de instruções é ainda simples: o ciclo interno (for j) é O(n) e é executado n vezes O(n2)

Eficiência da Pesquisa Sequencial int PesquisaSequencial (int x, int V[], int n) { int i = 0, k = -1; // k = posição onde se encontra x em V while ( (i < n) && (k == -1) ) if (x == V[i]) k = i; else if (V[i] < x) i = i + 1; else k = -2; return (k); }

Eficiência da Pesquisa Sequencial Eficiência temporal: A operação realizada mais vezes é o teste da condição de continuidade do ciclo while, que é no máximo n+1 vezes (no caso de não encontrar x o pior caso) Se x existir no array, o teste é realizado aproximadamente n/2 vezes (no caso médio) e, 1 vez (no melhor caso) Logo, T(n) = O(n) (linear) no pior caso e no caso médio

Eficiência da Pesquisa Sequencial Eficiência espacial: Gasta o espaço das variáveis locais (incluindo argumentos) Como os arrays são passados por referência (na linguagem C, o que é passado é o endereço do primeiro elemento do array), o espaço ocupado pelas variáveis locais é constante e independente do tamanho do array Logo, S(n) = O(1) (constante) em qualquer caso

Eficiência da Pesquisa Binária int PesquisaBinaria (int x, int V[], int n) { int inicio = 0, fim = n 1, meio, k = -1; while ( (inicio <= fim) && (k == -1) ) { meio = (inicio + fim) / 2; if (x == V[meio]) k = meio; else if (x < V[meio]) fim = meio - 1; else inicio = meio + 1; } return (k); }

Eficiência da Pesquisa Binária Eficiência temporal: Em cada iteração, o tamanho do sub-array a analisar é dividido por um factor de aproximadamente igual a 2 Ao fim de k iterações, o tamanho do sub-array a analisar é aproximadamente igual a n/2 k Se não existir no array o valor procurado, o ciclo só termina quando n/2 k 1 log 2 n - k 0 k log 2 n No pior caso, o número de iterações é aproximadamente igual a log 2 n. Logo, T(n) = O(log n) (logarítmico)

Eficiência da Ordenação por Borbulhagem void Ordenar_Borbulagem (int V[], int n) { int k, Num_trocas, aux; do{ Num_trocas = 0; for (k = 0; k < n-1; k++) if (V[k] > V[k+1]) { aux = V[k]; V[k] = V[k+1]; V[k+1] = aux; Num_trocas++; } }while (Num_trocas!= 0); }

Eficiência da Ordenação por Borbulhagem No melhor caso: Apenas 1 execução do ciclo for : n-1 comparações e 0 trocas No total : (n-1) operações O(n) No pior caso: 1ª passagem pelo ciclo for : n 1 comparações e n 1 trocas 2ª passagem pelo ciclo for : n 1 comparações e n 2 trocas... (n-1)-ésima passagem pelo ciclo for: n-1 comparações e 1 troca Total de comparações : (n-1)x(n-1) = n 2 2n + 1 Total de trocas : (n-1) + (n-2) +... + 1 = n(n-1)/2 = (n 2 n)/2 Total de operações : (n 2 2n + 1) + ((n 2 n)/2) O(n 2 )

Eficiência da Ordenação por Borbulhagem void Ordenar_Borbulagem_Opt (int V[], int n) { int k, kk, fim = n-1, aux; do{ } kk = 0; for (k = 0; k < fim; k++) if (V[k] > V[k+1]) { aux = V[k]; V[k] = V[k+1]; V[k+1] = aux; kk = k; } fim = kk; }while (kk!= 0);

Eficiência da Ordenação por Borbulhagem No melhor caso: Apenas 1 execução do ciclo for : n-1 comparações e 0 trocas No total : (n-1) operações O(n) No pior caso: 1ª passagem pelo ciclo for : n 1 comparações e n 1 trocas 2ª passagem pelo ciclo for : n 2 comparações e n 2 trocas... (n-1)-ésima passagem pelo ciclo for: 1 comparação e 1 troca Total de comparações : (n-1) + (n-2) +... + 1 = n(n-1)/2 Total de trocas : (n-1) + (n-2) +... + 1 = n(n-1)/2 Total de operações : 2x(n(n 1)/2) = n(n-1) = (n 2 n) O(n 2 )