Knapsack Chain Multiply
::
2025-01-15Using the Dynamic Programming approach to solve knapsack and chain multiply problems
Summary
When attempting to solve problems via dynamic programming, it is often useful to first try solving a subproblem that is a prefix of the main problem. If that doesn’t work, you can try a substring.
Contents
Knapsack Problem
Input
: n objects with a weight
and a value
, and a total capacity.
Goal
: Find a subset of objects that fit in the knapsack and maximizes the
total value
There are two versions:
- One copy of each object
- “without repitition”
- Unlimited copy of each object
- “with repitition”
Without Repition
A greedy approach often fails, so we need to maintain sub-optimal solutions along the way
Attempt 1
- K(i) = max value achievable using a subset of objects 1 through i
- Express K(i) in terms of K(1) through K(i-1)
Given:
The solution doesn’t depend on the solution. We need to maintain a sub-optimal solution for . We need to maintain . This meains we need to change the subproblem definition to say we are including object i.
Attempt 2
- a max value achievable using a subset of objects 1 through i and a total weight of b
- Express K(i) in terms of K(1) through K(i-1)
if :
That is to say, if either we include the current object and use the value of the previous best solution that has enough capacity to include the object, or we don’t include the object and use the previous best value.
Knapsack(W,V,B):
for b in range(0,B):
K[0][b] = 0
for i in range(0,N):
K[i][0] = 0
for i in range(0,N):
for b = in range(1,B):
if W[i] <= b:
K[i][b] = max(V[i] + K[i-1][b-W[i]], K[i-1][b])
else:
K[i][b] = K[i-1][b]
return K[n][B]
Total runtime is O(nB)
With Repition
- a max value achievable using a multiset of objects 1 through i and a total weight of b
- Express K(i) in terms of K(1) through K(i-1)
Similar psuedocode
Simpler Subproblem
Do we need parameter i?
max value attainable using weight less than or equal to b
KnapsackRepeat(W,V,B):
for b in range(0,B):
K[b] = 0
for i in range(0,n):
if W[i] <= b && K[b] < V[i] + K[b-W[i]]:
K[b] = V[i] + K[b-W[i]]
return K[B]
Runtime is still O(nB), but space is smaller and algo is simpler
Chain Matrix Multiply
Example
: 4 matrices, A, B, C, D
Goal
: Computer most efficiently
Which is better? What is the cost?
If a matrix W has size axb and Y a size of bxc, then WxY has a cost of abc
Input
: N matrices
Goal
: What’s the min cost for computing
Graphical View
Attempt 1
We can’t simply use a prefix because some computations are a substring (like )
Substrings
Psuedocode
NOTE
This might be wrong
ChainMultiply(M):
for i in range(0,n):
C[i][i] = 0
# Compute diagonally
for s in range(1, n-1):
for i in range(1, n-s):
j = i+1
C[i][j] = INF
for l in range(i, j-1):
cur = M[i-1] * M[l] * M[j] + C[i][l] + C[l+1][j]
if C[i][j] > cur:
C[i][j] = cur
return C[0][n]
Runtime is
Practice Problems
Try prefix, then substring.
If you do use substring, go back over the recurrence to see all parameters are needed.