The 0/1 Knapsack problem is a fundamental problem in combinatorial optimization. Given a set of items, each with a weight and a value, and a knapsack with a maximum weight capacity, the objective is to maximize the total value of items that can be included in the knapsack without exceeding its weight capacity. Each item can either be included or excluded (hence the name “0/1”), and the challenge is to find the optimal subset of items that maximizes value within the weight limit.
Given:
- A set of
n
items. - Each item has a weight
wt[i]
and a valueval[i]
. - A knapsack with a weight capacity
W
.
The task is to find:
- The maximum total value of items that can be included in the knapsack without exceeding its weight capacity.
Dynamic Programming Approach
Dynamic programming is well-suited for the 0/1 Knapsack problem because it involves breaking down the problem into smaller subproblems and solving each subproblem just once, storing the results in a table to avoid recalculating them.
- Initialization:
- Create a 2D array
dp
of size(n+1) x (W+1)
wheren
is the number of items andW
is the knapsack capacity. Initialize all elements to0
. dp[i][w]
represents the maximum value that can be attained with the firsti
items and a knapsack capacity ofw
.
- Create a 2D array
- Fill the DP Table:
- Iterate over each item (
i
) and each possible weight (w
) up to the maximum capacityW
. - For each item, decide whether to include it in the knapsack. This depends on whether including the item leads to a higher value than excluding it, without exceeding the capacity.
- Update
dp[i][w]
accordingly.
- Iterate over each item (
- Optimal Solution:
- The value
dp[n][W]
will contain the maximum value that can be attained within the given weight capacity.
- The value
fun knapSack(W: Int, wt: IntArray, val: IntArray, n: Int): Int {
// DP Table
val dp = Array(n + 1) { IntArray(W + 1) }
// Build table dp[][] in a bottom-up manner
for (i in 0..n) {
for (w in 0..W) {
if (i == 0 || w == 0)
dp[i][w] = 0
else if (wt[i - 1] <= w)
dp[i][w] = maxOf(val[i - 1] + dp[i - 1][w - wt[i - 1]], dp[i - 1][w])
else
dp[i][w] = dp[i - 1][w]
}
}
return dp[n][W] // Return the maximum value that can be stored in the knapsack
}
// Example usage
fun main() {
val val = intArrayOf(60, 100, 120)
val wt = intArrayOf(10, 20, 30)
val W = 50
val n = val.size
println(knapSack(W, wt, val, n))
}
Explanation:
- The function
knapSack
calculates the maximum value that can be achieved within the given weight limitW
. - It initializes a 2D array
dp
to store the maximum value that can be achieved using the firsti
items given a knapsack capacity ofw
. - It iterates over each item and capacity, updating the
dp
table based on whether including the current item is beneficial. - If including an item increases the total value without exceeding capacity, the item is considered included in the optimal subset.
- The function returns the value at
dp[n][W]
, which represents the maximum value that can be obtained for the entire set of items within the knapsack’s weight limit. - The
main
function demonstrates an example usage ofknapSack
, printing the maximum value that can be achieved for a given set of items and knapsack capacity.