Programação dinâmica. CLRS cap 15. = recursão com tabela = transformação inteligente de recursão em iteração

Documentos relacionados
AULA 15. Algoritmos p.600/637

Programação Dinâmica. Prof. Marcio Delamaro ICMC/USP

Programação dinâmica

AULA 17. Algoritmos p.662/695

Algoritmos gulosos (greedy) CLRS Cap 16 e KT Cap 4

Mochila. Dados dois vetores x[1..n] e w[1..n], denotamos por x w o produto escalar

Mochila. Dados dois vetores x[1..n] e w[1..n], denotamos por x w o produto escalar

Algoritmos gulosos (greedy)

Algoritmos gulosos (greedy)

Fernando Lobo. Algoritmos e Estrutura de Dados. Outra técnica de concepção de algoritmos, tal como Divisão e Conquista.

Comparação com Divisão e Conquista

O termo Programação Dinâmica é um bocado infeliz.

AULA 24. Algoritmos p.856/905

Análise de Algoritmos

Programação Dinâmica. Prof. Anderson Almeida Ferreira

Mergesort. Aula 04. Algoritmo Mergesort. Divisão e Conquista. Divisão e Conquista- MergeSort

Projeto e Análise de Algoritmos Aula 4: Dividir para Conquistar ou Divisão e Conquista ( )

Solução de Recorrências

Melhores momentos AULA 3. Algoritmos p.148/188

Análise de Algoritmos

Projeto e Análise de Algoritmos

