Fractional Knapsack Problem in DSA C - Time & Space Complexity
We want to understand how the time needed to solve the Fractional Knapsack Problem changes as the number of items grows.
Specifically, how does the algorithm's work increase when we have more items to consider?
Analyze the time complexity of the following code snippet.
// Fractional Knapsack Problem
// items[] contains pairs of (value, weight)
// n is number of items, W is max capacity
// Step 1: Calculate value per weight for each item
// Step 2: Sort items by value per weight descending
// Step 3: Take items fully or partially until capacity fills
void fractionalKnapsack(int n, int W, Item items[]) {
// Sort items by value/weight ratio
qsort(items, n, sizeof(Item), compare);
int currentWeight = 0;
double totalValue = 0.0;
for (int i = 0; i < n; i++) {
if (currentWeight + items[i].weight <= W) {
currentWeight += items[i].weight;
totalValue += items[i].value;
} else {
int remain = W - currentWeight;
totalValue += items[i].value * ((double) remain / items[i].weight);
break;
}
}
}
This code sorts items by their value per weight and then picks as much as possible from the best items until the knapsack is full.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting the array of items by value per weight.
- How many times: Sorting takes about n log n steps for n items.
- Secondary operation: One loop through all items to pick them.
- How many times: This loop runs at most n times.
As the number of items increases, the sorting step grows faster than the picking loop.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * log 10 ≈ 33 operations for sorting + 10 for picking |
| 100 | About 100 * log 100 ≈ 664 operations for sorting + 100 for picking |
| 1000 | About 1000 * log 1000 ≈ 9966 operations for sorting + 1000 for picking |
Pattern observation: The sorting step dominates and grows faster than the picking loop as n increases.
Time Complexity: O(n log n)
This means the time needed grows a bit faster than just the number of items because sorting takes extra steps as the list grows.
[X] Wrong: "The picking loop is the slowest part, so the time complexity is O(n)."
[OK] Correct: Sorting the items takes more time than just picking them, so the overall time depends mostly on sorting, which is O(n log n).
Understanding how sorting affects the time helps you explain why some steps take longer and shows you can analyze algorithms beyond just loops.
"What if the items were already sorted by value per weight? How would the time complexity change?"
Practice
Fractional Knapsack Problem?Solution
Step 1: Understand the problem goal
The fractional knapsack problem allows taking parts of items to maximize total value within a weight limit.Step 2: Compare options
Only Maximize total value by taking fractions of items within weight limit correctly describes maximizing value by taking fractions within weight limit.Final Answer:
Maximize total value by taking fractions of items within weight limit -> Option CQuick Check:
Goal = Maximize value with fractions [OK]
- Thinking only whole items can be taken
- Confusing with minimizing weight
- Ignoring value maximization
Solution
Step 1: Identify sorting requirement
Items must be sorted by value-to-weight ratio descending for greedy selection.Step 2: Match sorting method
Usingqsortwith a comparator sorting by value/weight descending is correct.Final Answer:
qsort(items, n, sizeof(Item), compare); where compare sorts by value/weight descending -> Option AQuick Check:
Sort by value/weight ratio descending [OK]
- Sorting by weight only
- Sorting without comparator
- Using inefficient sorting for large data
typedef struct { int value; int weight; } Item;
Item items[] = {{60, 10}, {100, 20}, {120, 30}};
int n = 3, W = 50;
// Assume items sorted by value/weight descending
float fractionalKnapsack(Item items[], int n, int W) {
int curWeight = 0;
float finalValue = 0.0;
for (int i = 0; i < n; i++) {
if (curWeight + items[i].weight <= W) {
curWeight += items[i].weight;
finalValue += items[i].value;
} else {
int remain = W - curWeight;
finalValue += items[i].value * ((float) remain / items[i].weight);
break;
}
}
return finalValue;
}
printf("%.2f", fractionalKnapsack(items, n, W));Solution
Step 1: Calculate value/weight ratios and sort
Ratios: 60/10=6, 100/20=5, 120/30=4. Sorted order is as given.Step 2: Add items until weight limit 50
Add first item fully: weight=10, value=60; second fully: weight=30, value=160; third partially: remain=20, value=120*(20/30)=80; total value=60+100+80=240.Final Answer:
240.00 -> Option AQuick Check:
Sum values with fractions = 240.00 [OK]
- Not sorting by ratio
- Adding partial value incorrectly
- Ignoring remaining capacity
float fractionalKnapsack(Item items[], int n, int W) {
int curWeight = 0;
float finalValue = 0.0;
for (int i = 0; i < n; i++) {
if (curWeight + items[i].weight < W) {
curWeight += items[i].weight;
finalValue += items[i].value;
} else {
int remain = W - curWeight;
finalValue += items[i].value * ((float) remain / items[i].weight);
break;
}
}
return finalValue;
}Solution
Step 1: Analyze the weight check condition
The conditioncurWeight + items[i].weight < Wexcludes items that exactly fill the knapsack.Step 2: Correct the condition
Changing to <= allows taking items that fit exactly, avoiding missing full items.Final Answer:
The condition should be <= instead of < to include full weight equal to W -> Option DQuick Check:
Use <= to include exact weight [OK]
- Using < excludes exact fit items
- Changing variable types unnecessarily
- Incorrect loop indices
Solution
Step 1: Calculate value/weight ratios and sort items
Ratios: 40/2=20, 100/20=5, 50/10=5. Sorted descending: {40,2}, {100,20}, {50,10}.Step 2: Greedy selection with capacity 26
Take {40,2} full: w=2, v=40, remain=24.
Take {100,20} full: w=22, v=140, remain=4.
Fraction of {50,10}: (4/10)*50=20, total v=160.Final Answer:
160 -> Option BQuick Check:
Max value by greedy fractions = 160 [OK]
- Ignoring sorting by ratio
- Taking items in wrong order
- Miscomputing fractional value
Ready to prove it?
Pass the test and this pattern moves unknown
