Problem
Given the weights (w1, w2, ... wn
) and values (v1, v2, ... vn
) of n
items, along with the capacity W of a knapsack, the task is to maximise the total value of the items in the knapsack.
Unlike the 0-1 Knapsack problem, where items cannot be divided, the Fractional Knapsack problem allows taking fractions of items. This means we can divide an item into smaller portions proportional to its weight and take only the fraction that fits in the remaining capacity of the knapsack.
Examples
Example 1
|
|
Example 2
|
|
Variations
In this article, we explored the Fractional Knapsack problem, where items can be divided to maximise value using a greedy approach. However, this is just one variation of the knapsack problem. When items cannot be divided, we move to the Discrete Knapsack problems, where each item is either taken entirely or left out. Discrete knapsack problems come in two types:
- With repetitions: Items can be selected multiple times Unbounded Knapsack Problem
- Without repetitions: Each item can only be selected once 0-1 Knapsack Problem
Additionally, there are special cases of the knapsack problem:
- All items have equal weight: In this scenario, the goal is to maximise profit as all items weigh the same. Sorting items by value and then picking the highest-value items will solve this variant using a greedy approach.
- All items have equal value: If all items have the same value, selecting as many items as possible within the weight limit becomes the target. Sorting items by size and selecting the smallest ones until the knapsack is full provides an efficient solution.
Another prominent instance of the knapsack problem is the Subset Sum Problem, where each item’s value is proportional to its size. For example, consider a collection of gold weights: heavier weights hold more value, and the goal is to fill the knapsack while minimising leftover space. Additionally, this problem appears in cases where you aim to achieve a specific total (C
) as closely as possible.
However, this subset sum problem cannot be solved using a greedy algorithm because it is NP-complete. This means it belongs to a class of problems for which no known polynomial-time solutions exist unless P = NP is proven. It is often linked to the Subset Sum Problem and related algorithms like the Integer Partition Algorithm.
Solution
Method 1 - Brute Force
A brute-force approach would involve testing every possible subset with varying fractions, but this method is highly time-consuming.
Method 2 - Greedy
Reasoning and Intuition
An efficient way to solve the Fractional Knapsack problem is by using a greedy approach. The core idea is to prioritise items with the highest value-to-weight ratio (v[i]/w[i]
) because they yield the most value per unit of weight. So, we compute the ratio of value/weight
for each item, then sort all items based on this ratio in descending order. Items having higher ratios should be placed in the knapsack first, and only fractions of subsequent items are used to fill the remaining capacity, if necessary. This ensures that items contributing the highest value per unit of weight are prioritised.
Approach
- Calculate value-to-weight ratio: For each item, compute the ratio
v[i]/w[i]
. - Sort items by their ratio: Sort items in descending order of value-to-weight ratio.
- Fill the knapsack greedily:
- Start with the first item and take it fully if weight allows.
- If the knapsack does not have sufficient capacity, take a fraction proportional to the remaining space.
- Stop when the knapsack is full.
This greedy strategy ensures the maximum value is achieved.
Pseudocode
|
|
Sample run
Here is how it can work:
- Make a greedy choice: Pick as many items as possible with the highest
value-to-weight ratio
. For example, consider these items:- Item A:
20/4 = 5/unit
- Item B:
18/3 = 6/unit
- Item C:
14/2 = 7/unit
Since item C offers the highest value per weight unit, it is chosen first, followed by item B and then item A as much as the capacity allows.
- Item A:
- Ensure it’s an optimal move: Any item can be divided into smaller fractions of weight with proportional value. Because the ratios are calculated per unit, selecting items with the highest ratio as much as possible is guaranteed to maximise value.
- Reduce the problem to a smaller subproblem: Once an item (whole or part) is selected, the remaining capacity of the knapsack and the list of items reduce, effectively creating a smaller equivalent problem.
- Solve the subproblem: Continue choosing items with the maximum value-to-weight ratio until the bag is filled. If the last item cannot fit entirely, take a fraction of it to complete the capacity.
Code
|
|
|
|
|
|
Complexity
- ⏰ Time complexity:
O(n log n)
. Sorting items by theirv[i]/w[i]
ratio takesO(n log n)
. Filling the knapsack only takesO(n)
. - 🧺 Space complexity:
O(n)
. To store the value-to-weight ratios and sorting, we use additional space proportional to the number of items.