Você está na página 1de 39

Projeto de Algoritmos

Programao Dinmica

Diviso e conquista: relembrando...


Paradigma em que um problema resolvido
recursivamente aplicando trs etapas em cada nvel
da recurso:
1. Diviso: Dividir o problema em subproblemas
menores.

2. Conquista: Resolver cada subproblema


independentemente.
3. Combinao: Combinar as solues encontradas para
os subproblemas

Diviso e conquista: relembrando...


Ordenao
Quicksort e Mergesort;
Pesquisa
Pesquisa binria;
Algoritmos aritmticos
Multiplicao de inteiros, multiplicao de
matrizes
Outros
Fibonacci recursivo, etc.

Programao Dinmica
Programao Dinmica est relacionada com
um mtodo de soluo baseado em tabela.
A programao dinmica calcula a soluo para
todos os subproblemas, partindo dos subproblemas menores para os maiores, armazenando
os resultados em uma tabela.
A vantagem que uma vez que um subproblema
resolvido, a resposta armazenada em uma tabela
e nunca mais recalculada.

Programao Dinmica
Necessrio para Programao Dinmica
estrutura recursiva: a soluo de toda instncia deve
"conter" solues de subinstncias

O algoritmo recursivo refaz a soluo de cada


subinstncia.
Constri-se uma tabela para
armazenar as soluo das subinstncia
A tabela a base de um algoritmo de
programao dinmica.
Vamos a um exemplo...

Programao Dinmica
Exemplo: Sequncia de Fibonacci
Consiste de uma sequncia de inteiros, tal
que:
F(0) = 0;
F(1) = 1;
F(n) = F(n-1) + F(n-2), se n > 1.

n
: 0 1 2 3 4 5 6 7 8 9
F(n): 0 1 1 2 3 5 8 13 21 34

Programao Dinmica
Exemplo: Sequncia de Fibonacci
Soluo recursiva:
F(n)

IF n 1
return n
// F(0) = 0 e F(1) = 1
ELSE
return F(n 1) + F(n 2)
Nmero de chamadas recursivas para calcular F(5) ou F(10)?

Programao Dinmica: F(5)

Programao Dinmica: F(10)


F(7)
F(8)

F(6)
F(9)
F(6)
F(7)
F(5)

F(4)

F(10)
F(6)

F(7)
F(5)
F(8)

F(5)
F(6)
F(4)

F(3)

Programao Dinmica
Sequncia de Fibonacci
Custo da soluo recursiva:
Quantas vezes cada F(k) calculado?
Para k entre 1 e n?

Com Programao Dinmica


Calcular cada subproblema uma vez e armazenar o
resultado.
Recuperar esta informao toda vez que o
subproblema for considerado.
Ou seja, calcula F(7), F(6), F(5) uma nica vez.

Programao Dinmica
Sequncia de Fibonacci
Com Programao Dinmica
F(1)
F(2)
F(4)
F(5)
F(6)
F(7)
F(8)

F(9)
F(10)

F(3)
F(0).
F(1).
F(2).

F(3).
F(4).

F(5).

F(6).
F(7).

F(8).

F(0) F(1) F(2) F(3) F(4)


0

Programao Dinmica
Esse paradigma pode ser definido "recurso com
apoio de uma tabela".

Em geral utilizado para resolver dois tipos de


problemas:
Otimizao
Contagem

A soluo eficiente est baseada no princpio da


subestrutura tima:
Em uma sequncia tima de escolhas ou de decises,
cada subsequncia deve tambm ser tima.

Programao Dinmica
Exemplo do princpio da otimalidade
(subestrutura tima):
Suponha que o caminho mais curto entre Belo
Horizonte e Curitiba passa por Campinas.
Podemos concluir que:
o caminho entre BH e Campinas utilizado tambm o
mais curto possvel;
como tambm o caminho entre Campinas e Curitiba.
Logo, o princpio da otimalidade se aplica.

Programao Dinmica
Quando aplicar PD?
Problema computacional de formulao recursiva.
No deve haver ciclos na formulao
PD apresenta subestrutura tima:
Soluo tima do problema -> solues timas dos
subproblemas.

Sobreposio de subproblemas:
Nmero total de sub-problemas distintos pequeno

