The Exact TSP Problem
Given costs $d(i,j)$ between $n$ cities, find a minimum-cost cycle that starts at city $0$, visits every other city exactly once, and returns to $0$. Costs may be symmetric, as with ordinary distances, or asymmetric, as with one-way travel times.
Fixing city $0$ removes rotations of the same cycle, but brute force still considers $(n-1)!$ orders. Held–Karp replaces those full histories with reusable summaries.
Subset
Which cities have already been visited?
Endpoint
At which visited city does the current path end?
Best cost
What is the cheapest prefix with exactly those two facts?
Compressing Route Histories
Different visit orders can lead to the same visited set and endpoint. Their past costs differ, but every legal continuation available from that state is identical. The more expensive prefix is therefore dominated: appending the same future can never make it cheaper.
Intuition: Keep the Cheapest Receipt
If two travelers have visited the same cities and now stand at the same place, their remaining options are identical. Keep the smaller receipt and forget how that traveler arrived.
State and Recurrence
Let $DP[S][j]$ be the minimum cost of a path that starts at $0$, visits exactly the cities in $S$, and ends at $j$. Valid states contain both $0$ and $j$.
The base state is $DP[\{0\}][0]=0$. The recurrence asks one question: which city $k$ was visited immediately before $j$? Remove $j$, solve the smaller endpoint state at $k$, then add the final edge $k\to j$.
After all cities are visited, the path is not yet a tour. Close it explicitly:
State Meaning Is the Invariant
Every table entry must mean “visit exactly this set and end here.” Accidentally allowing an unvisited endpoint, omitting city $0$, or reusing a city destroys the recurrence's meaning even if the program still produces numbers.
Bitmask Representation
A bitmask stores subset membership in one integer. Bit $i$ is $1$ exactly when city $i$ belongs to the subset. For four cities, mask $1101_2$ represents $\{0,2,3\}$.
| Question | Bit operation | Example with city $j$ |
|---|---|---|
| Is $j$ visited? | test | mask & (1 << j) |
| Add $j$ | bitwise OR | mask | (1 << j) |
| Remove $j$ | clear bit | mask ^ (1 << j) when membership is known |
| Full set | lowest $n$ bits | (1 << n) - 1 |
Bitmasks are not what makes the recurrence correct; they make dense subset tables compact, indexable, and fast. A sparse map keyed by subsets can express the same DP when only selected states should be stored.
Four-City Trace
Use the symmetric distance matrix from the implementation:
| 0 | 1 | 2 | 3 | |
|---|---|---|---|---|
| 0 | 0 | 10 | 15 | 20 |
| 1 | 10 | 0 | 35 | 25 |
| 2 | 15 | 35 | 0 | 30 |
| 3 | 20 | 25 | 30 | 0 |
For example, the full-set state ending at city $2$ is
The two candidates correspond to arriving from city $1$ or city $3$. Closing from $2$ adds $d(2,0)=15$, producing an optimal tour cost of $80$.
Reconstructing the Tour
A cost table alone forgets which predecessor achieved each minimum. Store parent[mask][j] whenever a transition improves a state. After choosing the best final endpoint, repeatedly:
- record the current endpoint $j$;
- read its predecessor $k=parent[mask][j]$;
- clear bit $j$ from the mask and continue from $k$;
- reverse the recovered prefix, then append city $0$ to close the cycle.
Ties Are Normal
The table may have several equally good predecessors. Keeping one reconstructs one optimal tour. Enumerating every optimal tour requires storing all minimizing predecessors and can produce exponentially many answers.
Why the Recurrence Is Correct
Prove the state invariant by induction on $|S|$. The base state $DP[\{0\}][0]=0$ is correct. For a larger state $(S,j)$, every valid path must enter $j$ from exactly one predecessor $k\in S\setminus\{j\}$. Before that last edge, it is a path for state $(S\setminus\{j\},k)$.
By the induction hypothesis, the table stores the cheapest such prefix. Replacing it with any more expensive prefix cannot improve the completed path, so minimizing over every possible predecessor finds the cheapest path for $(S,j)$. Finally, every Hamiltonian tour has one last city before returning to $0$; minimizing over that endpoint examines every possible tour ending.
Why Dominance Is Safe
Two prefixes in one state have the same unvisited cities and the same current location. Any suffix feasible for one is feasible for the other at exactly the same added cost. The cheaper prefix therefore dominates for every continuation—not merely for the next step.
Implementation
All three versions now retain predecessor choices and return one optimal tour as well as its cost. They use a dense table for clarity; memory becomes the practical bottleneck before the bit-shift limit does.
Complexity and the Memory Wall
There are $2^n$ masks, up to $n$ endpoints per mask, and up to $n$ next-city transitions per reachable state:
The dense implementation allocates $n2^n$ table cells even though many are invalid. Fixing city $0$ and storing only reachable endpoint states improves constants, not the exponential class.
| $n$ | Dense cost cells $n2^n$ | Brute-force orders $(n-1)!$ | Practical lesson |
|---|---|---|---|
| 15 | 491,520 | 87,178,291,200 | DP is dramatically smaller |
| 20 | 20,971,520 | $1.216\times10^{17}$ | memory layout starts to dominate |
| 25 | 838,860,800 | $6.204\times10^{23}$ | even the DP table is enormous |
Big-O Hides Representation Cost
At $n=25$, the cost table alone contains about $839$ million cells. Eight-byte costs require roughly $6.25$ GiB before parents, row objects, allocator overhead, or the distance matrix. A Python list-of-lists representation requires far more.
If only the optimum value is needed, process states by subset size and keep fewer layers, or store reachable states sparsely. If the tour must be reconstructed, retain parents, recompute selected layers, or use a divide-and-conquer reconstruction strategy. Each choice trades memory, runtime, and implementation complexity.
Useful Variants
| Goal | Change | What stays the same |
|---|---|---|
| asymmetric TSP | use directed costs $d(i,j)$ as given | the recurrence is unchanged |
| Hamiltonian path | omit the return edge; minimize over allowed endpoints | subset-and-endpoint states |
| fixed final city | read only $DP[V][t]$ before optional closure | all earlier transitions |
| precedence rules | skip adding a city until its prerequisites are in the mask | bitmask membership tests |
| missing edges | use infinity and detect an unreachable final state | min-plus recurrence |
Be careful when adding time windows, vehicle capacity, or several salespeople. Subset and endpoint may no longer summarize every fact relevant to the future; extra state dimensions or a different optimization model are then required.
Common Pitfalls and a Reliable Checklist
| Pitfall | Why it fails | Reliable practice |
|---|---|---|
| forgetting $d(j,0)$ | solves a path, not a tour | close every full-set endpoint explicitly |
| allowing masks without bit $0$ | creates states with the wrong start | skip them or encode subsets excluding $0$ consistently |
| using zero for “unreached” | zero-cost edges become ambiguous | initialize with a safe infinity |
| overwriting without a strict improvement | parents may not match the stored cost | update cost and parent together |
| 32-bit totals | long tours may overflow | use a wide type and bounded infinity |
| assuming the tour is unique | tests reject another optimum | verify city coverage and total cost |
| allocating before estimating | the process can exhaust memory | calculate $n2^n$ cells first |
Implementation Checklist
Validate a square matrix; define missing-edge semantics; fix the start convention; use a safe numeric type; estimate table memory; track parents only when needed; and test the returned cycle independently of its orientation.
Where Held–Karp Is Useful
Exact Route Optimization for Small Fleets
For a genuinely small stop set, Held–Karp can provide an exact route and an optimality certificate by exhaustive dynamic programming. That makes it useful as a correctness oracle for testing heuristics, as an exact solver for small batches, or as a subproblem inside a larger decomposition. The workable size depends heavily on language, memory layout, and available hardware.
- Benchmarking: measure the optimality gap of nearest-neighbor, local-search, or learned routing methods on small instances.
- Sequencing: order a small set of manufacturing, inspection, or robotic operations with pairwise transition costs.
- Clustered optimization: solve small clusters exactly while a higher-level heuristic connects the clusters.
- Subset-DP template: adapt the same mask-and-endpoint pattern to Hamiltonian paths, precedence-constrained tours, and other sequencing problems.
Exercises
- Trace: verify all six size-three endpoint values in the second SVG directly from the distance matrix.
- Dominance: prove formally that an expensive prefix can be discarded when its subset and endpoint match a cheaper prefix.
- Bitmasks: list every valid state for mask
1101and explain why endpoints $1$ and $0$ are not both ordinary choices. - Asymmetry: change $d(1,3)$ without changing $d(3,1)$ and recompute the optimal directed tour.
- Path variant: modify the Python function to accept specified start and end cities without closing the cycle.
- Verification: compare the returned cost with brute-force enumeration for random matrices up to $n=9$.
History and Takeaway
Michael Held and Richard Karp published their dynamic-programming treatment of sequencing problems in 1962. Richard Bellman published an independent dynamic-programming treatment of TSP in the same year, which is why the method is also called Bellman–Held–Karp.
The Mental Model to Keep
Held–Karp does not pretend route order is irrelevant. It proves that the future needs only two facts about the past: the set already visited and the current endpoint. For each such state, keep the cheapest receipt, extend it to one new city, and remember the winning predecessor if the route itself must be recovered.