Part 0 · the ground floor · spine

00

Models, instances, and an oracle you trust

What a combinatorial problem is, the nine you will meet all course, and the one tool that lets you believe your own code.

needs nothing~1¼ h slides + 2 h lablab: uv run co lab 00

00 · overview

Three things to leave with

vocabulary

Problem vs instance. A feasible set described implicitly. Decision, optimization, counting.

the nine problems

Knapsack, set cover, assignment, bin packing, colouring, max-cut, TSP, job-shop, vertex cover.

two habits

Test every algorithm against an oracle. Ask what would prove an answer optimal, not just what the answer is.

Roadmap: definitions → the nine → spaces and symmetry → certificates → the oracle and the harness → the wall.

getting around

Words with a dotted underline are glossary terms: click one for its definition. G lists every term in the unit, N shows the notes. One small graph, the running example, comes back on most slides; a solid underline like that one shows it on hover. Optional extra: interactive figures, linked from the slides they support by a small ▸ chip; skip them freely.

section 1

What makes a problem combinatorial

Finite, but only in the least useful sense of the word.

00 · definitions

Problems and instances

definition

An optimization problem is a set of instances. An instance is a pair $(F, c)$: a feasible set $F$ and an objective $c : F \to \mathbb{R}$. We want $x^* \in F$ with $c(x^*) \le c(x)$ for all $x \in F$ (or $\ge$, for maximization).

combinatorial

$F$ is finite, and given implicitly: a simple, enumerable space $S$ and constraints, $\;F = \{x \in S : x \text{ satisfies the constraints}\}$.

Example. Vertex cover: an instance is a graph $G=(V,E)$. The space is $S = \{0,1\}^V$, the constraints are $x_u + x_v \ge 1$ for every $uv \in E$, and the objective is $c(x) = \sum_v x_v$, to be minimized. In words: pick the fewest vertices so that every edge touches one of them. The next slide does it on one graph.

00 · definitions · example

The running example

A triangle $0,1,2$ with one extra edge to vertex $3$. Four edges: $01,\ 02,\ 12,\ 23$. A candidate is $x \in \{0,1\}^4$, the vertices it picks.

candidate $x$picksuncovered edges$c(x)$
$(0,1,1,0)$$\{1, 2\}$none ✓2
$(1,1,0,1)$$\{0, 1, 3\}$none ✓3
$(0,0,1,1)$$\{2, 3\}$$01$ ✗—
$(0,0,1,0)$$\{2\}$$01$ ✗—

Feasibility is checking every edge. $\{2,3\}$ misses edge $01$, so it is not in $F$ and its size doesn't matter. Of all $2^4 = 16$ candidates, 7 are covers, and the smallest have 2 vertices.

The space $S$ is all 16 candidates. The feasible set $F$ is the 7 covers. Nobody wrote $F$ down: the four edge constraints describe it.

0 1 2 3

Filled: the cover $\{1,2\}$. Every edge has a filled end.

00 · definitions

Finite, and astronomically so

spacesizeat $n = 50$
subsets, $\{0,1\}^n$$2^n$$1.1 \times 10^{15}$
set partitionsBell $B_n$$1.9 \times 10^{47}$
tours from a fixed city$(n-1)!$$6.1 \times 10^{62}$

Enumerating is always correct and almost always useless.

The running example has $2^4 = 16$ candidates. Each vertex added doubles that: a graph with 50 vertices has the number in the first row.

Almost always useless, but it is not worthless: for $n \lesssim 20$ it is the only solver whose correctness you can see by reading it.

scale

At a billion candidates a second, $2^{50}$ takes 13 days. $(50-1)!$ takes about $10^{46}$ years.

00 · definitions

Four questions about one instance

versionaskson the running example, $k = 2$
decisionis there $x \in F$ with $c(x) \le k$?is there a cover with at most 2 vertices? yes (with $k = 1$: no)
evaluationwhat is $\min_{x\in F} c(x)$?the smallest cover has 2 vertices
search / optimizationfind an $x^*$ achieving ithere is one: $\{1, 2\}$
countinghow many $x \in F$ have $c(x) \le k$?2 covers: $\{1, 2\}$ and $\{0, 2\}$
fact

For integer objectives of polynomial bit size, the first three are equally hard, up to polynomial factors. Counting can be much harder.

how, on the example

Decision to evaluation: ask $k = 0, 1, 2, \dots$ and stop at the first yes. Evaluation to search: delete vertex 0 and its edges. The rest ($12$, $23$) needs 1, one less than 2, so some best cover uses 0. Keep it and repeat on the rest.

section 2

The nine problems

Each one is the textbook example of at least one technique later in the course.

00 · the nine

The cast