Programao Dinmica
Estrututa base do algoritmo de PD
1. Caracterizar/Identificar a estrutura de uma
soluo tima
2. Definir Recursivamente o valor de uma soluo
tima
3. Calcular o valor de uma soluo tima em um
processo bottom-up
4. Contruir uma soluo tima a partir das
informaes calculadas.

Programao Dinmica
Nas prximas aulas
Alguns exemplos de problemas que se resolvem
com Programao Dinmica:
1.
2.
3.
4.
5.
6.
7.

Problema da Mochila 0-1 (knapsack problem)


Soma de subconjuntos (subset sum)
Troco de moedas (coin change)
Multiplicao tima de matrizes
Caixeiro viajante
Conjunto independente mximo em rvores
Subsequencia comum mais longa

Programao Dinmica
Exemplo: Mochila 0-1 ou binria
Mochila de capacidade : W
Dados n itens de:
Valores : v
Pesos : p

Descobrir um subconjunto de itens cujos pesos


somam at W de forma que a mochila tenha o
valor mximo.

Programao Dinmica

Problema: Mochila 0-1


Instncia
n=4
W=5

p
v

1
4
50

2
2
40

3
1
30

4
3
45

O que podemos pensar se for possvel colocar na mochila parte de um item?

Soluo Gulosa

12,5

20

30

15

Os itens 3 e 2 seriam escolhidos. Peso total 1+2=3. No caberia mais itens.


Valor total = 70 e sobra espao um espao igual a 5-3=2.
Poderia pegar um outro item e ter mais de 70?

Programao Dinmica
Mochila 0-1: soluo por PD etapa 1
A idia guardar em uma tabela, digamos t, as
solues das (sub)instncias do problema. A tabela
definida assim:
Para i = 0,1,,n (itens) -> linhas
Para w = 0,1,,W (pesos) -> colunas

t[i,w] = valor timo de uma soluo da instncia


(p1,,pi, v1,,vi, w) do problema
se calcularmos todas as entradas dessa matriz, a
entrada t[n,W] vai conter a resposta do problema
original

Programao Dinmica
Mochila 0-1: soluo por PD etapa 2
Recurso:
Casos base:

Passo recursivo:

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Passo-a-passo

1
4
50

p
v

2
2
40

3
1
30

Caso base: nenhum item sendo considerado


Itens / Pesos
0
0
1
0
2
0
3
0
4
0

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Passo-a-passo

1
4
50

p
v

2
2
40

Considerando at o item 1
Itens / Pesos
0
0
1
0
2
0
3
0
4
0

0
0

0
0

0
0

0 0
50 50

3
1
30

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Passo-a-passo

1
4
50

p
v

2
2
40

Considerando at o item 2
Itens / Pesos
0
0
1
0
2
0
3
0
4
0

0
0
0

0
0
40

0
0
40

0 0
50 50
50 50

3
1
30

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Passo-a-passo

1
4
50

p
v

2
2
40

Considerando at o item 3
Itens / Pesos
0
0
1
0
2
0
3
0
4
0

0
0
0
30

0
0
40
40

0
0
40
70

0 0
50 50
50 50
70 80

3
1
30

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Passo-a-passo

1
4
50

p
v

2
2
40

Considerando at o item 4
Itens / Pesos
0
0
1
0
2
0
3
0
4
0

0
0
0
30
30

0
0
40
40
40

0
0
40
70
70

0
50
50
70
75

0
50
50
80
85

3
1
30

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD etapa 3
Instncia
n=4
W=5

p
v

1
4
50

2
2
40

i\w 0
1
2
3
4
5
0
0
0
0
0
0
0
1
0
0
0
0 50 50
2
0
0 40 40 50 50
3
0 30 40 70 70 80
4
0 30 40 70 75 85

3
1
30

4
3
45

Programao Dinmica
Mochila 0-1: soluo por PD algoritmo

Programao Dinmica
Mochila 0-1: soluo por PD algoritmo
Soluo final

p
v

1
4
50

2
2
40

i\w 0
1
2
3
4
5
0
0
0
0
0
0
0
1
0
0
0
0 50 50
2
0
0 40 40 50 50
3
0 30 40 70 70 80
4
0 30 40 70 75 85

3
1
30

4
3
45

