A Bit of History
From a Victorian puzzle to NP-completeness
Hamiltonian Cycle, Hamiltonian Path, and TSP
Hamiltonian path
Visits every vertex exactly once; its two endpoints need not be adjacent.
Hamiltonian cycle
Visits every vertex exactly once and then closes back to the first vertex.
Traveling salesperson
Optimizes the total weight of a Hamiltonian cycle rather than merely asking whether one exists.
For a simple undirected graph, a Hamiltonian cycle has at least three vertices. The repeated start vertex is normally shown only to make closure explicit: $[0,1,2,3,0]$ represents three distinct visited vertices plus the return edge.
Choose, Explore, Undo
- Break rotational symmetry. Fix vertex 0 as the start; any Hamiltonian cycle can be rotated to begin there.
- Choose. From the current endpoint, append one adjacent unvisited vertex and mark it used.
- Explore. Recurse. If all vertices are present, accept only when the endpoint connects to the start.
- Undo. If the branch fails, remove the last vertex, clear its visited flag, and try the next candidate.
- Stop or exhaust. Return the first cycle found, or report failure after every candidate prefix has been ruled out.
Visual Path Walkthrough
Both panels use the same six-vertex graph: a hexagon plus chords $0$–$2$ and $2$–$4$. Choosing neighbor 1 leads directly around the outer cycle. Choosing chord $0$–$2$, then $2$–$4$, then $4$–$3$ traps the endpoint because both neighbors of 3 are already used.
The Search Tree, Not Just the Graph
The algorithm explores a second structure: a tree whose nodes are partial paths. A graph vertex may appear in many search-tree nodes because it can be reached under different visited sets. Backtracking is depth-first traversal of this implicit tree.
path.pop() or visited[candidate] = false corrupts every later branch.Safe Pruning Rules
| Rule | When it rejects | Cost / value |
|---|---|---|
| Adjacency | The next vertex is not adjacent to the current endpoint. | Constant-time with a matrix; fundamental pruning. |
| Visited | The candidate already appears in the path. | Prevents repetition in constant time. |
| Initial degree | Some vertex has degree below 2 in a simple cycle instance. | Cheap necessary-condition precheck. |
| Connectivity / cut vertex | The graph is disconnected, has a bridge, or has an articulation point. | A Hamiltonian cycle on $V\ge3$ is 2-vertex-connected. |
| Remaining frontier | Unvisited vertices plus the two path endpoints cannot remain connected or satisfy future degree needs. | Stronger but costs extra work per search node. |
| Candidate ordering | Does not reject; tries the most constrained neighbor first. | Can expose failure earlier without changing correctness. |
Pruning must prove impossibility
A heuristic ordering may be wrong about which branch is promising, so it may only change search order. A pruning rule deletes a branch permanently and must therefore be a necessary condition for every completion of that partial path.
Necessary Conditions vs. Sufficient Theorems
Necessary checks can quickly prove no: connectivity, minimum degree at least two, absence of bridges and articulation points, and—in a bipartite graph—equal partition sizes. None of these alone proves a cycle exists.
Sufficient theorems can quickly prove yes. For a simple graph with $n\ge3$, Dirac’s condition $deg(v)\ge n/2$ for every vertex guarantees Hamiltonicity. Ore’s condition $deg(u)+\deg(v)\ge n$ for every nonadjacent pair also guarantees it. Graphs can be Hamiltonian without satisfying either condition, so failure of the theorem’s premise means “unknown,” not “no.”
Implementation
The following versions target simple undirected graphs represented by an adjacency matrix. They fix start vertex 0, restore state on every failed branch, reject graphs with fewer than three vertices, and return the repeated start vertex so the closing edge is visible.
What this reference implementation optimizes
An adjacency matrix makes candidate checks $O(1)$ and keeps the recurrence readable. On sparse graphs, iterating only over the current vertex’s neighbors reduces useless candidate tests. In either representation, candidate ordering changes practical speed but not the factorial worst case.
Complexity and Exact Alternatives
Fixing the start removes rotational duplicates, leaving at most $(V-1)!$ vertex orders. Backtracking can still explore a factorial number of prefixes in adversarial graphs:
The auxiliary space covers the path, visited set, and recursion stack. The shown adjacency matrix itself occupies $O(V^2)$. A memoized subset dynamic program—often associated with Held–Karp—trades memory for a better exact bound of roughly $O(V^2 2^V)$ time and $O(V2^V)$ space.
| Approach | Typical strength | Main cost |
|---|---|---|
| Backtracking | Simple, low memory, benefits strongly from structure and pruning. | Factorial worst case; performance depends on ordering. |
| Subset DP | Predictable $2^V$-scale exact method for modest $V$. | Exponential memory. |
| SAT / ILP / CP | Powerful propagation and easy addition of side constraints. | Requires a solver and careful formulation. |
| Heuristics | Can find good tours quickly in large optimization instances. | Cannot certify nonexistence unless embedded in an exact method. |
Hamiltonian vs. Eulerian: Do Not Mix Them Up
| Question | Hamiltonian cycle | Eulerian circuit |
|---|---|---|
| Visit exactly once | Vertices | Edges |
| Vertices may repeat | No, except the repeated start that closes the cycle. | Yes. |
| General decision test | NP-complete; no known polynomial-time test. | $O(V+E)$ via connectivity and even-degree conditions. |
| Constructive algorithm | Backtracking, subset DP, or exact solver. | Hierholzer’s algorithm in linear time. |
Real-World Applications
Puzzles and tours
Model Knight’s tours, board traversals, and route puzzles as vertex-once searches.
Sequencing constraints
Ask whether tasks or states can be ordered once each under allowed-transition rules.
Routing foundations
Hamiltonian cycles form the feasibility skeleton beneath TSP-style weighted tour optimization.
Real routing and drilling systems usually optimize distance on a weighted graph, making them TSP variants rather than plain Hamiltonian-cycle decision problems. Genome assembly also largely moved from fragment-overlap Hamiltonian formulations toward Eulerian walks in de Bruijn graphs. These connections are best understood as modeling history and shared structure, not identical problems.
Exercises
Explore the search space
- Trace the dead branch $[0,2,4,3]$ and list exactly which candidate checks fail.
- Modify the code to return a Hamiltonian path by removing only the final closing-edge test.
- Add the safe initial checks for connectivity and minimum degree two. Test a path graph and a star.
- Order candidates by the number of their currently unvisited neighbors. Compare recursive-call counts on several graphs.
- Challenge: implement subset DP with state $(S,v)$ meaning “a path from 0 visits exactly $S$ and ends at $v$.”
Hint: instrument the recursive function with a counter; elapsed time alone is noisy when comparing pruning strategies.
Limitations
Exact search still scales exponentially
- No polynomial guarantee: pruning can transform practical performance without changing the NP-complete worst case.
- Recursion depth: the path can be $V$ vertices long; iterative state or stack configuration may be needed.
- Representation cost: matrices give fast lookups but consume $O(V^2)$ memory.
- Directed graphs: adjacency and closure become directional; necessary degree checks must use in- and out-degree.
- Enumeration: finding one cycle is easier than listing all cycles without rotational and reversal duplicates.
Use backtracking when graphs are small, structured, or aggressively constrained. For larger exact instances, compare subset DP and modern SAT/ILP/constraint-programming solvers before committing to a hand-built search.