Você está na página 1de 15

Aula 17 – Problema da Mochila

25089/1001525 – Projeto e Análise de Algoritmos


2019/2 - Turma A
Prof. Dr. Murilo Naldi

naldi@dc.ufscar.br
Agradecimentos


Aos professores Mário Felice e Diego Furtado por ceder
parte do material utilizado.

Material inspirado nas aulas do prof. Tim Roughgarden
Princípios da Programação Dinâmica


Os princípios básicos para projetar um algoritmo de programação
dinâmica são:
1) encontrar um número pequeno de subproblemas
2) encontrar uma maneira (em geral, uma recorrência) que
permita resolver um problema maior usando as soluções de
problemas menores
– essa maneira deve ser correta (claro)
– e rápida (recorrência deve depender de um número polinomial
de termos)
3) depois de calcular os subproblemas, encontrar a solução final
deve ser fácil
– um valor da tabela (normalmente a última posição)
Princípios da Programação Dinâmica


Observe que para poder aplicar esses princípios
é necessário que o problema apresente a
propriedade de subestrutura ótima, ou seja, que
uma solução ótima para uma determinada
instância possa ser descrita em função de
soluções ótimas para sub-instâncias da mesma.
Problema da Mochila

Entrada:
– n itens, sendo que cada item i (1<=i<=n) tem
● valor vi > 0
● peso wi > 0 e inteiro
– capacidade W > 0 e inteiro

Solução:
– subconjunto S de itens que
– maximiza
∑ v i (tem lucro máximo)
i∈S

∑ w i≤W (e não viola a capacidade)
i∈S
Problema da Mochila


Vamos usar I(n, W) para denotar uma entrada para o
problema da mochila que tem:
– n itens
– capacidade W
– deixamos implícito que cada item tem valor vi e
peso wi, para 1 <= i <= n.
Subestrutura ótima em de recorrência


Considere uma entrada I(n, W) e uma
correspondente solução ótima S

Vamos focar nossa atenção no item n (último).
Temos duas possibilidades:
1) n não está em S
2) n está em S
Primeiro Caso

Vamos analisar 1) primeiro
– Neste caso S é uma solução ótima para I(n-1, W), ou seja,
para a mochila de mesma capacidade que só pode usar os
n-1 primeiros itens.
– Prova: que S é uma solução para I(n-1, W) é direto, já que
não usa o item n e respeita a capacidade W. Para mostrar
que é ótima para I(n-1, W) vamos supor, por contradição,
que existe uma solução S* melhor que S para I(n-1, W).
Note que S* também é uma solução para I(n, W), já que ela
respeita a capacidade W e só usa itens válidos para esta
entrada. Como o valor de S* é maior que S, chegamos a
uma contradição, já que S era ótima para I(n, W).

Qual o valor da solução ótima S em função da solução ótima
dos subproblemas neste caso?
Segundo Caso


Neste caso n está em S. Queremos descrever S em
função de soluções ótimas para subproblemas, vamos
considerar a solução S' = S \ {n}, ou seja, S sem o último
item. Novamente, temos que S' é uma solução que só usa
os n-1 primeiros itens, mas algo mais acontece neste
caso. Como S respeitava a capacidade W, i.e.,

∑ wi≤W
i∈S
– ao remover o item n de S temos que S' respeita uma
restrição mais forte

∑ w i=∑ w i−w n≤W −w n


i∈S ' i∈S
Segundo Caso

● Portanto, S' é uma solução ótima para I(n-1, W - wn), ou seja,


para a mochila de capacidade W - wn que só pode usar os n-1
primeiros itens.
– Prova: que S' é uma solução para I(n-1, W - wn) é direto, já
que ela não usa o item n e respeita a capacidade W - w n.
Para mostrar que ela é ótima para I(n-1, W - wn) vamos
supor, por contradição, que existe uma solução S* melhor
que S' para I(n-1, W - wn). Note que S* U {n} é uma solução
para I(n, W), já que ela respeita a capacidade W e só usa
itens válidos para esta entrada. Como o valor de S* + v n é
maior que S' + vn = S, chegamos a uma contradição, já que
S era ótima para I(n, W).
– Qual o valor da solução ótima S em função da solução
ótima dos subproblemas neste caso?
Recorrência


Como nossos subproblemas dependem:
– tanto dos itens que podem ser usados na solução
quanto da capacidade residual da mochila


Nossa recorrência terá dois parâmetros i e x

A[i, x] corresponde ao valor de uma solução ótima
para uma mochila que:
– pode ser preenchida com os i primeiros itens
(i = 1, ..., n)
– e tem capacidade x (x = 1, ..., W)
Recorrência


Seguindo nossa análise da subestrutura ótima,
temos a seguinte recorrência
– A[i, x] = max{A[i-1, x], A[i-1, x - wi] + vi}
– Observe que esta recorrência tem uma limitação
● o segundo caso não faz sentido quando wi > x,
já que a capacidade da mochila fica negativa
– Além disso, os casos bases da recorrência
ocorrem quando o número de itens disponível é 0

neste caso a mochila sempre terá valor 0,
independente da capacidade
Algoritmo a partir da recorrência

mochila(n, v, w, W) {
para x = 0 até W
A[0, x] = 0
para i = 1 até n
para x = 0 até W
A[i, x] = max{A[i-1, x], A[i-1, x - wi] + vi}
// tem uma incorreção aqui
devolva A[n, W]
}
Algoritmo a partir da recorrência

mochila(n, v, w, W) {
para x = 0 até W
A[0, x] = 0
para i = 1 até n
para x = 0 até W
se x < wi
A[i, x] = A[i-1, x]
senão
A[i, x] = max{A[i-1, x], A[i-1, x - w i] + vi}
devolva A[n, W]
}
Corretude e eficiência


Prova de corretude: Por indução matemática usando
como hipótese a recorrência que demonstramos antes

Eficiência: Θ(nW), o que faz deste algoritmo
pseudopolinomial, já que o número W pode crescer como
uma exponencial no tamanho da entrada.

Você também pode gostar