Proving NP-Completeness

The Cook–Levin theorem did the hard, once-in-a-lifetime work: it built a first NP-complete problem, SAT, from scratch. From here on, proving a new problem NP-complete is a craft with a fixed, repeatable recipe — and it never again requires reasoning about all of \mathsf{NP} directly. You stand on the shoulders of a known-hard problem and translate.

That leverage is why the catalogue of NP-complete problems exploded from one to thousands within a few years. Learn the recipe once and you hold a master key: given a new problem, you can usually tell within an afternoon whether it belongs to the intractable club.

The four-step recipe

To prove a target problem B is NP-complete, you do two things — show it is in \mathsf{NP}, and show it is NP-hard — and the second is a single reduction, not a quantifier over the whole class.

The direction of the reduction trips everyone up at first: you map the known-hard problem A into your new problem B. You are saying "if B were easy, then A would be easy — but A is known hard, so B must be hard too." Reduce from hard, to new.

Warm-up: SAT to 3-SAT

3-SAT is SAT restricted to clauses of exactly three literals. It is a favourite starting point precisely because it is so rigidly uniform. That it is still NP-complete comes from a clause-splitting reduction from general SAT: a long clause (\ell_1 \vee \ell_2 \vee \cdots \vee \ell_k) is rewritten with fresh "chaining" variables y_i into a conjunction of 3-literal clauses,

(\ell_1 \vee \ell_2 \vee y_1)\;\wedge\;(\bar{y}_1 \vee \ell_3 \vee y_2)\;\wedge\;\cdots\;\wedge\;(\bar{y}_{k-3} \vee \ell_{k-1} \vee \ell_k),

which is satisfiable exactly when the original clause is. Short clauses are padded with duplicate literals. The blow-up is linear, and the new formula uses only 3-clauses — so \text{SAT} \le_p \text{3-SAT}, and 3-SAT inherits NP-hardness. From now on we reduce from 3-SAT, the workhorse of the whole subject.

The star reduction: 3-SAT to Independent Set

An independent set in a graph is a set of vertices with no edge between any two of them. Independent Set asks: is there one of size k? We reduce 3-SAT to it with a beautiful little gadget construction. Given a 3-SAT formula with m clauses:

An independent set of size m must take exactly one literal from each triangle (that's the most a triangle allows, and it needs m in total), and the consistency edges guarantee those choices never contradict each other. Reading the chosen literals as "true" gives a consistent assignment satisfying every clause — and vice versa. The picture below shows the formula (x_1 \vee x_2 \vee x_3) \wedge (\overline{x_1} \vee x_2 \vee \overline{x_3}): two triangles, consistency edges between conflicting literals, and one size-2 independent set highlighted (choosing x_2 from each — the assignment x_2 = \text{true}).

Both directions of correctness fall out of the gadget's geometry, the map is clearly polynomial (3m vertices, a bounded number of edges), and Independent Set is obviously in \mathsf{NP} (the set itself is the certificate). So \text{3-SAT} \le_p \text{Independent Set}, and Independent Set is NP-complete.

One gadget, three theorems: Clique and Vertex Cover for free

The same graph yields two more NP-complete problems almost immediately, through elementary graph dualities — no new gadget needed.

Each of these is a one-line polynomial-time reduction with a two-way correctness proof — the recipe again, now trivially short. From a single triangle gadget we have harvested four NP-complete problems: 3-SAT, Independent Set, Clique, and Vertex Cover.

Why reductions compose

The whole enterprise works because polynomial-time reductions chain. If A \le_p B and B \le_p C, then A \le_p C: run one polynomial map, then the other, and a polynomial of a polynomial is still a polynomial. So to prove C is NP-hard you only need B \le_p C for any known-NP-hard B — the transitivity back to "all of \mathsf{NP}" is automatic, inherited from Cook–Levin through every link of the chain.

// Reductions compose: A ≤p B and B ≤p C give A ≤p C for free. type Reduction<X, Y> = (x: X) => Y; // polynomial-time instance map function compose<X, Y, Z>( aToB: Reduction<X, Y>, // A ≤p B bToC: Reduction<Y, Z>, // B ≤p C ): Reduction<X, Z> { return (x: X) => bToC(aToB(x)); // still polynomial time overall }

A year after Cook and Levin, Richard Karp published a landmark paper reducing SAT down a branching tree to 21 classic combinatorial problems — clique, vertex cover, Hamiltonian cycle, partition, knapsack and more — each proved NP-complete by exactly this recipe. Because reductions compose, every one of Karp's 21 became a fresh launch-pad for the next proof, and the list snowballed. Today the catalogue runs to thousands across every corner of computing, and the community reflex when meeting a new combinatorial problem is: "which known NP-complete problem does this smell like?" The recipe on this page is the same one used to grow that entire catalogue.

The single most common blunder in an NP-completeness proof is reducing the wrong way. To prove your new problem B is hard, you must map a known-hard problem A into B (A \le_p B) — showing "B is at least as hard as A". Building B \le_p A instead proves the opposite: that B is no harder than A, which says nothing about B's difficulty. And never skip the two-way correctness: an f that is only correct in one direction may turn a no-instance into a yes-instance and silently break the whole argument. Reduce from hard, prove both directions.