jazzpeh

0/1 Knapsack Problem

Jazz Peh, April 30, 2020

Given the weights and profits of N items, we are asked to put these items in a knapsack which as a capacity C. Restriction is, we cannot break the item into smaller units (fractional unit is not allowed). Find the maximum profit from the items in the knapsack.

Example
-----------
items: ["Mango", "Apple", "Banana", "Orange"]
profits: [31, 26, 72, 17]
weights: [3, 1, 5, 2]
capacity: 7
output: 98
Explanation: Apple + Banana (total weight = 6) => 98 profit

Solution

This problem can be solved by applying Divide and Conquer to break down the problem into smaller subproblems. Thus, by solving these subproblems, we will arrive at our final answer. Let’s try to derive the subproblems.

1. We take the first item: 31 + f([2,3,4], weight=3)  --|-- max
2. We skip the first item: 0 + f([2,3,4], weight=0)   --|

To achieve optimal substructure, we assume that at every step, we would take the first item or we skip it. Hence, if we take the first time, we add on the profit and also run a recursive function and pass in the remaining items and the weight that this item takes and hence 31 + f([2,3,4], weight=3). If we skip the first item, we then run a recursive function, pass in the remaining items and since we skip the item, the weight is 0 and therefore 0 + f([2,3,4], weight=0). By getting the max value of these 2 subproblems, we would then derive at our final answer.

Code Algortihm

function knapsack(profits: number[], weights: number[], capacity: number, index: number): number {
  if (index > profits.length - 1 || capacity === 0) return 0;

  let profit1 = 0;
  if (weights[index] <= capacity) {
    profit1 = profits[index] + knapsack(profits, weights, capacity - weights[index], index + 1);
  }

  const profit2 = knapsack(profits, weights, capacity, index + 1);

  return Math.max(profit1, profit2);
}

Optimisation

Let’s look at the an example of the recursion tree see if we need to optimise this solution.

                        knapsack(7, 0)
                  /                       \
            knapsack(4,1)               knapsack(7,1)
            /          \               /             \
    knapsack(3,1)  knapsack(4,2)   knapsack(6,2)   knapsack(7,2)
    /          \
base       knapsack(3,3)

Since there are no recurrences of any computation, we don’t have to but still can apply Dynamic Programming to optimise the solution.


Explore more like this

© 2020 Jazz Peh, Built with Gatsby