The 0-1 knapsack programming problem is as below: Given. a) A finite collection of weights with values. b) An empty knapsack with a limited weight capacity. The goal is to maximize the value of the knapsack by adding chosen weights that the knapsack can hold.
Example: Say we have a knapsack of capacity 5 kg. And we have a set of available items with their weights and corresponding values: [ 1 kg - $3 ], [ 2 kg - $5 ], [ 3 kg - $4 ], [ 4 kg - $8 ] and [ 5 kg - $10 ]
Thus the set of available items/weights is :
| Item | Weight | Value |
|---|---|---|
| 1. | 1 kg | $ 3 |
| 2. | 2 kg | $ 5 |
| 3. | 3 kg | $ 4 |
| 4. | 4 kg | $ 8 |
| 5. | 5 kg | $ 10 |
We can see that adding weights 1 kg (value $ 3) and 4 kg (value $ 8) to the knapsack gives it maximum value of $ 11.
Recurrence relation for the 0-1 knapsack
Base cases:
Dynamic programming approach for 0-1 knapsack
Base case values for 0-1 knapsack
| Knapsack Capacity 0 kg | Items | Value of knapsack | Hint |
|---|---|---|---|
| 0 kg | 0 kg, 1 kg, …, 5 kg | $0 | The knapsack of capacity 0 kg cannot hold any item. |
| Knapsack Capacity 5 kg | Items with weight 0 kg | Value of knapsack | Hint |
|---|---|---|---|
| 1 kg | 0 kg | $0 | Item of weight 0 kg does not add any value to the knapsack. |
| ……… | 0 kg | $0 | Item of weight 0 kg does not add any value to the knapsack. |
| 5 kg | 0 kg | $0 | Item of weight 0 kg does not add any value to the knapsack. |
Note: A weight of 0 kg of value $ 0 is added to the DP table for handling the base cases.
Filling the values in the dynamic programming table of 0-1 Knapsack using recurrence.
Recurrence equation for 0-1 Knapsack 0-1 Knapsack (numitems, capacity) = Max ( 0-1 Knapsack (numitems - 1, capacity) or 0-1 Knapsack (numitems - 1, capacity - weight [ numitems -1 ]) + value [ numitems-1 ] ) )
Example: Consider filling the knapsack of capacity 5 kg with items of weight 0 kg ( $ 0 ), 1 kg ( $ 3 ), 2 kg ( $ 5 ), 3 kg ( $ 4 ) and 4 kg ( $ 8 ). i.e Filling value in table [4] [5]
The maximum value of the knapsack of capacity 5 kg = maximum of ( value of knapsack using weights (0 kg, 1 kg, 2 kg, 3 kg ) or value of knapsack when a weight of 4 kg is chosen along with any of the chosen weights from ( 0 kg, 1 kg, 2 kg, 3 kg)
From the table,
Thus, we get table [ 4 ] [ 5 ] = max ( table [ 3 ] [ 5 ] or table [ 3 ] [ 5 - 4 ] + value of weight [ 4 kg ] ) i.e table [ 4 ] [ 5 ] = max ( $ 9 or $ 3 + $ 8 ) i.e the maximum Value of knapsack of capacity 5 kg = maximum of ( $9, $3 + $8) = $11.
Time complexity : O ( n * m ), where n is the capacity of the knapsack and m is the number of weights available for putting into the knapsack.
Implementation of 0-1 knapsack problem
from typing import List # For annotations
# Recursive approach to 0-1 Knapsack problem
def Knapsack (numitems : int, capacity : List[int], weight : List[int], value : List[int]) -> int :
# No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
if ( capacity == 0 ) :
return 0
# If 0 items are put in the sack, then maximum value for sack is 0
if ( numitems == 0 ) :
return 0
# Note : Here the number of item is limited (unlike coin change / integer partition problem)
# hence the numitems -> (numitems - 1) when the item is included in the knapsack
if ( capacity >= weight[numitems-1] ) :
return max ( Knapsack (numitems-1, capacity, weight, value), # Item is not included.
Knapsack (numitems-1, capacity-weight[numitems-1], weight, value) + value[numitems-1] )# Item included.
else:
return Knapsack (numitems-1, capacity, weight, value)
# DP approach to 0-1 Knapsack problem
def DPKnapsack (capacity : List[int], weight : List[int], value : List[int]) -> int :
numitems = len(weight)
maxval = [0] * ( numitems + 1 )
for r in range ( numitems + 1 ) :
maxval[r] = [0] * ( capacity + 1 )
# If 0 items are put in the sack of capacity 'cap' then maximum value for each sack is 0
for cap in range ( capacity + 1 ) :
maxval[0][cap] = 0
# No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
for item in range ( numitems + 1 ) :
maxval[item][0] = 0
# Note : Here the number of item is limited (unlike coin change / integer partition problem)
# hence the numitems -> (numitems - 1) when the item is included in the knapsack
for item in range ( 1, numitems + 1 ) :
for cap in range ( 1, capacity + 1 ) :
if ( cap >= weight[item-1] ) :
maxval[item][cap] = max (maxval[item-1][cap], maxval[item-1][cap-weight[item-1]] + value[item-1])
else:
maxval[item][cap] = maxval[item-1][cap]
return maxval[numitems][capacity]
weight = [ [1, 2, 3, 4, 5], [1, 3, 4, 6, 9], [1, 2, 3, 5], [3, 5] ]
value = [ [3, 5, 4, 8, 10], [5, 10, 4, 6, 8], [1, 19, 80, 100], [80, 100] ]
capacity = [ 5, 10, 6, 2 ]
i = 0
while i <= 3:
print("\n[DP] 0-1 Knapsack max value : " + str ( DPKnapsack (capacity[i], weight[i], value[i])))
print("[Recursion] 0-1 Knapsack max valule : " + str( Knapsack (len(weight[i]), capacity[i], weight[i], value[i])))
i += 1
Output
[DP] 0-1 Knapsack max value : 11
[Recursion] 0-1 Knapsack max valule : 11
[DP] 0-1 Knapsack max value : 21
[Recursion] 0-1 Knapsack max valule : 21
[DP] 0-1 Knapsack max value : 101
[Recursion] 0-1 Knapsack max valule : 101
[DP] 0-1 Knapsack max value : 0
[Recursion] 0-1 Knapsack max valule : 0
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
// Recursive approach to 0-1 Knapsack problem
int Knapsack (int numitems, int capacity, vector<int> & weight, vector<int> & value) {
// No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
if (capacity == 0)
return 0;
// If 0 items are put in the sack, then maximum value for sack is 0
if (numitems == 0)
return 0;
/* Note : Here the number of item is limited (unlike coin change / integer partition problem)
hence the numitems -> (numitems - 1) when the item is included in the knapsack */
if (capacity >= weight[numitems-1])
return max (Knapsack (numitems-1, capacity, weight, value), // item not included in the sack
Knapsack (numitems-1, capacity-weight[numitems-1], weight, value) + value[numitems-1]); // Item included.
else
return Knapsack(numitems-1, capacity, weight, value);
}
// Dynamic programming approach to 0-1 Knapsack problem
int DPKnapsack (int capacity, vector<int> & weight, vector<int> & value) {
int numitems = weight.size();
int maxval[numitems+1][capacity+1];
// If 0 items are put in the sack of capacity 'cap' then maximum value for each sack is 0
for (int cap=0; cap<=capacity; cap++)
maxval[0][cap] = 0;
// No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
for (int item=0; item<=numitems; item++)
maxval[item][0] = 0;
for (int item=1; item <= numitems; item++) {
for (int cap=1; cap <= capacity; cap++) {
/* Note : Here the number of item is limited (unlike coin change / integer partition problem)
hence the numitems -> (numitems - 1) when the item is included in the knapsack */
if (cap >= weight[item-1]) {
maxval[item][cap] = max (maxval[item-1][cap], // Item not included in the knapsack
maxval[item-1][cap-weight[item-1]] + value[item-1]); // Item included in the knapsack
} else {
maxval[item][cap] = maxval[item-1][cap];
}
}
}
return maxval[numitems][capacity];
}
int main() {
vector<vector<int>> weight = { {1, 3, 4, 6, 9}, {1, 2, 3, 5}, {3, 5}, {1, 2, 3, 4, 5} };
vector<vector<int>> value = { {5, 10, 4, 6, 8}, {1, 19, 80, 100}, {80, 100}, {3, 5, 4, 8, 10} };
vector<int> capacity = { 10, 6, 2, 5 };
int i = 0;
// 4 test cases
while ( i <= 3) {
cout << "\n[DP] 0-1 Knapsack max value : " << DPKnapsack ( capacity[i], weight[i], value[i] ) << endl;
cout << "[Recursion] 0-1 Knapsack max value : " << Knapsack ( weight[i].size(), capacity[i], weight[i], value[i] ) << endl;
i++;
}
return 0;
}
Output
[DP] 0-1 Knapsack max value : 21
[Recursion] 0-1 Knapsack max value : 21
[DP] 0-1 Knapsack max value : 101
[Recursion] 0-1 Knapsack max value : 101
[DP] 0-1 Knapsack max value : 0
[Recursion] 0-1 Knapsack max value : 0
[DP] 0-1 Knapsack max value : 11
[Recursion] 0-1 Knapsack max value : 11
import java.util.Arrays;
import java.util.List;
class Main {
// Recursive approach to 0-1 Knapsack problem
static int Knapsack (int numitems, int capacity, List<Integer> weight, List<Integer> value) {
// No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
if (capacity == 0)
return 0;
// If 0 items are put in the sack, then maximum value for sack is 0
if (numitems == 0)
return 0;
/* Note : Here the number of item is limited (unlike coin change / integer partition problem)
hence the numitems -> (numitems - 1) when the item is included in the knapsack */
if (capacity >= weight.get(numitems-1))
return Math.max (Knapsack (numitems-1, capacity, weight, value), // Item not included in the sack.
Knapsack (numitems-1, capacity-weight.get(numitems-1), weight, value) + value.get(numitems-1)); // Item included.
else
return Knapsack(numitems-1, capacity, weight, value);
}
// Dynamic programming approach to 0-1 Knapsack problem
static int DPKnapsack (int capacity, List<Integer> weight, List<Integer> value) {
int numitems = weight.size();
int maxval[][] = new int[numitems+1][capacity+1];
// If 0 items are put in the sack of capacity 'cap' then maximum value for each sack is 0
for (int cap=0; cap<=capacity; cap++)
maxval[0][cap] = 0;
// No item can be put in the sack of capacity 0 so maximum value for sack of capcacity 0 is 0
for (int item=0; item<=numitems; item++)
maxval[item][0] = 0;
for (int item=1; item <= numitems; item++) {
for (int cap=1; cap <= capacity; cap++) {
/* Note : Here the number of item is limited (unlike coin change / integer partition problem)
hence the numitems -> (numitems - 1) when the item is included in the knapsack */
if (cap >= weight.get(item-1)) {
maxval[item][cap] = Math.max (maxval[item-1][cap], // Item not included in the sack.
maxval[item-1][cap-weight.get(item-1)] + value.get(item-1)); // Item included.
} else {
maxval[item][cap] = maxval[item-1][cap];
}
}
}
return maxval[numitems][capacity];
}
public static void main (String args[]) {
List<Integer> weight = Arrays.asList(1, 3, 4, 6, 9);
List<Integer> value = Arrays.asList(5, 10, 4, 6, 8);
int capacity = 10; // Items (1, 3, 9) give maximum value of 21
System.out.println("Maximum value of 0-1 Knapsack using DP : " + DPKnapsack(capacity, weight, value));
System.out.println("Maximum value of 0-1 Knapsack using recursion: " + Knapsack(weight.size(), capacity, weight, value));
List<Integer> weight1 = Arrays.asList(1, 2, 3, 5);
List<Integer> value1 = Arrays.asList(1, 19, 80, 100);
capacity = 6; // Item (1,5) gives maximum value of 101
System.out.println("Maximum value of 0-1 Knapsack using DP : " + DPKnapsack(capacity, weight1, value1));
System.out.println("Maximum value of 0-1 Knapsack using recursion: " + Knapsack(weight1.size(), capacity, weight1, value1));
List<Integer> weight2 = Arrays.asList(3, 5);
List<Integer> value2 = Arrays.asList(80, 100);
capacity = 2; // No item can be added to the knapsack.
System.out.println("Maximum value of 0-1 Knapsack using DP : " + DPKnapsack(capacity, weight2, value2));
System.out.println("Maximum value of 0-1 Knapsack using recursion: " + Knapsack(weight2.size(), capacity, weight2, value2));
List<Integer> weight3 = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> value3 = Arrays.asList(3, 5, 4, 8, 10);
capacity = 5; // Items with weight (1, 4) give maximum value of 11.
System.out.println("Maximum value of 0-1 Knapsack using DP : " + DPKnapsack(capacity, weight3, value3));
System.out.println("Maximum value of 0-1 Knapsack using recursion: " + Knapsack(weight3.size(), capacity, weight3, value3));
}
}
Output
Maximum value of 0-1 Knapsack using DP : 11
Maximum value of 0-1 Knapsack using recursion: 11
Maximum value of 0-1 Knapsack using DP : 21
Maximum value of 0-1 Knapsack using recursion: 21
Maximum value of 0-1 Knapsack using DP : 101
Maximum value of 0-1 Knapsack using recursion: 101
Maximum value of 0-1 Knapsack using DP : 0
Maximum value of 0-1 Knapsack using recursion: 0
© 2019-2026 Algotree.org | All rights reserved.
This content is provided for educational purposes. Feel free to learn, practice, and share knowledge.
For questions or contributions, visit algotree.org
"There are two ways to write error-free programs; only the third one works. - Alan J. Perlis"