CIC 110 Análise e Projeto de Algoritmos I

Documentos relacionados
Complexidade de Algoritmos

ALGORITMOS AVANÇADOS UNIDADE I Análise de Algoritmo - Notação O. Luiz Leão

Análise e Projeto de Algoritmos

CT-234. Estruturas de Dados, Análise de Algoritmos e Complexidade Estrutural. Carlos Alberto Alonso Sanches

Análise e Projeto de Algoritmos

Complexidade de Algoritmos

Análise de Complexidade de Algoritmos. mario alexandre gazziro

CCO 016 / COM 110 Fundamentos de Programação

Algoritmos Avançados Análise de Complexidade

INF 1010 Estruturas de Dados Avançadas

Projeto e Análise de Algoritmos

Projeto e Análise de Algoritmos

Complexidade Assintótica de Programas Letícia Rodrigues Bueno

Análise de algoritmos. Parte I

Complexidade Assintótica

Teoria dos Grafos Aula 7

03 Análise de Algoritmos (parte 3) SCC201/501 - Introdução à Ciência de Computação II

Teoria da Computação Aula 9 Noções de Complexidade

Complexidade de Algoritmos

ANÁLISE DE ALGORITMOS: PARTE 3

Complexidade de Tempo e Espaço

INF 1010 Estruturas de Dados Avançadas

PLANO DE DISCIPLINA DISCIPLINA: Análise de Algoritmos

André Vignatti DINF- UFPR

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

TEORIA: 60 LABORATÓRIO: 0

Teoria da Computação. Aula 3 Comportamento Assintótico 5COP096. Aula 3 Prof. Dr. Sylvio Barbon Junior. Sylvio Barbon Jr

Análise e Projeto de Algoritmos

1 a Lista de Exercícios

Aula 1. Teoria da Computação III

Introdução à Ciência da Computação II

ANÁLISE DE COMPLEXIDADE DOS ALGORITMOS

Complexidade de Algoritmos

Teoria da Computação Aula 8 Noções de Complexidade

Análise de complexidade

Estruturas de Dados Aula 1: Introdução e conceitos básicos 28/02/2011

SIN5013 Análise de Algoritmos e Estrutura de Dados - 1o Semestre de 2019

Construção de Algoritmos II Aula 06

Introdução à Ciência da Computação II

Análise de Complexidade de Algoritmos

4º 20/10/2003. ÍNDICE

Projeto e Análise de Algoritmos

Análise e Projeto de Algoritmos

Projeto e Análise de Algoritmos

Classes, Herança e Interfaces

PCC104 - Projeto e Análise de Algoritmos

BCC202 - Estrutura de Dados I

Complexidade de algoritmos Notação Big-O

COMPLEXIDADE DE ALGORITMOS

1 a Lista Professor: Claudio Fabiano Motta Toledo Estagiário PAE: Jesimar da Silva Arantes

Aula 02 Notação Assintótica p. 4. Usodanotação O. Notação O. Notação O, Ω, ΘeExemplos. Intuitivamente... O(f(n)) funções que não crescem mais

Prova Didática Grafos: Árvores Geradoras e Caminhos Mínimos, Análise de Complexidade

Medida do Tempo de Execução de um Programa

Técnicas de projeto de algoritmos: Indução

André Vignatti DINF- UFPR

Filas de Prioridades Letícia Rodrigues Bueno

5COP096 TeoriadaComputação

Complexidade de Algoritmos

Algoritmos de Ordenação

COMPLEXIDADE DE ALGORITMOS COMPLEXIDADE DE ALGORITMOS

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

Aula 06: Análise matemática de algoritmos recursivos

Análise e Síntese de Algoritmos. Programação Dinâmica CLRS, Cap. 15

ALGORITMOS E ESTRUTURAS DE DADOS I PROF. EDSON IFARRAGUIRRE MORENO

Árvore Binária de Busca Ótima

Classificação e Pesquisa

Análise de Algoritmos e Estruturas de Dados

Lista de exercícios sobre contagem de operações Prof. João B. Oliveira

PLANO DE DISCIPLINA DISCIPLINA: Algoritmos e Programação

