Complexity Theory
Complexity classes and P vs NP
Which problems are tractable, and the biggest open question
Some problems are trivial to check yet seem impossibly hard to solve - and after fifty years, nobody can prove they truly are.
Hand someone a completed Sudoku and they can confirm it's correct in seconds - scan every row, column, and box. Hand them a blank one and the work explodes: they may have to try astronomically many fillings before one clicks. That yawning gap between checking a solution and finding one is the whole subject of complexity theory - and the single biggest open question in computer science lives inside it.
Solve vs verify
Two ways to be hard: solving vs checking
We measure cost with Big-O in the input size . A cost like , , or is polynomial - it grows gently and we call such problems tractable. A cost like is exponential - it doubles with every extra unit of input and is intractable in practice. Two classes carve up the world:
- P - problems solvable in polynomial time. Sorting, binary search, shortest paths (Dijkstra), matrix multiply. These we can actually run.
- NP - problems whose proposed solutions are verifiable in polynomial time. Formally, when there is a polynomial-time checker and a polynomial bound such that
Read as the certificate - the filled-in Sudoku, the satisfying assignment, the route. NP says: if someone whispers you the right , you can check it fast. It says nothing about how hard was to find. Every problem in P is trivially in NP (just re-solve it to check), so . The trillion-dollar question is whether that containment is strict.
# VERIFY: given an assignment, is every clause satisfied? - O(m), polynomial
def verify(clauses, assignment):
for clause in clauses: # m clauses
if not any(assignment[v] ^ neg # is any literal true?
for (v, neg) in clause):
return False
return True # all satisfied → certificate is valid
# SOLVE: no certificate handed to us - try every assignment - O(2**n * m)
def solve(clauses, n):
for bits in range(2 ** n): # 2**n candidates (!)
a = [(bits >> i) & 1 for i in range(n)]
if verify(clauses, a):
return a
return None # unsatisfiableThe race: verify in a blink, solve for centuries
Below is a real Boolean satisfiability (SAT) instance: variables and clauses, each an OR of three literals. You're handed a certificate - a proposed assignment that happens to satisfy every clause. Press Race: on the left, the verifier checks all clauses and finishes almost instantly. On the right, a solver with no certificate must brute-force the space of assignments. Now drag upward and watch the right side fall off a cliff.
check each clause once - m operations, polynomial
no certificate - try assignments, up to 2ⁿ
Full 2ⁿ search would take ≈ 8.6 days. Press Race.
At n = 42: verifying tests m = 168 clauses; solving tests up to 2ⁿ = 4.40 × 10¹² assignments - a gap of exactly 2ⁿ, even at a billion checks per second.
The gap is exactly 2ⁿ - and that asymmetry is for sale
The map: P, NP, NP-complete, NP-hard
Inside NP sits a spine of the hardest problems, tied together by reductions. We write (" reduces to ") when any instance of can be rewritten, in polynomial time, as an instance of - so a fast solver for instantly becomes a fast solver for . Reductions let one problem inherit another's hardness.
- NP-hard - at least as hard as every problem in NP (everything in NP reduces to it). It need not itself be in NP.
- NP-complete - the sweet, terrifying spot: in NP and NP-hard. These are the hardest problems that still have fast verifiers. Crack one in polynomial time and you crack them all.
| Class | Solve fast? | Check fast? | Examples |
|---|---|---|---|
| P | yes | yes | binary search, Dijkstra, sorting |
| NP | unknown | yes | SAT, graph coloring, subset-sum |
| NP-complete | no known way | yes | 3-SAT, Hamiltonian cycle, knapsack |
| NP-hard | no known way | not necessarily | TSP optimization, halting problem |
The keystone is the Cook-Levin theorem (Stephen Cook 1971, Leonid Levin independently): SAT is NP-complete - every problem in NP reduces to it. That's why SAT is the demo's star: it is the universal NP problem, and a polynomial-time SAT solver would collapse all of NP into P. Because thousands of practical problems - scheduling, routing, protein folding, chip layout - are NP-complete, they all stand or fall together. Almost every expert believes (checking really is easier than solving), but no one has proved it. It is one of the Clay Institute's Millennium Prize Problems, with a one-million-dollar bounty and a half-century of failed attempts.
Check yourself
NP is exactly the set of problems whose proposed solutions can be:
Modern cryptography works because some problems are believed to be:
Recall: what precisely does P vs NP ask?
Try to state it, then check.
Lock it in
- P is the class of problems solvable in polynomial time; NP is the class whose proposed solutions are verifiable in polynomial time. , and whether that containment is strict is the open question.
- The gap between checking a certificate and finding one is the whole subject: for NP-complete problems verifying is cheap while every known solver is exponential.
- SAT is NP-complete (Cook-Levin): every NP problem reduces to it, so a polynomial-time SAT solver would collapse all of NP into P.
- Cryptography sells exactly that one-way asymmetry - easy to verify, believed hard to forge. Nearly everyone believes , but no one has proved it.
Primary source
Ask your teacher