Análise de Problemas Recursivos. Algoritmos e Estruturas de Dados Flavio Figueiredo (

Estruturas de Dados 2

Luís Fernando Schultz Xavier da Silveira. 12 de maio de 2010

ANÁLISE DE ALGORITMOS

Desafios de Programação

Problema de seleção de atividades. Aula 14. Exemplo. Algoritmos Gulosos. Algoritmos Gulosos. Intervalo: par ordenado de números

Rascunho. CI165 - Análise de algoritmos (rascunho alterado constantemente) André Guedes Departamento de Informática UFPR. 7 de dezembro de 2016

Análise de Algoritmos

Complexidade de Algoritmos

ANÁLISE DE ALGORITMOS

Programação Dinâmica. Prof. Anderson Almeida Ferreira. Adaptado do material elaborado por Andrea Iabrudi Tavares

AULA 21. Algoritmos p.760/792

Rascunho. CI165 - Análise de algoritmos (rascunho alterado constantemente) André Guedes Departamento de Informática UFPR. 11 de junho de 2017

Referências e materiais complementares desse tópico

Algoritmos e Estrutura de Dados. Aula 04 Recorrência Prof. Tiago A. E. Ferreira

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

Alguns comentários. Segunda prova. Programação dinâmica em grafos. Guloso em grafos. Algoritmos p. 1

CAL ( ) - MIEIC/FEUP Programação Dinâmica ( )

Geometria Computacional p.1/14. Geometria Computacional p.1/14

Estruturas de Dados 2

Divisão-e-Conquista ( ) CAL ( ) MIEIC/FEUP. ./rr (1) Técnicas de Concepção de Algoritmos

MC102 Aula 26. Instituto de Computação Unicamp. 17 de Novembro de 2016

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

Algoritmos e Estruturas de Dados I Linguagem C

Busca Binária. Aula 05. Busca em um vetor ordenado. Análise do Busca Binária. Equações com Recorrência

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

Divisão e Conquista. Norton T. Roman. Apostila baseada nos trabalhos de Cid de Souza, Cândida da Silva e Delano M. Beder

n Programação Dinâmica n Exemplo: Sequência de Fibonnaci n Problemas de Otimização n Multiplicação de Matrizes n Principios de Programação Dinâmica

Projeto e Análise de Algoritmos

AULA 20. Algoritmos p.725/759

Coloração de intervalos

Mediana. Aula 09. Menor. i-ésimo menor elemento. Algoritmo de Seleção. -ésimo menor elemento. Mediana é o n+1. -ésimo menor ou o n+1

Fundamentos de programação

AULA 13. Algoritmos p.526/582

AULA 4. Algoritmo de Euclides. Hoje. Algoritmo de Euclides. Correção. Euclides recursivo

Listas. CIC/UFRGS INF Fundamentos de Algoritmos 2006/1

Ordenação em tempo linear

Aula 2. Divisão e conquista. Exemplo 1: Número de inversões de uma permutação (problema 2-4 do CLRS; veja também sec 5.4 do KT)

Análise de Algoritmos

Análise de Complexidade para algoritmos iterativos e recursivos

Recursão. Aula 1. Liana Duenha. Faculdade de Computação Universidade Federal de Mato Grosso do Sul

Projeto e Análise de Algoritmos

Projeto e Análise de Algoritmos

Introdução à Análise Algoritmos

if not(isinstance(a, int)) or a < 0: raise ValueError ("misterio: arg nao e inteiro nao negativo") else: return misterio_aux(a, a + 1)

Ponto q está no polígono?

Hoje. mais análise de algoritmos: algoritmo de Euclides mais recursão: curvas de Hilbert

Análise de algoritmos

Análise de Complexidade de Algoritmos

AULA 17. Melhores momentos. Segmento de soma máxima. Segmento de soma máxima. Conclusões. Algumas técnicas

Algoritmos de ordenação Quicksort

1 a Lista de Exercícios

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

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

Análise de Algoritmos

Divisão e Conquista. Fernando Lobo. Algoritmos e Estrutura de Dados II. É uma técnica para resolver problemas (veremos outras técnicas mais adiante).

Análise de algoritmos

Aula 05: - Recursão (parte 1)

Complexidade de Algoritmos

INE5403 FUNDAMENTOS DE MATEMÁTICA DISCRETA

Geometria Computacional

LISTA DE EXERCÍCIOS. Humberto José Bortolossi

Análise de algoritmos

ESTRUTURA DE DADOS CIÊNCIA E TECNOLOGIA DO RIO. Curso de Tecnologia em Sistemas para Internet

7 O Método do Nucleolus

Mais recursão ainda AULA 4. Máximo divisor comum. Divisibilidade. Máximo divisor comum. Divisibilidade PF 2.1, 2.2, 2.3 S 5.1

Construção de Algoritmos II Aula 06

Estruturas de Dados Algoritmos

Análise de Algoritmos

Introdução à Programação / Programação I

Algoritmos e Programação. AULA 21: Recursividade UNIVERSIDADE FEDERAL DE PELOTAS CENTRO DE DESENVOLVIMENTO TECNOLÓGICO CIÊNCIA DA COMPUTAÇÃO

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

Método de restrições ativas para minimização em caixas

Análise e Complexidade de Algoritmos

Projeto e Análise de Algoritmos Projeto de Algoritmos Programação Dinâmica. Prof. Humberto Brandão

FACULDADE CAMPO LIMPO PAULISTA BACHARELADO EM CIÊNCIA DA COMPUTAÇÃO. Projeto a Análise de Algoritmos I Lista de Exercícios 1

Algoritmos para Automação e Sistemas. Programação Dinâmica. Universidade Federal do Amazonas Departamento de Eletrônica e Computação

Funções são blocos de código que podem ser nomeados e chamados de dentro de um programa.

Transcrição:

Programação dinâmica CLRS cap 15 = recursão com tabela = transformação inteligente de recursão em iteração

Números de Fibonacci F 0 = 0 F 1 = 1 F n = F n 1 +F n 2 n 0 1 2 3 4 5 6 7 8 9 F n 0 1 1 2 3 5 8 13 21 34

Números de Fibonacci F 0 = 0 F 1 = 1 F n = F n 1 +F n 2 n 0 1 2 3 4 5 6 7 8 9 F n 0 1 1 2 3 5 8 13 21 34 Algoritmo recursivo para F n : FIBO-REC (n) 1 se n 1 2 então devolva n 3 senão a FIBO-REC(n 1) 4 b FIBO-REC(n 2) 5 devolva a+b

Consumo de tempo FIBO-REC (n) 1 se n 1 2 então devolva n 3 senão a FIBO-REC(n 1) 4 b FIBO-REC(n 2) 5 devolva a+b Tempo em segundos: n 16 32 40 41 42 43 44 45 47 tempo 0.002 0.06 2.91 4.71 7.62 12.37 19.94 32.37 84.50 F 47 = 2971215073

Consumo de tempo FIBO-REC (n) 1 se n 1 2 então devolva n 3 senão a FIBO-REC(n 1) 4 b FIBO-REC(n 2) 5 devolva a+b T(n) := número de somas feitas por FIBO-REC (n) linha número de somas 1-2 = 0 3 = T(n 1) 4 = T(n 2) 5 = 1 T(n) = T(n 1)+T(n 2)+1

Recorrência T(0) = 0 T(1) = 0 T(n) = T(n 1)+T(n 2)+1 para n = 2,3,... A que classe Ω pertence T(n)? A que classe O pertence T(n)?

Recorrência T(0) = 0 T(1) = 0 T(n) = T(n 1)+T(n 2)+1 para n = 2,3,... A que classe Ω pertence T(n)? A que classe O pertence T(n)? Solução: T(n) > (3/2) n para n 6. n 0 1 2 3 4 5 6 7 8 9 T n 0 0 1 2 4 7 12 20 33 54 (3/2) n 1 1.5 2.25 3.38 5.06 7.59 11.39 17.09 25.63 38.44

Recorrência Prova: T(6) = 12 > 11.40 > (3/2) 6 e T(7) = 20 > 18 > (3/2) 7. Se n 8, então T(n) = T(n 1)+T(n 2)+1 hi > (3/2) n 1 +(3/2) n 2 + 1 = (3/2+1)(3/2) n 2 + 1 > (5/2)(3/2) n 2 > (9/4)(3/2) n 2 = (3/2) 2 (3/2) n 2 = (3/2) n. Logo, T(n) é Ω((3/2) n ). Verifique que T(n) é O(2 n ).

Consumo de tempo Consumo de tempo é exponencial. Algoritmo resolve subproblemas muitas vezes. F 5 F 4 F 3 F 3 F 2 F 2 F 1 F 2 F 1 F 1 F 0 F 1 F 0 F 1 F 0

Resolve subproblemas muitas vezes FIBO-REC(5) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(5) = 5

Resolve subproblemas muitas vezes FIBO-REC(8) FIBO-REC(7) FIBO-REC(6) FIBO-REC(5) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(5) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(6) FIBO-REC(5) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(4) FIBO-REC(3) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0) FIBO-REC(1) FIBO-REC(2) FIBO-REC(1) FIBO-REC(0)