Teoria dos Grafos. Valeriano A. de Oliveira Socorro Rangel Departamento de Matemática Aplicada.

Elementos de Análise Assintótica

ESTRUTURA DE DADOS DCC013

Análise de Algoritmos Estrutura de Dados II

ESTRUTURAS DE DADOS prof. Alexandre César Muniz de Oliveira

Análise de Algoritmos

2. Complexidade de Algoritmos

Programação Dinâmica I SCC0210 Algoritmos Avançados (2/2011) Lucas Schmidt Cavalcante

Métodos de Ordenação: Selection, Insertion, Bubble, Merge (Sort)

PCC104 - Projeto e Análise de Algoritmos

Teoria da computabilidade Indecidíveis Decidíveis

a complexidade no desempenho de algoritmos

Transcrição:

CIC 110 Análise e Projeto de Algoritmos I Prof. Roberto Affonso da Costa Junior Universidade Federal de Itajubá

Introdução ao curso AULA 01

Prof. Roberto Affonso da Costa Junior rcosta62br@gmail.com http//www.facebook.com/rcosta62br http://www.rcosta62br.unifei.edu.br whatsapp: (35) 98879-8637 Instituto de Matemática e Computação

Tipo de aulas O curso Apresentação de slides Prática em laboratório Prática em casa Utilização de ambientes de programação Aulas em video.

Avaliação 6 Provas de 0 a 100 pontos (P1,P2,P3,P4) Essas provas serão realizadas em equipe de, NO MÁXIMO 3 alunos e NO MÍNIMO 2 alunos, no laboratório nas datas marcadas no site da sua turma. COMPOSIÇÃO: Nota N1: a média aritimética das notas (P1 e P2) Nota N2: a média aritimética das notas (P3 e P4)

Avaliação 1 Prova Substitutiva de 0 a 100 pontos (PS) Essas provas será realizada no laboratório e seguira as regras da UNIFEI.

Avaliação O aluno que perder uma prova poderá realizar a substitutiva para repor a prova perdida. Sendo que neste caso não precisa trazer autorização da PRG. No caso da perda de uma prova com autorização da PRG, o aluno irá realizar individualmente e em horário agendado com o professor.

Composição da prova Todas as provas serão no formato de competição. As provas terão 5 questões valendo, cada uma delas, 16 pontos, totalizando 80 pontos. Conforme a colocação da equipe na prova, elas irão receber a seguinte pontuação: 1 30 2 25 3 22 4 19 5 17 6 15 7 13 8 11 9 9... 5

Avaliação COMPETIÇÃO: Concorrência a uma mesma pretensão por parte de duas ou mais pessoas ou grupos, com vistas a igualar ou a superar o outro.

A nota final será composta de: Avaliação Nota Final (NF) = (N1 + N2) / 2 Se NF >= 60 Então APROVADO Senão REPROVADO A prova Substitutiva, vai substituir a nota da prova P1 ou P2, a menor delas.

Datas Importantes Estão disponibilizadas no site: www.rcosta62br.unifei.edu.br

Sugestão de Bibliografia Notas de Aulas Competitive Programming, 3rd Edition, Steven Halim T. Cormen, C. E. Leiserson, R. L. Rivest, C. Stein. Introduction to Algorithms, second edition, The MIT Press, 2005. N. Wirth. Algorithms + Data Structures = Programs. Prentice Hall, 1976. D. E. Knuth. The Art of Computer Programming. Volume 1, Addison Wesley, 1973.

Sugestão de Bibliografia A. V. Aho, J. E. Hopcroft, and J. D. Ullman. Data structures and algorithms. Addison Wesley, 1987. J. L. Szwarcfiter e L. Markenzon. Estruturas de Dados e seus Algoritmos. LTC Editora, 1994. A. Drozdek. Estrutura de Dados e Algoritmos em C++. Thompson, 2002. N. Ziviani. Projeto de Algoritmos com Implementações em Pascal e C. Livraria Pioneira Editora, São Paulo, 1993.

