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 the sorting and selection steps affect the total work done.
Analyze the time complexity of the following code snippet.
// Fractional Knapsack Problem
// items: array of (value, weight) pairs
// capacity: max weight allowed
Array.Sort(items, (a, b) => ((float)b.value / b.weight).CompareTo((float)a.value / a.weight));
float totalValue = 0;
int remainingCapacity = capacity;
foreach (var item in items) {
if (item.weight <= remainingCapacity) {
totalValue += item.value;
remainingCapacity -= item.weight;
} else {
totalValue += item.value * ((float)remainingCapacity / item.weight);
break;
}
}
This code sorts items by value per weight and then picks as much as possible from the highest ratio items until capacity is full.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting the array of items by value-to-weight ratio.
- How many times: Sorting typically takes time proportional to n log n, where n is the number of items.
- Secondary operation: One loop through all items to pick fractions or whole items.
- How many times: This loop runs once over all n items.
As the number of items increases, sorting takes more time, growing faster than just going through the list.
| 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: Sorting dominates and grows faster than the simple loop, so total time grows roughly like n log n.
Time Complexity: O(n log n)
This means the time needed grows a bit faster than just the number of items, mainly because of sorting.
[X] Wrong: "The fractional knapsack can be solved in linear time because we just pick items until full."
[OK] Correct: We must first sort items by value per weight, which takes more than linear time, so sorting dominates the total time.
Understanding this time complexity helps you explain why sorting is necessary before selection, showing you grasp the problem's core steps clearly.
"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 states maximizing total value by taking fractions within weight limit.Final Answer:
Maximize total value by taking fractions of items within weight limit -> Option BQuick Check:
Goal = Maximize value with fractions [OK]
- Thinking only whole items can be taken
- Confusing with minimizing weight
- Ignoring value-to-weight ratio
Item with public fields weight and value?Solution
Step 1: Check class declaration syntax
In C#, class fields must have type and access modifier for public fields.Step 2: Validate each option
class Item { public int weight; public int value; } correctly declares public int fields. class Item { int weight; int value; } lacks access modifier. public Item { int weight; int value; } misses class keyword. class Item { public weight; public value; } misses types.Final Answer:
class Item { public int weight; public int value; } -> Option AQuick Check:
Correct class syntax = class Item { public int weight; public int value; } [OK]
- Omitting access modifiers
- Missing data types
- Incorrect class keyword usage
var items = new[] {
new Item { weight = 10, value = 60 },
new Item { weight = 20, value = 100 },
new Item { weight = 30, value = 120 }
};
int capacity = 50;
double maxValue = 0;
Array.Sort(items, (a, b) => (b.value / (double)b.weight).CompareTo(a.value / (double)a.weight));
int remaining = capacity;
foreach (var item in items) {
if (item.weight <= remaining) {
maxValue += item.value;
remaining -= item.weight;
} else {
maxValue += item.value * (remaining / (double)item.weight);
break;
}
}
Console.WriteLine(Math.Round(maxValue, 2));Solution
Step 1: Sort items by value/weight ratio
Ratios: Item1=6, Item2=5, Item3=4. Sorted order: Item1, Item2, Item3.Step 2: Add items until capacity 50
Take Item1 fully (weight 10, value 60), remaining=40. Take Item2 fully (weight 20, value 100), remaining=20. Take 20/30 fraction of Item3: value = 120 * (20/30) = 80.Step 3: Calculate total value
Total = 60 + 100 + 80 = 240. Rounded to 240.00.Final Answer:
240.00 -> Option DQuick Check:
Sum values with fractions = 240.00 [OK]
- Not sorting by value/weight ratio
- Taking items without fraction
- Incorrect fraction calculation
int capacity = 50;
var items = new List<Item> {
new Item { weight = 10, value = 60 },
new Item { weight = 20, value = 100 },
new Item { weight = 30, value = 120 }
};
items.Sort((a, b) => (a.value / a.weight).CompareTo(b.value / b.weight));
double maxValue = 0;
int remaining = capacity;
foreach (var item in items) {
if (item.weight <= remaining) {
maxValue += item.value;
remaining -= item.weight;
} else {
maxValue += item.value * (remaining / item.weight);
break;
}
}
Console.WriteLine(maxValue);Solution
Step 1: Analyze sorting comparator
The comparator uses integer division (a.value / a.weight) which truncates decimals, causing wrong ratios.Step 2: Impact on sorting and calculation
Integer division leads to incorrect sorting order and wrong maxValue calculation.Final Answer:
Integer division causes incorrect ratio calculation -> Option CQuick Check:
Use double division for correct ratios [OK]
- Sorting ascending instead of descending
- Ignoring integer division truncation
- Assuming List causes error
Solution
Step 1: Calculate value/weight ratios and sort
Ratios: (5,30)=6, (10,40)=4, (15,45)=3. Sorted order: (5,30), (10,40), (15,45).Step 2: Fill knapsack capacity 20
Take full (5,30), remaining=15, value=30. Take full (10,40), remaining=5, value=70. Take fraction of (15,45): 5/15=1/3 fraction, value=45*(1/3)=15.Step 3: Calculate total value
Total value = 30 + 40 + 15 = 85.Final Answer:
85 -> Option AQuick Check:
Sum with fractions = 85 [OK]
- Not sorting by value/weight ratio
- Taking items without fraction
- Incorrect fraction calculation
Ready to prove it?
Pass the test and this pattern moves unknown
