Memra

Greedy strategy & activity selection

The greedy-choice property and optimal substructure, proved by an exchange argument, applied to activity selection.

What makes an algorithm greedy

A greedy algorithm makes the choice that looks best *right now* and never reconsiders it. It commits to a locally optimal choice before solving any subproblem, then recurses on the one subproblem that remains. This is the opposite of dynamic programming, which solves subproblems *first* and only then chooses. Greedy is therefore top-down and DP is bottom-up; greedy considers exactly one choice per step where DP considers all of them.

Greedy does not always work. When it does, the problem has two properties:

  1. Greedy-choice property — a globally optimal solution can be built by making locally optimal (greedy) choices. The greedy choice may depend on choices made so far, but not on the solutions to future subproblems.
  2. Optimal substructure — an optimal solution to the problem contains optimal solutions to its subproblems. (DP needs this too; greedy uses it after assuming the greedy choice is already made.)

The activity-selection problem

You are given $n$ activities, each with a start time $s_i$ and a finish time $f_i$ (the activity occupies the half-open interval $[s_i, f_i)$). Two activities are compatible if their intervals do not overlap. The goal is to select a maximum-size set of mutually compatible activities — think of scheduling the most events possible in one lecture hall.

The greedy choice: sort the activities by finish time, then always take the *next* activity whose start time is at or after the finish time of the last one you took. Taking the earliest-finishing compatible activity leaves the resource free as soon as possible, maximizing room for the rest.

Worked example. With 11 activities sorted by finish time (CLRS Fig. 15.1):

$$\begin{array}{c|ccccccccccc} i & 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 & 11\\\hline s_i & 1 & 3 & 0 & 5 & 3 & 5 & 6 & 8 & 8 & 2 & 12\\ f_i & 4 & 5 & 6 & 7 & 9 & 9 & 10 & 11 & 12 & 14 & 16 \end{array}$$

Take $a_1$ (finishes at 4). The next compatible one is $a_4$ (starts at $5 \ge 4$, finishes at 7). Then $a_8$ (starts at $8 \ge 7$, finishes at 11). Then $a_{11}$ (starts at $12 \ge 11$). Result: $\{a_1, a_4, a_8, a_{11}\}$ — four activities, which is optimal.

Why earliest-finish is safe (Theorem 15.1)

The correctness rests on an exchange argument, the canonical proof for the greedy-choice property. Let $a_m$ be the earliest-finishing activity in a subproblem, and let $A$ be *any* maximum-size compatible set for that subproblem. Let $a_j$ be the earliest-finishing activity in $A$. If $a_j = a_m$, we are done. Otherwise build $A' = (A - \{a_j\}) \cup \{a_m\}$. Because $f_m \le f_j$, swapping $a_j$ out for $a_m$ keeps every later activity compatible, so $A'$ is still valid and $|A'| = |A|$. Thus a maximum-size solution containing the greedy choice exists. ∎

After the $O(n \lg n)$ sort, the selection loop is $\Theta(n)$: each activity is examined once. Contrast this with the $\Theta(n^2)$ DP recurrence $c[i,j] = \max_k \{c[i,k] + c[k,j] + 1\}$ that the greedy choice collapses into a single $O(1)$ choice per step.

NORMAL ~/memra/learn/comp-372/greedy-strategy-activity-selection utf-8 LF