Sites de desafios https://www.urionlinejudge.com.br http://acm.timus.ru/ http://codeforces.com/ https://a2oj.com/ https://codepit.io

Sugestões para seu bom desempenho no curso Não falte às aulas; Não tenha vergonha de fazer perguntas para tirar suas dúvidas durante as aulas; Não deixe para estudar às vésperas das provas; Procure seu professor em sua sala, sempre que uma dúvida não tiver sido bem esclarecida;

O aluno não será atendido pelo professor às vésperas das provas; Sempre que possível, utilize o computador para tirar suas dúvidas; Procure também os alunos monitores de ensino, para ser ajudado nas tarefas escolares (horários disponíveis nos quadros de avisos );

Jamais tente colar ou passar cola para outros durante as atividades escolares; as penas institucionais são muito rígidas a este respeito. O aluno, se pego nestas situações, é punido com a perda da disciplina. Qualquer dúvida com relação à disciplina, procure o professor da mesma ou leia diariamente os quadros de avisos oficiais; não confie em boatos ou fiquei sabendo, ou disseram etc.

Haverá chamada em todas as aulas. O aluno que faltar mais de ¼ das aulas será reprovado. Para justificar sua ausência, o aluno deve procurar a PRG, documentado com o motivo de sua ausência. E está informará o professor.

Conteúdo das disciplinas 1. Data Strucutres Stacks/Queues/Heaps/ Segment Tree BitVec 2. Graph DFS BFS Topological Sort Kruskal Prim Dijkstra (with previous nodes) Bellman Ford Floyd-Warshall (minimax, maximin, safest path, transitive hull)

Conteúdo das disciplinas 3. Dynamic Programming Knaspack LIS/LDS (n 2 e n log n) LCS Counting Change 4. Geometry Point, distance, triangle area, collinear, counterclockwise Line, parallel Convex Hull: Graham Scan 5. Strings Suffix array LCP

Conteúdo das disciplinas 6. Math and Number Theory Base Convertion GCD/LCM Primes, sieve powmod Fibonacci Mod Polar coordinate system LatlongDistance Modular arithmetics Combinatorics Totient Carmichael Number Catalan Formula Recursion as matrix exponentiation

Agradecimentos ao Prof. Siang Wun Song - Universidade de São Paulo IME/USP

Objetivo de estudar Por que analisar a complexidade dos algoritmos? A preocupação com a complexidade de algoritmos é fundamental para projetar algoritmos eficientes. Podemos desenvolver um algoritmo e depois analisar a sua complexidade para verificar a sua eficiência. Mas o melhor ainda é ter a preocupação de projetar algoritmos eficientes desde a sua concepção.

Eficiência ou complexidade Para um dado problema considere dois algoritmos que o resolvem. Seja n um parâmetro que caracteriza o tamanho da entrada do algoritmo. Por exemplo, ordenar n números ou multiplicar duas matrizes quadradas n n (cada uma com n 2 elementos). Como podemos comparar os dois algoritmos para escolher o melhor?

Complexidade de tempo ou de espaço Precisamos definir alguma medida que expresse a eficiência. Costuma-se medir um algoritmo em termos de tempo de execução ou o espaço (ou memória) usado. Para o tempo, podemos considerar o tempo absoluto (em minutos, segundos, etc.). Medir o tempo absoluto não é interessante por depender da máquina. Em Análise de Algoritmos conta-se o número de operações consideradas relevantes realizadas pelo algoritmo e expressa-se esse número como uma função de n. Essas operações podem ser comparações, operações aritméticas, movimento de dados, etc.

Complexidade de tempo ou de espaço O número de operações realizadas por um determinado algoritmo pode depender da particular instância da entrada. Em geral interessa-nos o pior caso, i.e., o maior número de operações usadas para qualquer entrada de tamanho n. Análises também podem ser feitas para o melhor caso e o caso médio. Neste último, supõe-se conhecida uma certa distribuição da entrada. Exemplo: Busca sequencial de um dado elemento em um vetor armazenando n elementos de forma aleatória. Discuta o pior caso, melhor caso e o caso médio. No caso médio suponha a distribuição uniforme e que o dado buscado está dentro do vetor. Como muda o caso médio se o dado em geral não está presente?