Programação dinâmica "Dynamic programming is a fancy name for divide-and-conquer with a table. Instead of solving subproblems recursively, solve them sequentially and store their solutions in a table. The trick is to solve them in the right order so that whenever the solution to a subproblem is needed, it is already available in the table. Dynamic programming is particularly useful on problems for which divide-and-conquer appears to yield an exponential number of subproblems, but there are really only a small number of subproblems repeated exponentially often. In this case, it makes sense to compute each solution the first time and store it away in a table for later use, instead of recomputing it recursively every time it is needed." I. Parberry, Problems on Algorithms, Prentice Hall, 1995.

Versão recursiva com memoização MEMOIZED-FIBO (f, n) 1 para i 0 até n faça 2 f[i] 1 3 devolva LOOKUP-FIBO (f, n) LOOKUP-FIBO (f, n) 1 se f[n] 0 2 então devolva f[n] 3 se n 1 4 então f[n] n 5 senão f[n] LOOKUP-FIBO(f,n 1) + LOOKUP-FIBO(f,n 2) 6 devolva f[n] Não recalcula valores de f.

Algoritmo de programação dinâmica Sem recursão: FIBO (n) 1 f[0] 0 2 f[1] 1 3 para i 2 até n faça 4 f[i] f[i 1]+f[i 2] 5 devolva f[n] Note a tabela f[0..n 1]. f?? Consumo de tempo (e de espaço) é Θ(n).

Algoritmo de programação dinâmica Versão com economia de espaço. FIBO (n) 0 se n = 0 então devolva 0 1 f_ant 0 2 f_atual 1 3 para i 2 até n faça 4 f_prox f_atual + f_ant 5 f_ant f_atual 6 f_atual f_prox 7 devolva f_atual

Algoritmo de programação dinâmica Versão com economia de espaço. FIBO (n) 0 se n = 0 então devolva 0 1 f_ant 0 2 f_atual 1 3 para i 2 até n faça 4 f_prox f_atual + f_ant 5 f_ant f_atual 6 f_atual f_prox 7 devolva f_atual Consumo de tempo é Θ(n). Consumo de espaço é Θ(1).

Corte de hastes Hastes de aço são vendidas em pedaços de tamanho inteiro. As usinas produzem hastes longas, e os comerciantes cortam em pedaços para vender. Suponha que o preço de uma haste de tamanho i esteja tabelado como p i.

Corte de hastes Hastes de aço são vendidas em pedaços de tamanho inteiro. As usinas produzem hastes longas, e os comerciantes cortam em pedaços para vender. Suponha que o preço de uma haste de tamanho i esteja tabelado como p i. Problema: Dada uma haste de tamanho n e a tabela p de preços, qual a melhor forma de cortar a haste para maximizar o preço de venda total?