Programao Dinmica
Exerccios (para a prxima aula):
A partir das soluo por programao dinmica do
Problema da Mochila 0-1, defina solues de PD para os
dois problemas abaixo:
1. Make-change problem: dados um inteiro k e um conjunto
S = {d1, d2, , dn} de n inteiros, qual o tamanho do menor
subconjunto de S cuja soma de seus elementos seja igual
a k?
2. Subset sum problem: dados um inteiro k e um conjunto S
= {d1, d2, , dn} de n inteiros, existe um subconjunto de S
cuja soma de seus elementos seja igual a k?

Dica: pense na relao entre esses dois problemas e


tambm na relao deles com o problema da mochila.

Programao Dinmica: subset sum


Estrutura de uma soluo tima:
C[i, j] = true se existe um subconjunto dos elementos
de 1 at i de S cuja soma seja igual a j. false caso
contrrio. Assim, T[n, k] a resposta do problema.

Recorrncia:
C[i, j] = C[i - 1, j di] or C[i - 1, j]);
Casos base:
C[i, j] = true, se j = 0
C[i, j] = false, se i = 0 e j > 0

Programao Dinmica
Subsequncia comum mais longa (LCS)
Definies bsicas:
X = <x1, x2, ..., xm>, Y = <y1, y2, ..., yn> e Z = <z1, z2, ..., zk>
Z uma subsequncia de X se existe uma sequncia
estritamente crescente <i1, i2, ..., ik> de ndices de de X tais
que xij = zj, para j=1, 2, ..., k
Exemplo: Z = <B, C, D, B> subsequncia de X = <A, B, C, B, D, A,
B> com sequncia de ndices <2, 3, 5, 7>

Z uma subsequncia comum de X e Y se Z uma


subsequncia de X e de Y ao mesmo tempo
Exemplo: X = <A, B, C, B, D, A, B> e Y = <B, D, C, A, B, A>
<B, C, A> subsequncia comum de X e Y: mas no LCS!!!
<B, C, B, A> uma LCS de X e Y: <B, D, A, B> tambm !

Programao Dinmica
Subsequncia comum mais longa (LCS)
O problema
Entrada: As sequncias
X = <x1, x2, ..., xm> e Y = <y1, y2, ..., yn>
Sada: Uma subsequncia comum de X e Y, cujo
comprimento seja mximo

Soluo fora bruta


Enumerar todas as possveis subsequncias de X
Para cada, verificar se subsequncia tambm de Y
Soluo: a de maior tamanho

Existem 2m subsequncias possveis de X


Algoritmo ineficiente (complexidade exponencial)

Programao Dinmica
Subsequncia comum mais longa (LCS)
Etapa 1: Caracterizao de uma LCS
Dada uma sequncia X = <x1, x2, ..., xm>

i-simo prefixo de X definido por Xi = <x1, x2, ..., xi>, para im


Ex: X = <A, B, C, B, D, A, B>
X0 a sequncia vazia
X3 = <A, B, C>
X5 = <A, B, C, B, D>

Subestrutura tima de uma LCS: sejam as sequncias X = <x1,


x2, ..., xm> e Y = <y1, y2, ..., yn>, e seja Z = < z1, z2, ..., zk> uma
LCS de X e Y.
1. Se xm = yn, ento zk = xm = yn e Zk-1 uma LCS de Xm-1 e Yn-1;
2. Se xm yn, ento zk xm implica que Z uma LCS de Xm-1 e Y;
3. Se xm yn, ento zk yn implica que Z uma LCS de X e Yn-1.

Programao Dinmica
Subsequncia comum mais longa (LCS)
Etapa 2: Uma soluo recursiva
1 caso: Se xm = yn, ento deve ser encontrada
uma LCS de Xm-1 e Yn-1
Concatenando xm (ou yn) nessa LCS obtm-se a LCS
de X e Y

2 caso: Se xm yn, ento h dois subproblemas


a resolver:
1. Encontrar LCS de Xm-1 e Y
2. Encontrar LCS de X e Yn-1
... a maior dentre essas duas LCS uma LCS de X e Y

Programao Dinmica
Subsequncia comum mais longa (LCS)
Etapa 3: Como calcular o comprimento de uma LCS

i
0

xi

yj

Programao Dinmica
Subsequncia comum mais longa (LCS)
Etapa 3: Como calcular o comprimento de uma LCS

Programao Dinmica
Subsequncia comum mais longa (LCS)
Etapa 4: A construo de uma LCS

Referncias
[CLRS] Algoritmos: Teoria e Prtica, 3ed.
Cormen, 2012.
Algorithms in C++, Sedgewick.