Complexidade de tempo Como exemplo, considere o número de operações de cada um dos dois algoritmos que resolvem o mesmo problema, como função de n. Algoritmo 1: f 1 (n) = 2n 2 + 5n operações Algoritmo 2: f 2 (n) = 500n + 4000 operações Dependendo do valor de n, o Algoritmo 1 pode requerer mais ou menos operações que o Algoritmo 2. (Compare as duas funções para n = 10 e n = 100.)

Comportamento assintótico Algoritmo 1: f 1 (n) = 2n 2 + 5n operações Algoritmo 2: f 2 (n) = 500n + 4000 operações Um caso de particular interesse é quando n tem valor muito grande (n ), denominado comportamento assintótico. Os termos inferiores e as constantes multiplicativas contribuem pouco na comparação e podem ser descartados. O importante é observar que f 1 (n) cresce com n 2 ao passo que f 2 (n) cresce com n. Um crescimento quadrático é considerado pior que um crescimento linear. Assim, vamos preferir o Algoritmo 2 ao Algoritmo 1.

Comportamento assintótico Algoritmo 1: f 1 (n) = 2n 2 + 5n operações Algoritmo 2: f 2 (n) = 500n + 4000 operações Um caso de particular interesse é quando n tem valor muito grande (n ), denominado comportamento assintótico. Os termos inferiores e as constantes multiplicativas contribuem pouco na comparação e podem ser descartados. O importante é observar que f 1 (n) cresce com n 2 ao passo que f 2 (n) cresce com n. Um crescimento quadrático é considerado pior que um crescimento linear. Assim, vamos preferir o Algoritmo 2 ao Algoritmo 1.

Notação O Dada uma função g(n), denotamos por O(g(n)) o conjunto das funções. { f(n) : constantes c e n 0 tais que 0 f(n) cg(n) para n n 0.} Isto é, para valores de n suficientemente grandes, f(n) é igual ou menor que g(n). Como abuso de notação, vamos escrever f(n) = O(g(n)) ao invés de f(n) O(g(n)). Algoritmo 1: f 1 (n) = 2n 2 + 5n = O(n 2 ) Algoritmo 2: f 2 (n) = 500n + 4000 = O(n) Um polinômio de grau d é de ordem O(n d ). Como uma constante pode ser considerada como um polinômio de grau 0, então dizemos que uma constante é O(n 0 ) ou seja O(1).

Exercícios A) É verdade que 2n 2 + 100n = O(n 2 )? Prove. B) É verdade que 10 + 4/n = O(n 0 ) = O(1)? Prove. C) Escreva a seguinte função em notação O, sem provar: 4n 2 + 10 log n + 500 D) Mesmo para a função. 5n n + 102 n E) Mesmo para a função. 2(n 1) n + n n 1

Solução A) É verdade que 2n 2 + 100n = O(n 2 )? Prove. Sendo f(n) = 2n 2 + 100n. Observe que: 2n 2 + 100n 2n 2 + 100n 2 = 102n 2 desde que n 1. Resumindo, f(n) 102 g(n) para todo n 1. Portanto, f(n) = Ο(g(n)) = O(n 2 ) = 2.

Visitar, ler e estudar https://www.ime.usp.br/~pf/analise_de_algoritmos/a ulas/oh.html

Notação Ω Dada uma função g(n), denotamos por Ω(g(n)) o conjunto das funções. { f(n) : constantes c e para n n 0.} n 0 tais que 0 cg(n) f(n) Isto é, para valores de n suficientemente grandes, f(n) é igual ou maior que g(n). Novamente, abusando a notação, vamos escrever f(n) = Ω(g(n))

Notação Θ Dadas duas funções f(n) e g(n), temos f(n) = Θ(g(n)) se e somente se f(n) = O(g(n)) e f(n) = Ω(g(n))

