1. Formal Invariant — Complexity Classes & Karp Reduction Direction
Definition: P, NP, NP-Hard, NP-Complete & $A \le_p B$
- Class $\mathbf{P}$: Decision problems solvable in deterministic time $O(n^c)$ for some constant $c$.
- Class $\mathbf{NP}$: Decision problems for which a 'YES' instance $x$ has a polynomial-length certificate $w$ ($|w| = \text{poly}(|x|)$) verifiable by a deterministic algorithm $V(x, w) = 1$ in polynomial time.
- Karp Reduction ($A \le_p B$): A polynomial-time computable transformation $f$ such that for every instance $x$:
$$x \in A \iff f(x) \in B$$
- $\mathbf{NP}$-Hard: Every problem $A \in \mathbf{NP}$ satisfies $A \le_p B$.
- $\mathbf{NP}$-Complete: $B \in \mathbf{NP}$ AND $B$ is $\mathbf{NP}$-Hard.
2. Karp's Canonical Reduction Chain (1972)
(Cook-Levin 1971)"] -->|"Tseitin O(N)"| ThreeSAT["3-SAT
(m Clauses of 3 Literals)"] ThreeSAT -->|"Clause Triangles +
Conflict Edges (K = m)"| IndSet["Independent Set
(|I| >= K)"] IndSet -->|"Complement S = V \ I
(K' = |V| - K)"| VertexCover["Vertex Cover
(|S| <= |V| - K)"] IndSet -->|"Complement Graph G_bar"| Clique["Clique
(|C| >= K)"] VertexCover -->|"Base-4 Incidence Numbers"| SubsetSum["Subset Sum /
0-1 Knapsack"]
3. Anatomy of the Core Reductions
- $\text{3-SAT} \le_p \text{Independent Set}$: Given a 3-CNF formula with $m$ clauses, create a triangle of $3$ vertices for each clause (so any independent set can pick at most $1$ vertex per triangle, max $m$ vertices total). Add conflict edges between every literal $x_i$ and its negation $\neg x_i$ across all clauses. Then the graph has an Independent Set of size $K = m$ if and only if one true literal can be chosen from every clause without contradiction!
- $\text{Independent Set} \equiv_p \text{Vertex Cover}$ (Gallai's Identity): In any graph $G = (V, E)$, a subset $I \subseteq V$ has no internal edges (Independent Set) if and only if its complement $S = V \setminus I$ touches every edge in $E$ (Vertex Cover)! Thus $\alpha(G) + \tau(G) = |V|$.
- $\text{Vertex Cover} \le_p \text{Subset Sum}$: Encode each vertex $v_i$ and edge $e_j$ as digits in a base-4 number with $|E| + 1$ columns (column $0$ has weight $4^{|E|}$ counting chosen vertices, and column $j$ tracks how many endpoints cover edge $e_j$). Adding a slack number $4^{j}$ per edge allows reaching target sum $K \cdot 4^{|E|} + \sum_{j=0}^{|E|-1} 2 \cdot 4^j$ with zero carry between columns iff a Vertex Cover of size $K$ exists!
4. Strong NP-Completeness vs Weak (Pseudo-Polynomial) NP-Completeness
Why $O(N W)$ Knapsack Is NOT a Polynomial-Time Algorithm
In complexity theory, input size is measured in bits: an integer capacity $W$ requires $b = \lceil \log_2 W \rceil$ bits to write down. Therefore, $O(N W) = O(N \cdot 2^b)$ is exponential in the bit-length $b$ (a pseudo-polynomial algorithm)! Problems like Subset Sum, Partition, and 0-1 Knapsack are Weakly NP-Complete (solvable in polynomial time if numbers are given in unary), whereas 3-SAT, Clique, TSP, and 3-Partition remain NP-Complete even when all numbers are polynomial in $N$ (Strongly NP-Complete).
5. Complexity Matrix: Tractable Twins vs NP-Complete Counterparts
Simulate Karger random multigraph edge contractions down to 2 supernodes, 3-SAT ≤_p Vertex Cover gadget graphs, and Knapsack FPTAS value-bucket scaling K = εP/n.
Invariant & State
| Tractable Problem in $\mathbf{P}$ | Time Complexity | NP-Complete Twin | Why the Twin Jumps to NP-Complete |
|---|---|---|---|
| 2-SAT (2 literals/clause) | O(N + M) (Tarjan SCC) | 3-SAT (3 literals/clause) | $(a \lor b \lor c)$ branches into 2 choices on falsification |
| Shortest Path (No Neg Cycles) | O(M + N log N) | Longest Simple Path / Hamiltonian | Simple-path non-repeating vertex constraint |
| Eulerian Circuit (Visit Every Edge) | O(N + M) (Hierholzer) | Hamiltonian Cycle (Visit Every Vertex) | Local degree parity suffices for edges, not vertices |
| Minimum Cut ($s$-$t$ or Global) | O(V^2 E) (Dinic) | Maximum Cut (MAX-CUT) | Submodular (min) vs Supermodular (max) cut function |
| Vertex Cover on Bipartite Graphs | O(E sqrt(V)) (Kőnig/HK) | Vertex Cover on General Graphs | Odd cycles break LP integrality gap |
6. Production-Grade C++20 Implementation (Karp Reduction $\text{3-SAT} \to \text{Independent Set}$)
#include <vector>
#include <utility>
#include <cmath>
struct Clause3 {
// Literals encoded as +var (1..num_vars) or -var (-1..-num_vars)
int lit[3];
};
struct IndependentSetInstance {
int num_vertices;
int target_k;
std::vector<std::pair<int, int>> edges;
};
// Polynomial-time Karp reduction: 3-SAT (m clauses) <=_p Independent Set (3m vertices, K = m)
IndependentSetInstance reduce_3sat_to_independent_set(const std::vector<Clause3>& clauses) {
const int m = static_cast<int>(clauses.size());
IndependentSetInstance out;
out.num_vertices = 3 * m;
out.target_k = m;
// 1. Add triangle edges inside each clause c (at most 1 vertex chosen per clause)
for (int c = 0; c < m; ++c) {
int u0 = 3 * c, u1 = 3 * c + 1, u2 = 3 * c + 2;
out.edges.emplace_back(u0, u1);
out.edges.emplace_back(u1, u2);
out.edges.emplace_back(u0, u2);
}
// 2. Add conflict edges between complementary literals (x and -x)
for (int c1 = 0; c1 < m; ++c1) {
for (int i = 0; i < 3; ++i) {
for (int c2 = c1 + 1; c2 < m; ++c2) {
for (int j = 0; j < 3; ++j) {
if (clauses[c1].lit[i] == -clauses[c2].lit[j]) {
out.edges.emplace_back(3 * c1 + i, 3 * c2 + j);
}
}
}
}
}
return out;
}
Production Pitfall — Reversing the Reduction Direction ($B \le_p \text{3-SAT}$ Instead of $\text{3-SAT} \le_p B$)
The #1 mistake in algorithms interviews and exams is reducing your target problem $B$ into 3-SAT or an ILP solver to prove $B$ is NP-Hard! Showing $B \le_p \text{3-SAT}$ only proves that $B$ is no harder than 3-SAT (which is true even for trivial problems like sorting!). To prove $B$ is NP-Hard, you must reduce a known hard problem FROM $\text{3-SAT} \le_p B$, embedding any arbitrary 3-SAT formula into an instance of $B$.