Knapsack{0,1}ⁿ · max DP (16), cover cuts (08), weakly NP-hard, FPTAS (22)
Set cover{0,1}ᵐ · min greedy $H_n$ (23), LP rounding & primal–dual (24)
Assignmentpermutations · min integral LP (06), Hungarian (15), Sinkhorn (31)
Bin packingset partitions · min strongly NP-hard, column generation (10)
Graph colouringset partitions · min SAT encodings (20), symmetry (27), Lovász θ (25)
Max-cut{0,1}ⁿ · max no constraints at all, Goemans–Williamson 0.878 (25)
TSPtours · min subtour separation (09), Held–Karp (11, 16), Christofides (23), 2-opt (26)
Job-shopmachine orders · min disjunctive & cumulative (18), LNS (19), CP-SAT (21)
Vertex cover{0,1}ⁿ · min 2-approx (23), half-integral LP (24), FPT (16), UGC (22)

subsets orderings partitions schedules

00 · the nine

One problem, three descriptions

As a predicate

what an oracle needs

def feasible(G, x):
    return all(x[u] or x[v]
               for u, v in G.edges)

def objective(G, x):
    return sum(x)

As an integer program

Parts I–II

$$\begin{aligned}\min\ & \textstyle\sum_{v} x_v \\ \text{s.t. } & x_u + x_v \ge 1 \quad \forall uv \in E \\ & x \in \{0,1\}^V\end{aligned}$$

As a constraint model

Part IV

x = [model.NewBoolVar(f"x{v}")
     for v in V]
for u, v in E:
    model.AddBoolOr(x[u], x[v])
model.Minimize(sum(x))

Same feasible set, three languages. What differs is what a solver can infer from the description without enumerating.

00 · spaces

The space is a modelling choice

Bin packing, $n$ items. Two spaces, the same feasible packings:

spacesize$n = 10$
every map item → bin$n^n$10 000 000 000
set partitions$B_n$115 975

The first space counts every relabelling of the bins as a new packing. The second counts each packing once: 86 000× fewer.

restricted growth strings

$a_0 = 0,\quad a_i \le 1 + \max(a_0,\dots,a_{i-1})$

$a_i$ is item $i$'s bin. Bins are opened in order, so each partition of $\{0,\dots,n-1\}$ has exactly one string. The next slide lists them for $n = 3$.

This is symmetry breaking. Later it is the biggest single lever on real MIP and CP models (units 05, 27).

00 · spaces · example

Set partitions, on three items

Every restricted growth string for $n = 3$, and the set partition it names. Read $a_i$ as "item $i$ goes in bin $a_i$".

stringbinswhy it is allowed
000$\{0,1,2\}$never opens a new bin
001$\{0,1\}\ \{2\}$item 2 opens bin 1
010$\{0,2\}\ \{1\}$item 1 opens bin 1
011$\{0\}\ \{1,2\}$item 1 opens bin 1
012$\{0\}\ \{1\}\ \{2\}$each item opens the next bin

Not allowed: 002 skips bin 1, and 100 starts at bin 1. Both are relabellings of strings already in the table (001, and 011). That is the symmetry being removed.

bin packing on these five

Items of size $3, 2, 1$; bins of capacity $4$.

stringbin loadsbins
000$6$ ✗—
001$5,\ 1$ ✗—
010$4,\ 2$ ✓2
011$3,\ 3$ ✓2
012$3,\ 2,\ 1$ ✓3

Five candidates, three feasible, optimum 2 bins. The "every map item → bin" space would have checked $3^3 = 27$.

section 3

Certificates

"Here is the answer" and "here is why nothing is better" are different objects.

00 · certificates

Two kinds of evidence

upper bound · "at most k"

Exhibit $x \in F$ with $c(x) = k$.

Anyone checks it by evaluating the constraints and the objective. For all nine problems that takes polynomial time. This is exactly what puts the decision versions in NP.

lower bound · "at least k"

Show that no $x \in F$ has $c(x) < k$.

Enumeration proves it, but the proof is exponentially long. Is there a short proof? For NP-hard problems, in general, it is believed there is not: that is NP ≠ coNP.

on the running example

At most 2: hand over $\{1, 2\}$; checking it is four edge lookups. At least 2: enumeration checks all 16 candidates and finds no cover of size 0 or 1. That works at 4 vertices, not at 50. The next two slides replace it with two edges.

For particular instances, and for whole problem classes, short lower-bound proofs do exist. Finding them is most of the course.

00 · certificates

A lower bound for vertex cover

lemma

If $M$ is a matching (edges sharing no endpoint) and $C$ a vertex cover in the same graph, then $|C| \ge |M|$.

why

Each matched edge needs one of its own endpoints in the cover. Matched edges share no endpoints, so no cover vertex can serve two of them: the cover needs $|M|$ different vertices.

So a cover and a matching of the same size prove each other optimal. This is the matching lower bound, the course's first instance of weak duality.

0 1 2 3 cover {1, 2} · matching {01, 23}

A path on four vertices. Filled vertices: a cover of size 2. Thick edges: a matching of size 2. Each proves the other optimal.

00 · certificates · example

A certificate, checked step by step

Claim: the smallest cover of the running example has 2 vertices. The certificate is a cover $C = \{1,2\}$ and a matching $M = \{01, 23\}$.