Considere 5 algoritmos com as complexidades de tempo. Suponhamos que uma operação leve 1 ms. n f1 (n) = n f 2 (n) = n log n f 3 (n) = n 2 f 4 (n) = n 3 f 5 (n) = 2 n 16 0,016 s 0,064 s 0.256 s 4 s 1 m 4 s 32 0,032 s 0,16 s 1 s 33 s 46 dias 512 0,512 s 9 s 4m 22 s 1 dia 13 h 10137 séculos

Considere 5 algoritmos com as complexidades de tempo. Suponhamos que uma operação leve 1 ms. n f 1 (n) = n f 2 (n) = n log n f 3 (n) = n 2 f 4 (n) = n 3 f 5 (n) = 2 n 16 0,016 s 0,064 s 0.256 s 4 s 1 m 4 s 32 0,032 s 0,16 s 1 s 33 s 46 dias 512 0,512 s 9 s 4m 22 s 1 dia 13 h 10137 séculos (Verifique se resolveria usar uma máquina mais rápida onde uma operação leve 1 ps (pico segundo) ao invés de 1 ms: ao invés de 10 137 séculos seriam 10 128 séculos :-)

Considere 5 algoritmos com as complexidades de tempo. Suponhamos que uma operação leve 1 ms. n f 1 (n) = n f 2 (n) = n log n f 3 (n) = n 2 f 4 (n) = n 3 f 5 (n) = 2 n 16 0,016 s 0,064 s 0.256 s 4 s 1 m 4 s 32 0,032 s 0,16 s 1 s 33 s 46 dias 512 0,512 s 9 s 4m 22 s 1 dia 13 h 10137 séculos (Verifique se resolveria usar uma máquina mais rápida onde uma operação leve 1 ps (pico segundo) ao invés de 1 ms: ao invés de 10 137 séculos seriam 10 128 séculos :-) Podemos muitas vezes melhorar o tempo de execução de um programa otimizando o código (i.e. usar x + x ao invés de 2x, evitar recálculo de expressões já calculadas, etc.).

Entretanto, melhorias muito mais substanciais podem ser obtidas se usarmos um algoritmo diferente, com outra complexidade de tempo, i.e. obter um algoritmo de O(n log n) ao invés de O(n 2 ).

Cota superior ou limite superior (upper bound) Seja dado um problema, por exemplo, multiplicação de duas matrizes quadradas n n. Conhecemos um algoritmo para resolver este problema (pelo método trivial) de complexidade O(n 3 ). Sabemos assim que a complexidade deste problema não deve superar O(n 3 ), uma vez que existe um algoritmo que o resolve com esta complexidade. Uma cota superior ou limite superior (upper bound) deste problema é O(n 3 ). O(n 3 ) A cota superior de um problema pode mudar se alguém descobrir um outro algoritmo melhor.

Multiplicação de Matriz n 3 Pior caso: for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { M3[i][j] = 0.0; for (k = 0; k < N; k++) { M3[i][j] = M3[i][j] + M1[i][k] * M2[k][j]; } } }

Cota superior (upper bound) O Algoritmo de Strassen reduziu a complexidade para O(n log 7 ). Assim a cota superior do problema de multiplicação de matrizes passou a ser O(n log 7 ). O(n log 7 ) O(n 3 ) Coppersmith e Winograd melhoraram ainda para O(n 2.376 ). O(n 2.376 ) O(n log 7 ) O(n 3 ) Note que a cota superior de um problema depende do algoritmo. Pode diminuir quando aparece um algoritmo melhor.

Como seria os algoritmos? Algoritmo de Strassen Algoritmo Coppersmith e Winograd

Analogia com record mundial A cota superior para resolver um problema é análoga ao record mundial de uma modalidade de atletismo. Ele é estabelecido pelo melhor atleta (algoritmo) do momento. Assim como o record mundial, a cota superior pode ser melhorada por um algoritmo (atleta) mais veloz. Cota superior da corrida de 100 metros rasos:

Analogia com record mundial Cota superior da corrida de 100 metros rasos: Ano Atleta (Algoritmo) Tempo 1988 Carl Lewis 9s92 1993 Linford Christie 9s87 1993 Carl Lewis 9s86 1994 Leroy Burrell 9s84 1996 Donovan Bailey 9s84 1999 Maurice Greene 9s79 2002 Tim Montgomery 9s78 2007 Asafa Powell 9s74 2008 Usain Bolt 9s72 2008 Usain Bolt 9s69 2009 Usain Bolt 9s58

