Algorithms
The Held-Karp TSP Algorithm
Exact travelling salesman — in O(2ⁿ·n²) instead of O(n!)
The Held-Karp algorithm solves the Travelling Salesman Problem exactly using bitmask dynamic programming over subsets of cities. It keeps a table dp[S][j] holding the cheapest path that starts at the origin, visits exactly the cities in the bitmask S, and ends at city j. This runs in O(2ⁿ·n²) time and O(2ⁿ·n) space — an exponential speedup over the O(n!) brute-force tour enumeration, yet still exponential. Michael Held and Richard Karp published it in 1962; Richard Bellman derived the same recurrence independently the same year.
- TimeO(2ⁿ · n²)
- SpaceO(2ⁿ · n)
- Brute-force baselineO(n!)
- TechniqueBitmask DP over subsets
- OptimalityExact (not approximate)
- Practical limit~18–20 cities on one machine
- Published1962 (Held & Karp; Bellman independently)
Interactive visualization
Press play, or step through manually. The visualization is yours to drive — try it before reading on.
Watch the 60-second explainer
A condensed visual walkthrough — narrated, captioned, under a minute.
The problem it solves
The Travelling Salesman Problem (TSP) asks: given n cities and the pairwise distances between them, what is the shortest tour that starts at one city, visits every other city exactly once, and returns to the start? It is one of the most famous NP-hard problems in computer science — the decision version is NP-complete, and no polynomial-time exact algorithm is known (or expected, unless P = NP).
The naive exact approach fixes a starting city and tries every ordering of the remaining n−1 cities. That is (n−1)! permutations, or (n−1)!/2 if you dedupe mirror-image tours in a symmetric instance. Factorial growth is brutal: at just 15 cities that is already over 43 billion tours. Held-Karp is the classic way to trade that factorial for a merely exponential 2ⁿ — the same asymptotic idea that turns a naive exponential recursion into a polynomial table in dozens of other dynamic-programming problems, applied to a problem where the honest answer is still exponential but far better than factorial.
The key insight: subsets, not permutations
Brute force wastes enormous effort. Consider two different tours that both begin 0 → 3 → 7 → 2 and then diverge. The cost of getting from the origin to city 2 having visited {3, 7} along the way is identical in both, yet brute force recomputes it every single time it appears inside a full permutation.
Held-Karp's insight is that the future of a partial tour depends only on two things — which cities have already been visited and which city you are currently standing in — not on the exact order you visited them in. So we collapse "the order so far" into a set. That set is stored as a bitmask: an n-bit integer where bit i is 1 iff city i is in the set. This is the optimal-substructure property that makes dynamic programming apply.
How Held-Karp works, step by step
Fix city 0 as the origin. Define the DP state:
dp[S][j]— the minimum cost of a path that starts at city 0, visits exactly the cities in bitmaskS, and ends at cityj. Here j must be a member of S, and by convention bit 0 (the origin) is set in every S.
Base case. The path that has visited only the origin and ends there costs nothing: dp[{0}][0] = 0.
Transition (relaxation). To reach city j having visited set S, you must have arrived from some predecessor city k that was the previous endpoint of the path over the smaller set S \ {j}:
dp[S][j] = min over k ∈ S, k ≠ j, k ≠ 0 (or k = 0 only when S = {0, j}) of dp[S \ {j}][k] + dist[k][j]
Order of evaluation. A state over set S depends only on states over the strictly smaller set S \ {j}. Since removing a bit always yields a smaller integer, iterating masks S in increasing numeric order guarantees every dependency is already computed — the same topological ordering trick used throughout subset DP.
Closing the tour. The states above compute open paths. To close the cycle, add the return edge back to the origin and take the best endpoint:
answer = min over j ≠ 0 of dp[FULL][j] + dist[j][0]
where FULL = (1 << n) − 1 is the mask with every city visited.
Why the complexity is O(2ⁿ·n²)
Count the work directly:
- There are 2ⁿ possible subsets S.
- For each subset, there are up to n choices of endpoint j.
- So there are 2ⁿ·n DP states — this is also the space, O(2ⁿ·n).
- Filling one state means minimizing over up to n predecessors k, an extra factor of n.
Multiply: 2ⁿ·n·n = O(2ⁿ·n²) time. The 2ⁿ term dominates everything; the n² is polynomial noise beside it. This is a genuine exponential-to-exponential improvement over factorial, not a fix for NP-hardness — Held-Karp is still exponential, and no one has found an exact TSP algorithm that beats the 2ⁿ base (up to polynomial factors) in over sixty years.
Held-Karp vs other TSP approaches
| Brute force | Held-Karp | Christofides | Branch-and-cut (Concorde) | |
|---|---|---|---|---|
| Result | Exact optimum | Exact optimum | ≤ 1.5× optimum (metric) | Exact optimum |
| Time | O(n!) | O(2ⁿ·n²) | O(n³) | Exponential worst case |
| Space | O(n) | O(2ⁿ·n) | O(n²) | Varies (LP + cuts) |
| Needs triangle inequality? | No | No | Yes (metric TSP) | No |
| Handles asymmetric distances? | Yes | Yes | No | Yes (ATSP variants) |
| Practical size | ~11 cities | ~18–20 cities | Thousands+ | Tens of thousands+ |
| Best for | Never (teaching only) | Small exact instances | Fast metric approximation | Large exact instances |
Implementation in Python
from math import inf
def held_karp(dist):
"""Exact TSP tour cost + order via bitmask DP. dist is an n x n matrix.
Returns (cost, tour) with the tour starting and ending at city 0."""
n = len(dist)
FULL = (1 << n) - 1
# dp[mask][j] = min cost path from 0, visiting exactly `mask`, ending at j.
# parent[mask][j] = predecessor k that achieved the minimum (for reconstruction).
dp = [[inf] * n for _ in range(1 << n)]
parent = [[-1] * n for _ in range(1 << n)]
dp[1][0] = 0 # base case: only city 0 visited, standing at 0
for mask in range(1 << n):
if not (mask & 1): # every subset must include the origin
continue
for j in range(n):
if dp[mask][j] == inf: # unreachable state — skip
continue
for k in range(n): # try to extend the path to a new city k
if mask & (1 << k): # k already visited
continue
nxt = mask | (1 << k)
cand = dp[mask][j] + dist[j][k]
if cand < dp[nxt][k]:
dp[nxt][k] = cand
parent[nxt][k] = j
# Close the tour: return to city 0 from the best final endpoint.
best, last = inf, -1
for j in range(1, n):
cand = dp[FULL][j] + dist[j][0]
if cand < best:
best, last = cand, j
# Reconstruct the order by walking parent pointers backward.
tour, mask, j = [], FULL, last
while j != -1:
tour.append(j)
pj = parent[mask][j]
mask ^= (1 << j) # remove j from the set
j = pj
tour.reverse() # now starts at 0
tour.append(0) # close the cycle back to origin
return best, tour
Note the "forward push" style used here: instead of pulling from predecessors, each reachable state dp[mask][j] relaxes every unvisited city k and updates dp[mask | (1<<k)][k]. It computes exactly the same table as the pull recurrence and is often easier to write correctly. The parent array is the only addition needed to recover the tour itself rather than just its length.
Common misconceptions and pitfalls
- "Held-Karp makes TSP polynomial." It does not. TSP is NP-hard; Held-Karp is still exponential (2ⁿ). It only beats the factorial naive method. If anything advertised solves TSP in polynomial time, be very skeptical.
- Memory, not time, is the real wall. The 2ⁿ·n table is what kills you first. At n = 25 the table has 2²⁵·25 ≈ 840 million cells; even one byte each would be near a gigabyte, and you need more than a byte per cost. This is why the practical ceiling is ~20 cities, not because the CPU is too slow.
- Forgetting to pin the origin into every mask. If you don't guarantee bit 0 is set (or don't skip masks lacking it), you waste half the table and can produce paths that never start at the origin. The
if not (mask & 1): continueguard handles this. - Confusing "path" states with "tour" cost. The DP table stores open paths. You must add the closing edge
dist[j][0]at the end. Reportingmin dp[FULL][j]without the return edge gives the shortest Hamiltonian path, not the shortest tour. - Assuming symmetry. Held-Karp works fine on asymmetric matrices (
dist[a][b] ≠ dist[b][a]). Don't "optimize" by halving the state space assuming mirror tours are equal — that only holds for symmetric TSP.
A little history
In 1962 Michael Held and Richard M. Karp published "A Dynamic Programming Approach to Sequencing Problems" in the Journal of the Society for Industrial and Applied Mathematics, framing TSP as a sequencing problem solvable by dynamic programming over subsets. That same year, Richard Bellman — the father of dynamic programming itself — described the identical recurrence independently, which is why some texts call it the Bellman–Held–Karp algorithm. Richard Karp would later go on to define the class of 21 NP-complete problems (1972), of which TSP's decision variant is a canonical member. More than sixty years on, Held-Karp is still the textbook exact TSP algorithm and still holds the best-known worst-case exponential bound of 2ⁿ up to polynomial factors — a striking testament to how hard genuine improvement over it has proven to be.
Frequently asked questions
What is the time complexity of the Held-Karp algorithm?
Held-Karp runs in O(2ⁿ·n²) time and uses O(2ⁿ·n) space, where n is the number of cities. There are 2ⁿ subsets and n possible endpoints, giving 2ⁿ·n dynamic-programming states; filling each state requires trying up to n predecessor cities, adding a final factor of n. That is dramatically faster than the O(n!) brute-force enumeration of all tours, but it is still exponential — the 2ⁿ factor caps practical use at roughly 20 cities on a single machine, where 2²⁰·20² ≈ 4×10⁸ operations.
How is Held-Karp faster than brute force if both are exponential?
Brute force examines all (n−1)!/2 distinct tours, which grows as a factorial. Held-Karp reuses the shortest sub-path to a subset of cities instead of re-deriving it inside every full tour that contains that subset — classic dynamic programming. The number of subset-endpoint states is only 2ⁿ·n, so the factorial blowup collapses to 2ⁿ. For n = 20, brute force is about 6×10¹⁶ tours while Held-Karp does about 4×10⁸ operations — roughly 100 million times fewer, even though 2ⁿ still grows exponentially.
What does the state dp[S][j] mean in Held-Karp?
dp[S][j] is the minimum cost of a path that starts at the fixed origin city 0, visits exactly the set of cities encoded by bitmask S, and ends at city j (where j must be a member of S). Bit i of S is 1 when city i has been visited. The recurrence is dp[S][j] = min over k in S\{j} of dp[S\{j}][k] + dist[k][j], meaning the best way to reach j through set S is the best way to reach some predecessor k through S without j, plus the edge from k to j.
What is the largest TSP that Held-Karp can solve in practice?
On a single modern machine, Held-Karp is practical up to about 18–20 cities. The 2ⁿ·n memory table is the binding constraint: at n = 20 the table holds 2²⁰·20 ≈ 21 million entries, and each doubling of n roughly doubles both time and memory. Beyond ~25 cities the table no longer fits in RAM. Real-world instances with thousands of cities are solved instead with branch-and-cut solvers such as Concorde, which use linear-programming relaxations and are exponential only in the worst case.
Who invented the Held-Karp algorithm and when?
The algorithm was published in 1962 by Michael Held and Richard M. Karp in their paper 'A Dynamic Programming Approach to Sequencing Problems.' Richard Bellman independently described the same dynamic-programming formulation in the same year, which is why it is sometimes called the Bellman–Held–Karp algorithm. It remains the classic reference for exact TSP by dynamic programming and, as of today, no algorithm is known with a better worst-case exponential bound than 2ⁿ up to polynomial factors.
Does Held-Karp require the triangle inequality or a metric space?
No. Held-Karp is exact for any distance matrix, including asymmetric ones where dist[a][b] ≠ dist[b][a], and it does not need the triangle inequality. It simply reads dist[k][j] from the matrix during relaxation. The triangle inequality matters only for approximation algorithms such as Christofides, whose 1.5-approximation guarantee requires a metric; Held-Karp gives the exact optimum regardless.
Can Held-Karp recover the actual optimal tour, not just its length?
Yes. Store a parent pointer parent[S][j] recording which predecessor k achieved the minimum for dp[S][j]. After computing the answer min over j of dp[full][j] + dist[j][0], follow the parent pointers backward from the winning endpoint through shrinking subsets until you return to the origin, then reverse the sequence. This adds only the same O(2ⁿ·n) space already used for the table and O(n) time for reconstruction.