Purpose: Minimise the maximum penalty on a single machine subject to precedence constraints, in . Eugene Lawler, 1973.
The Problem
jobs, job has processing time and a non-decreasing cost function of its completion time . Precedence constraints form a DAG: job must finish before job starts. Minimise .
Common special case: , giving minimum maximum lateness .
Algorithm β schedule backwards
The whole schedule occupies where . Build it from the end:
- Let = the set of unscheduled jobs, .
- Among jobs in with no unscheduled successors (they can legally go last), pick the one minimising .
- Place it in the last remaining slot, ending at time . Set , remove from .
- Repeat.
// jobs 0..n-1, succ[j] = successors; f[j](t) = penalty
vector<int> lawler(int n, vector<long long> p, vector<vector<int>> succ,
function<long long(int,long long)> f) {
vector<int> outdeg(n, 0);
for (int j = 0; j < n; j++) for (int k : succ[j]) outdeg[j]++;
long long t = accumulate(p.begin(), p.end(), 0LL);
vector<bool> done(n, false);
vector<int> order;
vector<vector<int>> pred(n);
for (int j = 0; j < n; j++) for (int k : succ[j]) pred[k].push_back(j);
for (int step = 0; step < n; step++) {
int best = -1;
for (int j = 0; j < n; j++)
if (!done[j] && outdeg[j] == 0)
if (best < 0 || f(j, t) < f(best, t)) best = j;
done[best] = true; order.push_back(best);
t -= p[best];
for (int i : pred[best]) outdeg[i]--;
}
reverse(order.begin(), order.end());
return order;
}Complexity
- Time: β rounds, each scanning jobs. with a heap when has enough structure.
- Space:
Proof (exchange argument)
Claim: there is an optimal schedule in which the job chosen in step 2 is last.
Let be the algorithmβs choice and let be last in some optimal schedule. Both are eligible to be last (no unscheduled successors), and by the choice rule. Move to the end and shift everything between forward. Then:
- βs new cost is ;
- every other job finishes no later than before, and each is non-decreasing, so no other cost increases;
- precedence is preserved, because had no unscheduled successors.
So the modified schedule is still optimal. Induct on the remaining prefix. β
Where it sits among scheduling results
| Problem | Notation | Result |
|---|---|---|
| Min max lateness, no precedence | EDD β sort by due date, | |
| Min max penalty, precedence | Lawler, | |
| Min sum of completion times | SPT β sort by processing time | |
| Min weighted sum | Smithβs rule β sort by | |
| Min number of late jobs | Moore-Hodgson, | |
| Min max lateness with release times | NP-hard | |
| Two machines, min makespan | NP-hard (partition) |
The pattern
Almost every polynomially solvable single-machine scheduling problem is solved by βsort by the right keyβ plus an exchange argument. When you meet a scheduling problem, the first move is to guess the sort key and try to prove the adjacent swap never hurts. See Exchange Arguments.
Variants / Use Cases
- Minimising Maximum Lateness β the special case
- Job Sequencing with Deadlines β the profit-maximising cousin, solved with DSU or a heap
- Exchange Arguments β the proof technique
- Scheduling β the branch overview