Corte de hastes Hastes de aço são vendidas em pedaços de tamanho inteiro. As usinas produzem hastes longas, e os comerciantes cortam em pedaços para vender. Suponha que o preço de uma haste de tamanho i esteja tabelado como p i. Problema: Dada uma haste de tamanho n e a tabela p de preços, qual a melhor forma de cortar a haste para maximizar o preço de venda total? Versão simplificada: qual o maior valor q n que se pode obter de uma haste de tamanho n?

Exemplo n 1 2 3 4 5 6 7 8 9 p n 1 5 8 9 10 17 17 20 24

Exemplo n 1 2 3 4 5 6 7 8 9 p n 1 5 8 9 10 17 17 20 24 Possíveis cortes para n = 4: 9 1 8 5 5 1 1 5 1 1 1 1

Exemplo n 1 2 3 4 5 6 7 8 9 p n 1 5 8 9 10 17 17 20 24 Possíveis cortes para n = 4: 9 1 8 5 5 1 1 5 1 1 1 1 Melhor corte (de maior lucro): o terceiro, com valor 10.

Solução recursiva Corta-se um primeiro pedaço de tamanho i e o pedaço restante, de tamanho n i, do melhor jeito possível. O valor desse corte é p i +q n i.

Solução recursiva Corta-se um primeiro pedaço de tamanho i e o pedaço restante, de tamanho n i, do melhor jeito possível. O valor desse corte é p i +q n i. A questão é escolher o melhor i; o que maximiza a expressão acima: q n = max 1 i n {p i +q n i }. q 0 = 0.

Primeiro código CORTA-HASTE (p, n) 1 se n = 0 2 então devolva 0 3 q 4 para i 1 até n 5 q max{q,p[i]+corta-haste(p,n i)} 6 devolva q

Primeiro código CORTA-HASTE (p, n) 1 se n = 0 2 então devolva 0 3 q 4 para i 1 até n 5 q max{q,p[i]+corta-haste(p,n i)} 6 devolva q Consumo de tempo: n 1 T(n) = 1+ T(i)= 2 n. i=0

Primeiro código CORTA-HASTE (p, n) 1 se n = 0 2 então devolva 0 3 q 4 para i 1 até n 5 q max{q,p[i]+corta-haste(p,n i)} 6 devolva q Consumo de tempo: n 1 T(n) = 1+ T(i) = 2 n. i=0

Com memoização Note que r funciona como variável global. CORTA-HASTE-MEMOIZADO (p, n) 1 r[0] 0 2 para i 1 até n 3 r[i] 4 devolva CORTA-HASTE-MEMOIZADO-REC (p, n, r)

Com memoização Note que r funciona como variável global. CORTA-HASTE-MEMOIZADO (p, n) 1 r[0] 0 2 para i 1 até n 3 r[i] 4 devolva CORTA-HASTE-MEMOIZADO-REC (p, n, r) CORTA-HASTE-MEMOIZADO-REC (p, n, r) 1 se r[n] 0 2 devolva r[n] 3 senão q 4 para i 1 até n 5 q max{q,p[i]+corta-haste-memoizado-rec(p,n i,r)} 6 r[n] q 7 devolva q

Bottom up CORTA-HASTE-BOTTOM-UP (p, n) 1 r[0] 0 2 para j 1 até n 3 q 4 para i 1 até j 5 q max{q,p[i]+r[j i]} 6 r[j] q 7 devolva q

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 2

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 6

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 6

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 9

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 10

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 10

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 10

Recuperando o melhor corte CORTA-HASTE-BOTTOM-UP-COMPLETO (p, n) 1 r[0] 0 2 para j 1 até n 3 q 4 para i 1 até j 5 se q < p[i]+r[j i] 6 q p[i]+r[j i] 7 d[j] i 8 r[j] q 9 devolva q e d

Exemplo n 1 2 3 4 p n 1 5 8 9

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 d n 1

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 2 d n 1 1

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 d n 1 2

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 6 d n 1 2 1

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 d n 1 2 3

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 9 d n 1 2 3 1

Exemplo n 1 2 3 4 p n 1 5 8 9 n 0 1 2 3 4 r n 0 1 5 8 10 d n 1 2 3 2

Listando os cortes (usando concatenação de listas, estilo python) LISTA-CORTES(d, n) 1 se n = 0 ou d[n] = n 2 devolva [ ] lista vazia 3 senão 4 devolva [d[n]].lista-cortes(d,n d[n])

Listando os cortes (usando concatenação de listas, estilo python) LISTA-CORTES(d, n) 1 se n = 0 ou d[n] = n 2 devolva [ ] lista vazia 3 senão 4 devolva [d[n]].lista-cortes(d,n d[n]) Consumo de tempo: O(n)