3.7.4 · D1Algorithm Paradigms

Foundations — Greedy problems — activity selection, fractional knapsack, Huffman coding (full algorithm)

3,255 words15 min readBack to topic

Before you can read a proof about "finish times" or "value-per-weight" or "sibling leaves at maximum depth", you need to know what each of those pieces is and what it looks like. We build them in order, so that no symbol is used before it is drawn.


0. What is a "problem" here, and what is "optimal"?

The whole game is: out of the huge cloud of feasible solutions, land on an optimal one without checking them all. Greedy tries to do this in one straight sweep.


1. Number line, intervals, and "overlap"

Activity selection lives entirely on a number line — a straight horizontal axis where each point is a moment in time.

Figure s01 (below): two horizontal bars on a labelled time axis. The black bar is activity running from to ; the red bar is activity running from to . The gap between them (from to ) is the visual proof that they never share a moment — they are compatible.

Figure — Greedy problems — activity selection, fractional knapsack, Huffman coding (full algorithm)

Look at the figure. Two bars overlap if they share any point of the line at the same time. Two bars are compatible (non-overlapping) if one finishes at or before the other starts — the red bar starts after the black one ends, so they can both be scheduled.

The parent note's line "pick the next activity whose start last picked finish" is nothing more than this single inequality, applied over and over.


2. The symbols , , and inequalities (knapsack's language)

Now the parent's cryptic line reads in plain English: "Pick fractions of items so the money is as big as possible, but the packed weight never exceeds the bag."

Now that , , and all have meaning, we can read a filled bag.

Figure — Greedy problems — activity selection, fractional knapsack, Huffman coding (full algorithm)

Figure s02 (above): the tall rectangle is the knapsack of capacity . It is filled from the bottom by three slabs whose heights are the weights actually packed ():

  • item taken whole, : weight , value ;
  • item taken whole, : weight , value ;
  • item taken as a fraction (red slab): weight used , value .

The three packed weights are , so the bag is exactly full — the red slab is the "last slot" idea, filling the final gap with a fraction of the next item. The annotation totals the value .


3. Trees, nodes, leaves, and depth (Huffman's world)

Huffman coding is drawn as a binary tree. You must be fluent in tree pictures before the algorithm makes sense.

Figure — Greedy problems — activity selection, fractional knapsack, Huffman coding (full algorithm)

Figure s03 (above): a small binary tree. The top dot is the root (depth ). Every edge is labelled 0 (left) or 1 (right). The two black leaves at the bottom hanging off the same parent are marked as siblings. One leaf is drawn in red at depth ; reading the two edge-labels down to it spells its codeword 01. This is the picture that turns "depth" into "number of bits".


4. The min-heap / priority queue

Huffman repeatedly needs "give me the two smallest frequencies right now". Doing that fast needs one data structure.

Why not just re-sort every round? Because after each merge you insert a new combined frequency; a heap absorbs that in time instead of re-sorting from scratch. This is why Huffman's core loop rests on the heap, not on sorting.


5. Sorting and the symbol


6. The proof tool: the exchange argument

Every correctness proof in the parent note is the same trick, so learn it once.

You will meet three flavours of the same swap:

Activities. First fix an indexing convention: sort all activities by finish time and rename them so that . Under this convention, denotes the activity with the earliest finish time overall (index after sorting). The swap: in any optimal schedule, replace its earliest finisher with . Since finishes no later, everything that fit after the old choice still fits — feasible, same count.

Knapsack. Let (Greek "epsilon") be a tiny positive amount of weight — small enough that both items involved still have room to give and take it. Move kilograms out of a low-density item and into a high-density item (with ). Value lost ; value gained ; net change . So the swap strictly improves value, meaning a solution that did not take the densest item first could not have been optimal.

Huffman. Here we must use two different symbols so nothing is overloaded:

(Notice we wrote depth as , not : the symbol was already spent on knapsack density in §2, and is the finished code length — three different ideas, three different names.)


The prerequisite map — read it as a dependency chain

Each arrow below means "you need the left thing to understand the right thing". Read from the raw ideas at the top down into the three greedy problems, which all merge into the parent topic.

  • Number line + intervals → gives you the compatibility test → which powers Activity Selection.
  • Summation and density → both feed Fractional Knapsack.
  • Sorting + Big-O → feed the sort-first steps of activity selection and knapsack.
  • Min-heap → is what Huffman's core loop actually uses (pull the two smallest frequencies), not a sort.
  • Binary tree (depth, leaves, siblings) + prefix-free code → feed Huffman Coding.
  • The exchange argument → is the correctness proof shared by all three problems.
  • Activity Selection + Fractional Knapsack + Huffman Coding → together are the parent greedy topic.

Here is the same chain as a diagram (each box is one foundation, arrows point toward what it unlocks):

Number line and intervals

Compatibility f_i le s_j

Activity Selection

Summation sign sum

Fractional Knapsack

Density v over w

Sorting and Big-O

Binary tree depth leaves

Huffman Coding

Prefix free code

Min heap priority queue

Exchange argument

Greedy paradigm 3.7.4

This whole map feeds the parent greedy topic. Two other places reuse these pieces: Minimum Spanning Tree (Kruskal/Prim) (greedy + exchange again) and Dynamic Programming (what you fall back on when greedy fails, as in 0/1 knapsack).


Equipment checklist

Close the page and answer each; if you stumble, reread its section.

What does mean, and which two activities can it certify?
Activity finishes at or before activity starts, so they are compatible (non-overlapping) — after labelling so .
What is the density of a knapsack item, in words, and what must be true of ?
Value divided by weight, — money per kilogram; requires so the division is defined.
What do , , and each mean?
Skip the item, take all of it, take half of it.
What is the Huffman objective we minimise, as a formula?
Total cost bits, over all symbols .
What does mean?
The number of edges from the root down to node (root has ).
In a code tree, why does the depth of a leaf equal its codeword length ?
Each edge from root to leaf adds one bit (0 or 1), so depth = number of bits = .
What makes a code prefix-free, and why do leaves guarantee it?
No codeword begins another; symbols sit only at leaves, so no path is a prefix of another.
What are two leaves called when they share a parent?
Siblings.
What single operation does a min-heap give you cheaply, and at what cost?
Pop the smallest element (and push a new one), each in about time.
Why does Huffman use a min-heap rather than a sort for its core loop?
Each merge inserts a new combined frequency; a heap re-inserts in time instead of re-sorting from scratch.
What does denote in the activity-selection exchange argument?
After sorting so , is the activity with the earliest finish time overall.
In the Huffman swap, why is ?
(rarer symbol) times (deeper leaf) is non-positive.
What is in the knapsack exchange argument?
A tiny positive amount of weight, small enough that both items can still give and take it.
What does formally mean?
for some constant and all large — an upper bound on growth, ignoring constants.
What are the two different meanings of the letter in this topic?
Finish time in activity selection; symbol frequency in Huffman coding.