Problema da mochila 0-1
Curso de Maratona de ProgramaçãoICT-Unifesp – SJC
Paradigmas• Guloso
• Realiza a escolha que parece ser a melhor no momento, ou seja, faz uma escolha ótima local na esperança de que escolha leve até a solução ótima global.
• Será que sempre garante chegar a uma solução ótima global?• Curiosidade: o algoritmo Dijkstra é guloso... (só guloso ??)
Paradigmas• Backtracking
• Refinamento de busca por força bruta!• Várias soluções podem ser eliminadas sem serem explicitamente examinadas.
Programação dinâmica• Vários algoritmos eficientes utilizam esse paradigma.• O termo “programação” significa planejamento.• Estrutura recursiva:
• A solução de qualquer instância deve conter soluções de subinstâncias da instância.• Representação por uma recorrência (algoritmo recursivo).• O algoritmo recursivo é normalmente ineficiente porque refaz cálculos.• Temos que construir uma tabela para memorizar os resultados de soluções de
subinstâncias (subproblemas) para evitar o recálculo!
Programação dinâmica• Decomposição do problema em subproblemas.• Pense na solução para cada subproblema.• Subproblemas sobrepostos: resolve um determinado subproblema e mais a
frente precisa do resultado daquele subproblema que já foi resolvido.• Reutilização das soluções (eficiência): podemos sair de um problema
exponencial para polinomial...• Otimalidade: solução ótima é composta de soluções ótimas dos subproblemas• O Dijkstra é só guloso? Não, é uma combinação de guloso e PD!
• Discussão: http://codeforces.com/blog/entry/20503
Programação dinâmica• Hello World – não adianta, sempre Fibonacci estará presente!• Normalmente o cálculo de Fibonacci é feito da seguinte forma:
• Isso é eficiente?
Programação dinâmica• fib(6)
6
5 4
4 3 3 2
Ineficiente, já calculou o fib(3)... vai calcular novamente?
Programação dinâmica• fib(6)
6
5 4
4 3 3 2
Temos repetições de subproblemas...
Programação dinâmica• fib(6)
6
5 4
4 3 3 2
A abordagem é exponencial
Programação dinâmica• fib(6)
6
5 4
4 3 3 2
Se os subproblemas se repetem, basta guardar osresultados dos problemas já resolvidos!
Programação dinâmica• Como usar PD? Basta fazer uma memorização dos resultados:
memorizando o resultado...
já calculei?
Programação dinâmica• Como usar PD? Basta fazer uma memorização dos resultados:
Transformamos algo exponencial em linear.
Programação dinâmica• Essa é uma abordagem top-down , ou seja, tentamos calcular o fib(n)
antes de todo mundo...
Programação dinâmica• Abordagem bottom-up:
• Removemos a chamada recursiva, criamos um array para guardar os resultados e fomos construindo de trás para frente!
Problema da mochila 0-1• Digamos que você possui objetos onde cada objeto possui um peso e valor.• Digamos que você também possui uma mochila que possui uma capacidade
máxima (peso máximo suportado).• Seu objetivo é: levar um conjunto de objetos cujo valor total seja máximo e o
peso total não ultrapasse a capacidade da mochila.• Resumindo: você quer maximizar o valor de forma que não ultrapasse a
capacidade máxima da mochila.
Problema da mochila 0-1• Objetos: X1, X2, ... , Xn• Valores: V1, V2, ... , Vn• Pesos: P1, P2, ... , Pn• Peso máximo da mochila: P• Qual aplicação disso?
• Maximizar o lucro...• Maximizar a quantidade de brinquedos...• Maximizar a felicidade...
Problema da mochila 0-1• Trata-se de um problema difícil, vários refinamentos foram feitos até se chegar
a uma solução legal... Don’t panic!• Como encontrar uma composição de objetos que maximize o valor
respeitando a restrição da capacidade máxima da mochila?• Uma abordagem: guloso.
Problema da mochila 0-1• Utilizando abordagem gulosa:
• Ordena os objetos pelo valor máximo e vai pegando cada objeto se não ultrapassar a capacidade máxima da mochila.
• Também pode-se ordenar pelo (valor / peso)...• Garante chegar a solução ótima global?
• De acordo com a estratégia gulosa de pegar pelo maior valor, colocaria o item X3 (maior valor), mas não poderia colocar nenhum item a mais. Uma solução melhor é pegar os itens X1 e X2 totalizando o valor 35 (> 30).
Capacidade: 20 X1 X2 X3
Pi 10 10 20
Vi 15 20 30
Problema da mochila 0-1• Por que 0-1 ? Ou o objeto está ou não está na mochila.• Estratégia gulosa pode garantir uma boa aproximação, mas não garante a
solução ótima global. Vamos tentar por programação dinâmica...• Temos que reduzir o problema, chegarmos a uma solução recursiva.• Com a redução do problema, teremos subproblemas.• Resolve os subproblemas (cálculos menores)...• Faz-se uma observação e...• É difícil esboçar um algoritmo!
20
Problema da mochila 0-1• Qual a observação?
“O objeto Xn pode está ou não está na solução ótima.”
21
Problema da mochila 0-1• Se um objeto Xn está na mochila, então a composição ótima da mochila é esse
objeto mais os demais descontando o peso desse objeto!• Considere P (capacidade da mochila) = 20.• Pn = 8 (peso do objeto “n”).• A mochila terá (Xn + (n – 1)) objetos cujo peso máximo é 12 (descontou peso do objeto).• É como se tivesse compondo uma outra mochila...
• Se o objeto não está na solução ótima, então a solução ótima é a mochila com peso original composta pelos (n – 1) elementos.• Compara-se o máximo desses dois casos, queremos maximizar...
22
Problema da mochila 0-1• Se Xn pertence à solução, então o valor dessa solução será:
• Vn + (valor de uma solução ótima com uma mochila de capacidade P – Pn) considerando os (n – 1) primeiros itens.
• Como descrevemos isso?• Como transformar numa solução?
23
Problema da mochila 0-1• Temos os parâmetros:
• Conjuto dos objetos• Peso da mochila
• Como captar esses parâmetros?• f(i, p) -> valor ótimo considerando os “i” primeiros itens e uma mochila de
capacidade p.f(i, p)
objetos que estou considerando,os “i” primeiros objetos
p é p peso que a mochila suporta
24
Problema da mochila 0-1• Se Xn está na solução ótima:
• f(n – 1, p – pn) + Vn• (n – 1) -> considera agora somente os “n – 1” primeiros itens.• (p – pn) -> desconta o peso (pn) do objeto “n”. “p” é a capacidade da mochila.• Se o objeto “n” está na solução ótima, ele leva o valor dele, por isso o “+ Vn”.
• Se Xn não está na solução ótima:• f(n – 1, p)• (n – 1) -> considera agora somente os “n – 1” primeiros itens.• p -> não desconta o peso dele, pois ele não está na solução ótima...
• Resolva fazendo o máximo (max) desses dois casos...
25
Problema da mochila 0-1• O objetivo é o cálculo do f(n), ou seja, para “n” objetos.• Iremos resolver de baixo para cima (bottom-up).• Calculando valores pequenos e aumentando os valores da função “f” até
chegar no f(n, p).
26
Problema da mochila 0-1• Recorrência:
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
• f(i, p) = f(i – 1, p) se pi > p• O i-ésimo item cabe na mochila? Se pi > p, então ele não cabe na mochila, esqueça ele e
olhe para os “i – 1” primeiros itens.
• f(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p• Se pi <= p, calcula-se o máximo dos 2 casos: está ou não na mochila?• O primeiro considera o item na mochila e o segundo não considera o item na mochila.
27
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
28
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
f(0, p) = f(i, 0) = 00 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0
2 0
3 0
4 0
i
29
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
Vamos calcular o f(1, 1): 1 item e mochila de peso 1
0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 ?
2 0
3 0
4 0
i
30
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
P1 > P? 2 > 1? Sim, então não cabe, resposta: f(i – 1, 1) = f(1 – 1, 1) = f(0, 1) = 0 0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 ?
2 0
3 0
4 0
i
31
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
Vamos calcular o f(1, 2): 1 item e mochila de peso 20 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 0 ?
2 0
3 0
4 0
i
32
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
P1 > P ? 2 > 2 ? Não, então vamos calcular o max ...0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 0 ?
2 0
3 0
4 0
i
33
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
f(i – 1, p – pi) + vi = f(0, 0) + 10 = 0 + 10 = 100 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 0 ?
2 0
3 0
4 0
i
34
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
e f(i – 1, p) = f(0, 2) = 00 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 0 ?
2 0
3 0
4 0
i
35
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
max(10, 0) = 100 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0 0
1 0 0 10
2 0
3 0
4 0
i
36
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
depois de implementar e olhar o resultado da matriz...0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
37
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
f(4, 7) é o valor máximo0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
38
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
P4 > P ? 5 > 7 ? Não, então vamos calcular o max ...0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
39
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
f(3, 2) + v4 = 10 + 24 = 340 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
40
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
f(3, 7) = 320 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
41
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
max( f(3, 2) + 24 ; f(3, 7) ) = max(34, 32) = 340 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 ?
i
42
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
34 é o valor máximo!0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 34
i
43
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
Qual a composição? Guarde os apontadores 0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 34
i
44
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
De onde o 34 veio? Do f(3, 2), então o X4 faz parte da solução.0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 34
i
45
Problema da mochila 0-1P: 7 X1 X2 X3 X4
Vi 10 7 25 24Pi 2 1 6 5
f(i, p) = f(i – 1, p) se pi > pf(i, p) = max{ f(i – 1, p – pi) + vi, f(i – 1, p) } se pi <= p
De onde veio f(1, 2) ? Veio do f(0, 0) + 10, então o X1 faz parte da solução.0 1 2 3 4 5 6 7 P
0 0 0 0 0 0 0 0 0
1 0 0 10 10 10 10 10 10
2 0 7 10 17 17 17 17 17
3 0 7 10 17 17 17 25 32
4 0 7 10 17 17 24 31 34
i
Problema da mochila 0-1• Complexidade: O(n * P)
• “n” é a quantidade de itens.• “P” é a capacidade máxima da mochila.• Depende do “P”, portanto, é pseudo-polinomial.
Problema da mochila 0-1• Implementação em C++:
• https://goo.gl/87o8U9
• Vídeo-aula:• https://goo.gl/9syeQP
• Dúvidas?• [email protected]
Top Related