checkon the example
1. every edge of $M$ is an edge of $G$$01$ ✓, $23$ ✓✓
2. edges of $M$ share no endpointendpoints $0,1,2,3$: all different✓
3. $C$ covers every edge$01{:}\,1$ · $02{:}\,2$ · $12{:}\,1,2$ · $23{:}\,2$✓
4. sizes agree$|C| = 2 = |M|$✓

What follows: check 3 says the optimum is at most 2. Checks 1–2 and the lemma say every cover has at least 2. So 2 is optimal, and nobody enumerated anything.

A wrong certificate fails a check. $M = \{01, 12\}$ fails check 2 (vertex 1 twice), and rightly: one vertex, 1, touches both edges.

0 1 2 3

Filled: the cover. Thick: the matching. Each thick edge has its own filled end.

00 · certificates

When the bound is not enough

On a triangle, the largest matching has 1 edge, and the smallest cover needs 2 vertices. No matching certifies the optimum. This duality gap is real.

Delete the running example's edge $23$ and you are here: the matching loses its second edge, the cover still needs 2.

könig, 1931

In a bipartite graph, $\max |M| = \min |C|$. The certificate always exists.

The triangle is the smallest odd cycle, and odd cycles are exactly what bipartite graphs lack. That coincidence is where polyhedral combinatorics starts (units 06, 15).

ν = 1 < 2 = τ

Any edge is a maximum matching (1). Any two vertices form a minimum cover (2).

section 4

An oracle you trust

Slow, obviously correct, and the reference every later lab is checked against.

00 · oracle

Brute force, done once and done right

def brute_force(problem):
    best = best_x = None
    feasible = examined = 0
    for x in problem.space():
        examined += 1
        if not problem.is_feasible(x):
            continue
        feasible += 1
        v = problem.objective(x)
        if best is None or better(v, best, problem.sense):
            best, best_x = v, x
    return Result(best, best_x, feasible, examined)

Where people slip: initializing best to 0 or ∞ (wrong for one sense), and reporting a value on infeasible instances.

Obviously correct: it is the definition of the optimum, executed.

Self-certifying: examined == space.size() is the lower-bound proof.

Generic: one function for all nine problems, because every problem has the same problem interface.

on the running example

examined=16, feasible=7, value 2 at (0, 1, 1, 0): the cover $\{1, 2\}$. It keeps the first best it meets, so the tie $\{0, 2\}$, found later, is not reported.

00 · oracle

Differential testing

generator n = 1, 2, 3 … × seeds your algorithm brute force compare feasible? value? stop and print the instance

Smallest first. The first failure is the smallest counterexample the sweep contains, and so the easiest one to draw.

Feasibility checked separately. A "better than optimal" answer is always an infeasible one.

Ratio mode. For approximation algorithms, pass ratio=2 and check a guarantee, not equality.

00 · oracle

The harness catches what you believe

greedy's first pick optimum {middle row} = 3 · greedy = 4

"Take the vertex covering the most uncovered edges." (max-degree greedy)

On this spider it takes the centre (degree 3). The three leg-ends are then disjoint edges, and each costs one more vertex: 4.

The middle row covers everything with 3, and the three thick edges are a matching of size 3, so 3 is provably optimal.

No graph with fewer vertices makes max-degree greedy fail whatever the tie-breaking. In lab step 5 you write the heuristic, and the harness has to find a case like this on its own.

00 · oracle

The wall

Pure-Python brute force, reference machine, extrapolated from µs per candidate:

space1 minute1 hour1 year
$2^n$ — vertex cover253144
$(n-1)!$ — TSP111316
$B_n$ — bin packing121519

A year of computing buys five more TSP cities than a minute does. That limit is the wall.

rule for the rest of the course

Tests against brute force use $n \le 12$ for subset spaces, $n \le 8$ for tours and partitions. Anything larger needs a certificate or a trusted solver.

00 · lab

Lab 00 — what you build

about 2 hours · uv run co lab 00
  1. Model it: feasibility and objective for vertex cover and bin packing.
  2. Set partitions: the restricted-growth-string enumerator.
  3. The oracle: generic brute force, checked against the reference on all nine problems.
  4. A certificate: the matching lower bound, and a checker that rejects the triangle.
  5. Break it: a heuristic you believe, and the harness proving you wrong.
uv run co test 00      # after each step: · not started  ✗ failing  ✓ done
uv run co then 00      # find your wall

00 · checkpoint

Done when

checkpoint
  • All five lab steps are ✓.
  • You can generate and exactly solve an instance of any of the nine problems at the sizes your wall allows.
  • The harness caught your deliberately wrong heuristic without you pointing it at the failure.
  • Without notes, you can explain the two kinds of certificate, and use the triangle to show why a matching cannot always certify a cover.

Reading

Papadimitriou & Steiglitz, Combinatorial Optimization, ch. 1.
Korte & Vygen, Combinatorial Optimization, §1.1–1.3 (optional).

Next

Any of three roots: 01 polyhedra (LP trunk), 13 matroids (combinatorial trunk), 17 propagation (constraint trunk).