Sequência de Fibonacci Para projetar um algoritmo eficiente, é fundamental preocupar-se com a sua complexidade. Como exemplo: considere a sequência de Fibonacci. 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, A sequência pode ser definida recursivamente: F n ={ 0 se n=0 1 se n=1 F n 1 + F n 2 se n>1 Dado o valor de n, queremos obter o n-ésimo elemento da sequência. Vamos apresentar dois algoritmos e analisar sua complexidade.

Algoritmo 1: função fibo1(n) Seja a função fibo1(n) que calcula o n-ésimo elemento da sequência de Fibonacci. Input: Valor de n Output: O n-ésimo elemento da sequência de Fibonacci Experimente rodar este algoritmo para n = 100 :-)

Algoritmo 1: função fibo1(n) Algoritmo 1: função fibo1(n) Function fibo1(n) 1: if (n == 0) 2: { 3: return 0; 4: } else { 5: if (n == 1) 6: { 7: return 1; 8: } else { 9: return fibo1(n 1) + fibo1(n 2); 10: } 11: }

Algoritmo 1: função fibo1(n) A complexidade é O(2 n ). (Mesmo se uma operação levasse um picosegundo, 2 100 operações levariam 3 10 13 anos = 30.000.000.000.000 anos.)

Algoritmo 2: função fibo2(n) Function fibo2(n) 1: if (n == 0) 2: { 3: return 0; 4: } else { 5: if (n == 1) 6: { 7: return 1; 8: } else { 9: penultimo = 0; 10: ultimo = 1; 11: for (i = 2; i <= n; i++) 12: { 13: atual = penultimo + ultimo; 14: penultimo = ultimo; 15: ultimo = atual; 16: } 17: return atual; 18: } 19: }

Algoritmo 2: função fibo2(n) A complexidade é O(2 n ) para O(n). Você sabe que dá para fazer em O(log n)? Qual a diferença dos 3 abaixo? https://rcosta62br.unifei.edu.br/cic110/fibonacci_log_n.c https://rcosta62br.unifei.edu.br/cic110/fibonacci_pd.c https://rcosta62br.unifei.edu.br/cic110/fibonacci_recursivo.c

Cota inferior (lower bound) As vezes é possível demonstrar que, para um dado problema, qualquer que seja o algoritmo a ser usado, o problema requer pelo menos um certo número de operações. Essa complexidade é chamada cota inferior (lower bound) do problema. Note que a cota inferior depende do problema mas não do particular algoritmo.

Cota inferior para multiplicação de matrizes Para o problema de multiplicação de matrizes quadradas n n, apenas para ler os elementos das duas matrizes de entrada ou para produzir os elementos da matriz produto leva tempo O(n 2 ). Assim uma cota inferior trivial é Ω(n 2 ). Na analogia anterior, uma cota inferior de uma modalidade de atletismo não dependeria mais do atleta. Seria algum tempo mínimo que a modalidade exige, qualquer que seja o atleta. Uma cota inferior trivial para os 100 metros rasos seria o tempo que a velocidade da luz leva para percorrer 100 metros no vácuo.

Meta: aproximando as duas cotas Ω(n 2 ) O(n 2.376 ) O(n log 7 ) O(n 3 ) Se um algoritmo tem uma complexidade que é igual à cota inferior do problema, então ele é assintoticamente ótimo. O algoritmo de Coppersmith e Winograd é de O(n 2.376 ) mas a cota inferior (conhecida até hoje) é de Ω(n 2 ). Portanto não podemos dizer que ele é ótimo. Pode ser que esta cota superior possa ainda ser melhorada. Pode também ser que a cota inferior de Ω(n 2 ) possa ser melhorada (isto é aumentada ). Para muitos problemas interessantes, pesquisadores dedicam seu tempo tentando encurtar o intervalo ( gap ) até encostar as duas cotas.