Homeβ€Ί DSAβ€Ί Fractional Knapsack Problem β€” Greedy Approach

Fractional Knapsack Problem β€” Greedy Approach

Where developers are forged. Β· Structured learning Β· Free forever.
πŸ“ Part of: Greedy & Backtracking β†’ Topic 9 of 13
Learn the fractional knapsack problem and its greedy solution.
βš™οΈ Intermediate β€” basic DSA knowledge assumed
In this tutorial, you'll learn:
  • Sort by value/weight density descending. Take full items while they fit, take a fraction of the next item to fill remaining capacity. O(n log n) dominated by sort.
  • The exchange argument is the key: any solution not taking the highest-density item first can be improved by swapping β€” this is the formal proof, not just intuition.
  • Fractional knapsack: greedy optimal. 0/1 knapsack: DP required. Knowing which you are facing is the first question to ask in any packing/allocation problem.
✦ Plain-English analogy ✦ Real code with output ✦ Interview questions
⚑ Quick Answer
You have a bag with a weight limit and a pile of items each with a weight and value. Unlike 0/1 knapsack where you must take or leave each item, here you can take fractions β€” like scooping 70% of a bag of gold dust. The greedy strategy is simple: always take the item with the highest value-per-weight ratio first, and when the bag is almost full, take a fraction of the next best item.

Fractional knapsack is where most engineers first encounter the concept of greedy correctness β€” the proof that taking the highest value-density item first is provably optimal, not just intuitively reasonable. The exchange argument used here is a template that appears throughout algorithm design: assume the greedy choice is not in an optimal solution, then show you can swap it in without making things worse.

In practice, fractional knapsack models continuous resource allocation: bandwidth allocation across network flows, portfolio optimisation with divisible assets, CPU time sharing. The 0/1 version (items must be whole) requires dynamic programming and is a completely different beast β€” knowing which version you're facing is the first question to ask.

The Greedy Strategy

Sort all items by value/weight ratio in descending order. Take items greedily β€” full items when they fit, a fraction of the next item when the bag is almost full.

fractional_knapsack.py Β· PYTHON
123456789101112131415161718192021
def fractional_knapsack(capacity: float, weights: list, values: list) -> float:
    n = len(weights)
    # Create (value_density, weight, value) tuples
    items = sorted(zip(values, weights), key=lambda x: x[0]/x[1], reverse=True)
    total_value = 0.0
    remaining = capacity
    for value, weight in items:
        if remaining <= 0:
            break
        if weight <= remaining:
            total_value += value
            remaining -= weight
        else:
            # Take fraction
            total_value += value * (remaining / weight)
            remaining = 0
    return total_value

weights = [10, 20, 30]
values  = [60, 100, 120]
print(fractional_knapsack(50, weights, values))  # 240.0
β–Ά Output
240.0

Why Greedy Works Here But Not for 0/1 Knapsack

The greedy approach works for fractional knapsack because of the greedy choice property: taking the highest value-density item first is always locally and globally optimal β€” you can always 'undo' a partial choice by trading a fraction.

For 0/1 knapsack, taking the highest density item might leave a gap that no remaining item can fill optimally. Example: - Capacity = 10 - Item A: weight=6, value=10 (density 1.67) - Item B: weight=5, value=8 (density 1.60) - Item C: weight=5, value=8 (density 1.60)

Greedy picks A (density 1.67) then can only fit one of B/C β€” total = 10+8 = 18. Optimal picks B+C β€” total = 8+8 = 16. Wait β€” greedy wins here. But with capacity=10, items [{w=6,v=6},{w=5,v=5},{w=5,v=5}]: greedy picks first (density 1), then one of the others = 11. Optimal: pick both w=5 items = 10. Greedy wins again for fractional.

The key: with fractional items, the exchange argument holds perfectly β€” you can always swap parts of lower-density items for parts of higher-density ones to improve value.

πŸ”₯
Proof of OptimalitySuppose an optimal solution doesn't take the highest-density item first. Swap some fraction of a lower-density item for an equal weight of the highest-density item β€” value increases. Contradiction. Therefore greedy is optimal.

Complexity

Sorting: O(n log n) Selection: O(n) Total: O(n log n) time, O(1) extra space

Compare with 0/1 knapsack: O(nW) dynamic programming.

🎯 Key Takeaways

  • Sort by value/weight density descending. Take full items while they fit, take a fraction of the next item to fill remaining capacity. O(n log n) dominated by sort.
  • The exchange argument is the key: any solution not taking the highest-density item first can be improved by swapping β€” this is the formal proof, not just intuition.
  • Fractional knapsack: greedy optimal. 0/1 knapsack: DP required. Knowing which you are facing is the first question to ask in any packing/allocation problem.
  • Real-world: continuous resource allocation β€” bandwidth, CPU cycles, capital allocation where fractional units are meaningful.
  • Follow-up interview question: if weights and values are integers, does fractional knapsack still give a fractional answer? (Yes, if no item fits perfectly in remaining space.)

Interview Questions on This Topic

  • QWhy does greedy work for fractional knapsack but not 0/1 knapsack?
  • QWhat is the time complexity of the fractional knapsack greedy solution?
  • QProve that sorting by value/weight ratio gives the optimal solution.

Frequently Asked Questions

What if two items have the same value density?

Tie-breaking order doesn't matter β€” any ordering of equal-density items gives the same total value.

πŸ”₯
Naren Founder & Author

Developer and founder of TheCodeForge. I built this site because I was tired of tutorials that explain what to type without explaining why it works. Every article here is written to make concepts actually click.

← PreviousPermutations using BacktrackingNext β†’Job Sequencing Problem with Deadlines
Forged with πŸ”₯ at TheCodeForge.io β€” Where Developers Are Forged