Hamiltonian Path and Circuit Problems
Imagine a delivery truck that must visit every warehouse in a city exactly once. It must return to the depot afterward. This is not a toy question. It is the daily scheduling headache behind logistics networks, circuit-board drilling, DNA fragment assembly, and even puzzle games like Rubik's-cube-solving tours. The mathematical skeleton of all these problems is the same: given a graph, does there exist a path or cycle that touches every node exactly once? This is the Hamiltonian Path problem (HAMPATH) and its cyclic cousin, the Hamiltonian Circuit problem (HAMCYCLE). What makes these problems a centerpiece of complexity theory is a contrast. They draw a contrast with a superficially similar problem. The Eulerian circuit problem — does a graph have a closed walk using every edge exactly once — has an elegant characterization due to Euler. It also has a polynomial-time algorithm. Hamiltonian circuits, which use every vertex exactly once, have resisted every attempt at an analogous efficient test. This resistance has lasted over a century. Complexity theory explains why: the problem is NP-Complete. No known algorithm beats exponential worst-case time. If one existed, it would collapse the P versus NP hierarchy. This article builds the NP-completeness proof for HAMPATH from the ground up. It uses a gadget reduction from 3-SAT. This is the same style of argument used to show Clique and Vertex Cover are NP-complete. It ultimately rests on the Cook–Levin theorem that seeded the entire theory of NP-completeness. The reduction is one of the most visually satisfying in the subject. Each Boolean variable becomes a two-way "diamond" of vertices. A path can traverse this diamond in either direction. Each clause becomes a small hub vertex. The path can only pass through this hub if at least one adjacent variable-gadget offers a free lane. By the end, you will be able to construct this reduction by hand. You will also verify its correctness with a clean forward/backward argument. You will see precisely why the circuit and path versions of the problem transfer NP-completeness to one another. This sets the stage for later ideas. One example is the asymmetry between NP and coNP, that Hamiltonian-style problems help illustrate.
- HAMPATH asks whether a directed/undirected graph has a path visiting every vertex exactly once; HAMCYCLE asks for such a path that returns to its start.
- Both are in NP: a candidate ordering of vertices is a certificate checkable in polynomial time.
- NP-hardness is shown by a polynomial-time reduction from 3-SAT, using variable gadgets (diamonds) and clause gadgets (hub vertices).
- The reduction transforms any 3-CNF formula into a graph such that the formula is satisfiable iff the graph has a Hamiltonian path.
- HAMPATH and HAMCYCLE reduce to each other in polynomial time, so both are NP-complete.
- The contrast with the polynomial-time solvable Eulerian circuit problem is a classic illustration of how a small change in problem statement can cross the P/NP boundary.
A Hamiltonian path exists in the gadget graph exactly when the encoded 3-CNF formula is satisfiable, because each variable-diamond forces a binary left-to-right or right-to-left traversal choice that models a truth assignment, and each clause-hub can only be visited if some chosen literal "lends" it a detour.
The idea
A Hamiltonian path in a graph is a path that visits every vertex in exactly once (no repeats, no omissions). A Hamiltonian circuit (or Hamiltonian cycle) is a Hamiltonian path that additionally has an edge from the last vertex back to the first, forming a closed tour. The decision problems are:
Both problems are naturally in NP: given a proposed vertex ordering as a certificate, checking that it is a permutation of and that consecutive vertices are joined by edges of takes only time. The entire difficulty is in the search — with vertices there are up to orderings to consider, and no polynomial-time method is known (or believed to exist) to avoid this combinatorial explosion in the worst case. The hardness half of the NP-completeness proof uses a polynomial-time many-one reduction from 3-SAT, written . This means we give an algorithm that, given any 3-CNF formula , runs in time polynomial in and outputs a graph (with designated start and end vertices) such that
Since 3-SAT is NP-complete by the Cook–Levin theorem (via the standard SAT-to-3-SAT reduction), and since this reduction is computable in polynomial time, HAMPATH inherits NP-hardness. Combined with membership in NP, this proves HAMPATH is NP-complete. The technique of building small local structures — gadgets — that simulate variables and clauses is the same craft used for Clique, Vertex Cover, Independent Set, and dozens of other NP-completeness proofs; mastering it here transfers directly to those settings.
How it works
The gadget construction
Fix a 3-CNF formula with variables and clauses , each clause a disjunction of exactly three literals. We build a directed graph as follows.
Variable gadgets (diamonds). For each variable , construct a horizontal chain of vertices between two endpoint vertices, arranged as a "diamond" — really a pair of parallel row structures with intermediate nodes each — such that:
- The diamond can be traversed left-to-right using the top row, corresponding to setting .
- The diamond can be traversed right-to-left using the bottom row, corresponding to setting .
- Crucially, each of the positions in the row corresponds to one of the clause-slots (each clause can mention positively or negatively, so there are up to relevant occurrences, one slot reserved per clause per polarity).
Chain the diamonds together end to end: the right endpoint of diamond connects to the left endpoint of diamond (and also the reverse edge exists, of a special "bridge" form described below), so that a Hamiltonian path must pass through the diamonds in sequence, entering diamond from one side and leaving from the other, with the direction of traversal free to choose independently per diamond — this freedom is exactly a truth assignment.
Clause gadgets (hub vertices). For each clause , create a single vertex . This vertex needs incoming and outgoing edges from exactly the vertices representing "this literal is satisfied by the current traversal direction of its variable's diamond." Concretely, each diamond has, for every clause it appears in, a small pair of extra edges that detour through if and only if the diamond is traversed in the direction making that literal true. The clause vertex has degree bounded by (at most three literals, each contributing an in/out detour pair), so checking or constructing it takes constant work per clause.
Global start and end. Add a designated start vertex feeding into the first diamond and an end vertex receiving from the last diamond. The essential engineering fact, which must be verified carefully, is: > A Hamiltonian path from to must pass through each variable diamond in one single consistent direction (it cannot enter and exit the diamond multiple times without skipping or repeating vertices), and it may detour to pick up a clause vertex only while passing a diamond segment corresponding to a literal of that is true under the direction chosen. This is the crux gadget-design invariant, proved in the Complexity & Correctness section below.
Algorithm: constructing the reduction
``` function REDUCE-3SAT-TO-HAMPATH(phi):
# phi has variables x_1..x_n and clauses c_1..c_m, each with exactly 3 literals G = empty directed graph
# 1. Build one diamond gadget per variable for i in 1..n: D[i] = build_diamond_gadget(variable = x_i, num_clauses = m) add D[i].vertices and D[i].internal_edges to G
# 2. Chain diamonds together with bridging vertices allowing
# left-to-right or right-to-left entry into the next diamond for i in 1..n-1: add_bridge_edges(D[i].right_end, D[i+1].left_end, G)
# 3. Add global start/end s = new vertex; t = new vertex add_edge(s, D[1].left_end, G) add_edge(D[n].right_end, t, G)
# 4. Build one hub vertex per clause and wire literal detours for j in 1..m: c_j = new vertex add c_j to G for each literal L in clause_j: i = variable_index(L) slot = reserved_slot(D[i], clause_j, polarity(L)) wire_detour(D[i], slot, c_j, G) # in-edge and out-edge through c_j return (G, s, t) ``` ``` function wire_detour(diamond, slot, clause_vertex, G):
# 'slot' identifies a pair of consecutive vertices (u, v) on the
# row of 'diamond' corresponding to the literal's true-making direction (u, v) = slot.vertex_pair remove_edge(u, v, G) # direct edge is replaced by detour option add_edge(u, clause_vertex, G) add_edge(clause_vertex, v, G) add_edge(u, v, G) # also keep the direct edge, so the
# path MAY skip the clause vertex if
# it is already satisfied elsewhere ``` The `wire_detour` step is the delicate part: each slot offers the traversing path a choice — take the direct edge , or detour through and then continue . Because must be visited exactly once by the final Hamiltonian path (it is a vertex of ), it will be "claimed" by exactly one of its offered detours, corresponding to exactly one satisfied literal (though semantically any of the true literals could serve, the Hamiltonian-path property only forces at least one opportunity to succeed).
Diagram
Reading the figure: the path enters diamond at its left tip, and can go via the top row (setting ) or the bottom row (). If it uses the top row, it passes near the orange clause vertex and may detour to visit it (since appears positively in ). The path then crosses the black bridge vertex into diamond , and so on, finally reaching . Every clause vertex must be picked up by some detour for the tour to be Hamiltonian — this is exactly the constraint that the corresponding clause be satisfied.
Complexity & correctness
Size and time bound. For variables and clauses, each diamond gadget has vertices (one slot pair per clause occurrence, and each variable occurs in at most literal slots across all clauses, but standard constructions bound this by per diamond by reusing slots per clause rather than per literal occurrence). There are diamonds and clause vertices, giving
and the construction algorithm processes each clause and variable slot in constant time per edge, so REDUCE-3SAT-TO-HAMPATH runs in time , which is polynomial in . This satisfies the requirement for a valid Karp reduction: the transformation itself must be computable by a deterministic polynomial-time algorithm, independent of whether HAMPATH itself is efficiently solvable.
Membership in NP. A certificate for is simply the sequence of vertices claimed to be a Hamiltonian path. Verification checks (a) the sequence is a permutation of — sort and compare, — and (b) each consecutive pair is an edge of — a hash-set lookup per pair, total. Both run in time polynomial in the input size, so HAMPATH NP. The same argument, with the added check that , shows HAMCYCLE NP.
Correctness of the reduction — forward direction. Suppose has a satisfying assignment . Define a path through that traverses diamond via the top row if and the bottom row if , moving straight through bridge vertices between diamonds, from to . Since satisfies , every clause has at least one literal made true by ; pick one such literal per clause and have the path take the corresponding detour through exactly at that slot (taking direct edges at all other slots). Because each clause vertex is visited exactly once (via its one chosen detour) and every diamond, bridge, and endpoint vertex is visited exactly once by construction, this yields a Hamiltonian path from to .
Correctness of the reduction — backward direction. Suppose has a Hamiltonian path from to . Because the diamonds are chained in a strict sequence via bridge vertices with no alternate routes between non-adjacent diamonds, must traverse the diamonds in index order (any attempt to skip ahead or double back would either strand vertices unreached or revisit a bridge vertex, violating the Hamiltonian property). Within diamond , the internal wiring is designed so that a Hamiltonian path can only enter at one tip and leave at the other by committing to a single row — top or bottom — for the entire diamond; mixing rows mid-diamond would leave some row-vertices unvisited or force a revisit of a shared vertex. (This is the load-bearing combinatorial fact about the diamond's internal structure: it has, by design, no Hamiltonian sub-path traversal pattern other than "all-top" or "all-bottom.") Define if uses the top row of diamond , else FALSE. Since is Hamiltonian, every clause vertex lies on , meaning took some detour through at a slot corresponding to some literal of ; by the wiring, this detour is only available when the diamond for 's variable is traversed in the direction making true. Hence is true under , so clause is satisfied. As this holds for every clause, satisfies . Together, the two directions establish , completing the reduction and proving HAMPATH is NP-hard. Combined with NP membership, HAMPATH is NP-complete.
Transferring to HAMCYCLE. To show HAMCYCLE is NP-complete, reduce HAMPATH to it: given , add a new vertex with edges and (and no other edges touching ), producing . Any Hamiltonian path in extends to a Hamiltonian cycle in by appending , and conversely any Hamiltonian cycle in must use both edges incident to (since has exactly one in-edge and one out-edge), so removing from the cycle yields a Hamiltonian path in . This reduction runs in extra time and space, so HAMCYCLE is NP-hard, and it is in NP by the same certificate argument, hence NP-complete.
Honest complexity picture. No known algorithm solves HAMPATH or HAMCYCLE in time polynomial in in the worst case. The naive brute-force search over all orderings is far too slow, but dynamic programming over subsets (Held–Karp style, akin to the technique used for the Traveling Salesman Problem) solves it in time and space — exponential, but a dramatic improvement over factorial brute force, and it remains the best known worst-case bound for general graphs. Special graph classes (e.g., graphs with high minimum degree, per Dirac's and Ore's theorems) admit polynomial-time Hamiltonicity tests or guarantees, illustrating that hardness is a worst-case, not universal, property.
Worked example
Let , with variables, clauses, matching the figure above.
| Step | Formula fact | Gadget consequence |
|---|---|---|
| Assignment attempt | Try : | Traverse diamond 1 top row, diamond 2 bottom row, diamond 3 bottom row |
| Check | makes true | Path detours through at the -true slot |
| Check | ; ; | No literal of is true — fails |
| Fix: try : | : ✓. : ✓ | Both clauses satisfied |
| Build path | Diamonds traversed: top, bottom, top | |
| Verify Hamiltonian | All diamond vertices, both bridges, , , , each appear once | Yes — Hamiltonian path exists |
Trace of the failed attempt () shows why the reduction is sound: it is not merely that some Hamiltonian path exists whenever a graph is "big enough" — an inconsistent assignment genuinely fails to produce a valid tour, because clause vertex would have no available detour edge to be entered from and left to, stranding it unreachable within a single Hamiltonian path (any attempted visit to without a valid literal detour would require using an edge that was never wired into the graph, since `wire_detour` only adds edges through for literals appearing in ). This confirms the backward direction of the correctness proof concretely: an unsatisfying assignment corresponds to no Hamiltonian path, not just a Hamiltonian path that happens not to exist for unrelated reasons.
Common pitfalls & traps
| Pitfall | Why it happens | Fix |
|---|---|---|
| Confusing Hamiltonian (vertices) with Eulerian (edges) problems | Both involve "visit everything once," easy to conflate | Remember Eulerian circuits are polynomial-time (all-even-degree characterization); Hamiltonian circuits are NP-complete |
| Assuming the reduction graph is undirected when it needs directed diamonds | Many textbook figures simplify direction | Verify each gadget edge's direction enforces the "commit to one row" property; undirected versions need extra vertex-splitting gadgets |
| Believing "some Hamiltonian path exists" without checking every clause vertex is covered | Only checking a subset of clauses in a hand trace | Explicitly confirm every clause hub has an available, used detour |
| Off-by-one in slot counting per diamond | Forgetting a variable may appear in fewer than clauses, wasting or misallocating slots | Allocate slots per actual occurrence of the variable in clauses, not a fixed blindly |
| Treating the reduction as a proof that HAMPATH is undecidable or only solvable exponentially in all cases | Confusing NP-hardness with unsolvability | NP-complete means no known polynomial algorithm and hardness under P≠NP assumption; it is still decidable, e.g. via DP |
Pioneers & history
The Hamiltonian path problem is named for the 19th-century Irish mathematician who studied cycles on the dodecahedron, but its complexity-theoretic significance emerged a century later with the founding of NP-completeness theory.
Origins · 1 minWilliam Rowan Hamilton and how this was discovered
Where this matters
Vehicle routing and logistics systems that must construct delivery tours touching every stop exactly once are directly modeling Hamiltonian path/circuit search, typically relaxed into the closely related Traveling Salesman Problem with costs, solved in practice via heuristics, branch-and-bound, or integer programming solvers rather than exact exponential search. DNA sequencing pipelines historically framed fragment assembly as a Hamiltonian path problem on an overlap graph before shifting to the polynomial-time-tractable Eulerian path formulation on de Bruijn graphs — a striking real-world case where recognizing the P-vs-NP gap between the two "visit everything once" problems changed algorithm design. Circuit board drilling and 3D printer toolpath optimization also reduce to Hamiltonian-path-like tours minimizing travel between points. In compilers and hardware design, register allocation and certain scheduling problems embed Hamiltonian-path subproblems as hardness certificates justifying the use of heuristic or approximate schedulers instead of exact ones. Pedagogically, the gadget-based 3-SAT-to-HAMPATH reduction remains one of the clearest illustrations of how a single unifying proof technique — variable gadgets plus clause gadgets — powers NP-completeness proofs across graph theory, scheduling, and beyond, directly paralleling the gadget style used for Clique and Vertex Cover.
Ask the tutor: Can you show me exactly how the "diamond" gadget's internal edges rule out a mixed-row traversal, with the full edge list?
Is HAMPATH NP-complete for both directed and undirected graphs?
Yes, both versions are NP-complete. The reduction sketched here naturally produces a directed graph, since the gadget wiring relies on enforcing one-way detours through clause vertices. An undirected version can be shown NP-complete either by a similar direct 3-SAT reduction with symmetric gadgets, or by reducing directed HAMPATH to undirected HAMPATH via a standard vertex-splitting transformation, where each directed vertex becomes a pair of undirected vertices joined by a forced edge that simulates one-way passage. Both directions appear in Karp's original 1972 paper and in most complexity-theory treatments as companion results.
Why is the diamond gadget necessary — couldn't a simpler variable gadget work?
The diamond's two-row structure is what forces an all-or-nothing traversal per variable, which is what makes the encoded assignment well-defined. A simpler gadget, such as a single vertex with two self-loops or a small triangle, generally fails to prevent a Hamiltonian path from mixing partial commitments — for instance, entering as if TRUE but leaving as if FALSE, which would correspond to no coherent Boolean value at all. The diamond's design, with distinct top and bottom rows sharing only the two tip vertices, is the minimal structure that rigorously rules out such mixed traversals while still offering exactly two clean options.
Does NP-completeness mean Hamiltonian path instances can never be solved efficiently in practice?
No. NP-completeness is a worst-case statement: no known algorithm solves all instances in polynomial time, and finding one would imply P = NP. Many real instances — sparse graphs, graphs with high minimum degree (via Dirac's or Ore's theorem guarantees), or small instances — are solved quickly by SAT solvers, branch-and-bound, or specialized heuristics in practice. Dense graphs, graphs from real road networks, and many structured instances are often tractable even though adversarially constructed worst-case graphs are believed to require exponential time under standard complexity assumptions.
How does this reduction relate to the Cook-Levin theorem?
Cook–Levin directly shows SAT is NP-complete by simulating an arbitrary nondeterministic polynomial-time Turing machine with a Boolean formula. Every other NP-completeness proof, including HAMPATH's, builds on top of that foundational result by reducing from SAT or a problem already shown NP-complete via SAT, such as 3-SAT. The HAMPATH proof does not re-simulate a Turing machine directly; instead it reduces from 3-SAT, relying on the fact that 3-SAT's NP-completeness was itself established via Cook–Levin plus the standard CNF-to-3-CNF clause-splitting transformation.
What role does the "at least one true literal per clause" requirement play if the reduction just needs one detour per clause vertex?
It is exactly the semantic bridge between logic and graph structure. A clause vertex offers one detour opportunity per literal in the clause, and the Hamiltonian property forces exactly one such detour to be used (since the vertex must be visited exactly once). If a clause had zero true literals under an attempted assignment, none of its detour edges would be traversable given the chosen diamond directions, so the clause vertex would be unreachable within a valid Hamiltonian path — directly mirroring the logical requirement that a disjunction is false when all its literals are false.
Why does the reduction need directed edges for the "keep a direct edge as well as a detour" trick to work?
The direct edge and the detour path must coexist as alternative routes without creating extra ways for a Hamiltonian path to revisit vertices. In a directed graph, this is safe: the path can choose either the shortcut or the detour, and only one of possibly several detours per clause vertex will actually be used, since the clause vertex is visited once total across the whole graph. Making this work correctly in an undirected setting requires more careful gadget engineering, typically via the vertex-splitting technique mentioned earlier, to prevent unintended reversals.
Is there a simpler proof of HAMPATH's NP-hardness not going through 3-SAT?
Yes — HAMPATH's NP-hardness can also be shown by a reduction from Vertex Cover or from the Traveling Salesman decision problem's structure, and Karp's original 1972 paper interlinks many of these NP-complete problems through a web of reductions rather than each one going directly back to SAT. Pedagogically, the 3-SAT route is preferred because it cleanly demonstrates the general gadget-based reduction methodology — variable gadgets plus clause gadgets — that recurs throughout NP-completeness theory, making it the standard teaching path even though it is not the only valid one.