Solution: The 0/1 Knapsack Problem
This review provides a detailed analysis of the different ways to solve The Knapsack Problem
We'll cover the following...
Solution #1: Brute Force
#include <iostream>using namespace std;// Returns the maximum value that can be put in a knapsack of capacity Wint knapsackRecursive(int profits[], int profitsLength, int weights[], int capacity, int currentIndex) {// Base Caseif (capacity <= 0 || currentIndex >= profitsLength || currentIndex < 0)return 0;// If weight of the nth item is more than Knapsack capacity W, then// this item cannot be included in the optimal solutionint profit1 = 0;if (weights[currentIndex] <= capacity)profit1 = profits[currentIndex] + knapsackRecursive(profits, profitsLength, weights, capacity - weights[currentIndex], currentIndex + 1);int profit2 = knapsackRecursive(profits, profitsLength, weights, capacity, currentIndex + 1);// Return the maximum of two cases:// (1) nth item included// (2) not includedreturn max(profit1, profit2);}int knapSack(int profits[], int profitsLength, int weights[], int capacity) {return knapsackRecursive(profits, profitsLength, weights, capacity, 0);}int main() {int profits[] = {1, 6, 10, 16}; // The values of the jewelryint weights[] = {1, 2, 3, 5}; // The weight of eachcout << "Total knapsack profit = " << knapSack(profits, 4, weights, 7) << endl;cout << "Total knapsack profit = " << knapSack(profits, 4, weights, 6) << endl;}
We start from the beginning of the weight
array and check if the item is within the maximum capacity as done on line 14. If it is, we call the knapsack()
function recursively with the item and save the result in profit1
.
Then we call the function recursively excluding the item, and saving the result in the variable, profit2
. Out of the two, we return the result that is greater (as done on line 21).
Pseudocode
for each item 'i' starting from the end
create a new set which INCLUDES item 'i' if the total weight does not exceed the capacity, and recursively process the remaining capacity and items
create a new set WITHOUT item 'i', and recursively process the remaining items
return the set from the above two sets with higher profit
Let’s draw the recursive calls to see if there are any overlapping sub-problems. As we can see, in each recursive call, the profits and weights arrays remain constant, and only the capacity and the current index change. For simplicity, let’s denote capacity with C
and current index with n
:
Time Complexity
The time complexity of the algorithm above is —i.e., exponential—where is the total number of items. This is because we will have that many calls. The logic is similar to the one presented in the ... ...