- Type Parameters:
V- the graph vertex typeE- the graph edge type
- All Implemented Interfaces:
HamiltonianPathAlgorithm<V,E>
The implementation follows the classic Held-Karp subset DP, adapted to find a Hamiltonian
path rather than a Hamiltonian cycle. The state dp[subset][v] is
true when there exists a simple path that visits exactly the vertices in
subset and whose last vertex is v. The transition extends a path ending at
v by a new vertex u whenever the edge (v, u) exists and u is
not yet in the subset. A Hamiltonian path exists if and only if dp[fullMask][v] is
true for some v.
The subset-DP formulation is due to Held and Karp, "A Dynamic Programming Approach to Sequencing Problems", J. SIAM 10(1), 1962, and independently to Bellman, "Dynamic Programming Treatment of the Travelling Salesman Problem", J. ACM 9(1), 1962. The Hamiltonian-path variant (where the DP does not need a closing edge back to the start) is a standard textbook adaptation; see for example CLRS, "Introduction to Algorithms" (4th ed.), the dynamic-programming chapter, and the MIT 6.s078 lecture notes on advanced algorithms (lecture 17).
Complexity is O(n^2 * 2^n) time and O(n * 2^n) space, where n is the
number of vertices. Because the running time and memory grow exponentially in n,
this class refuses graphs with more than getMaxVertices() vertices by throwing
IllegalArgumentException. The default ceiling is DEFAULT_MAX_VERTICES; the
single-argument constructor lets callers opt in to a higher ceiling up to
HARD_MAX_VERTICES when they have the memory headroom. Callers handling larger
graphs should use BacktrackingHamiltonianPath instead and accept the lack of
polynomial-bound guarantees.
The algorithm is exact and deterministic. It supports directed and undirected graphs and
tolerates parallel edges and self-loops (self-loops are ignored because they cannot extend a
simple path). In multigraphs, parallel edges between the same vertex pair collapse to a
single DP transition; the returned path uses an arbitrary representative edge selected via
Graph.getEdge(V, V) and is not weight-optimised across parallel edges.
- Author:
- seilat
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault ceiling on the number of vertices.static final intHard upper bound on the number of vertices, fixed by the algorithm's use of aintsubset bitmask. -
Constructor Summary
ConstructorsConstructorDescriptionConstructs a new instance with the default vertex ceiling (DEFAULT_MAX_VERTICES).HeldKarpHamiltonianPath(int maxVertices) Constructs a new instance that accepts graphs with up tomaxVerticesvertices. -
Method Summary
Modifier and TypeMethodDescriptionintReturns the maximum number of vertices this instance will accept.Computes a Hamiltonian path in the given graph and returns a tri-stateHamiltonianPathSearchResult.longReturns the number of DP states (predecessor cells initialised) the algorithm filled during the most recent call togetPath(Graph).Methods inherited from class org.jgrapht.alg.tour.HamiltonianPathAlgorithmBase
buildAdjacency, requireNotEmpty, singletonPath, vertexListToPath
-
Field Details
-
DEFAULT_MAX_VERTICES
public static final int DEFAULT_MAX_VERTICESDefault ceiling on the number of vertices. Withn = 20the DP table requires roughly20 * 2^20 = ~20Mentries; the constant is chosen to keep memory and runtime within practical limits.- See Also:
-
HARD_MAX_VERTICES
public static final int HARD_MAX_VERTICESHard upper bound on the number of vertices, fixed by the algorithm's use of aintsubset bitmask. Aboven = 30the bitmask space overflowsInteger.MAX_VALUE; in practice memory is the dominant constraint well before this ceiling.- See Also:
-
-
Constructor Details
-
HeldKarpHamiltonianPath
public HeldKarpHamiltonianPath()Constructs a new instance with the default vertex ceiling (DEFAULT_MAX_VERTICES). -
HeldKarpHamiltonianPath
public HeldKarpHamiltonianPath(int maxVertices) Constructs a new instance that accepts graphs with up tomaxVerticesvertices.- Parameters:
maxVertices- upper bound on the number of vertices the algorithm will accept; must be at least 1 and at mostHARD_MAX_VERTICES- Throws:
IllegalArgumentException- ifmaxVerticesis outside the allowed range
-
-
Method Details
-
getMaxVertices
public int getMaxVertices()Returns the maximum number of vertices this instance will accept.- Returns:
- configured vertex ceiling
-
getStatesExpanded
public long getStatesExpanded()Returns the number of DP states (predecessor cells initialised) the algorithm filled during the most recent call togetPath(Graph). Intended for diagnostics; the exact counting semantics may change if the implementation changes.- Returns:
- DP states filled during the last search
-
getPath
Description copied from interface:HamiltonianPathAlgorithmComputes a Hamiltonian path in the given graph and returns a tri-stateHamiltonianPathSearchResult.The return value distinguishes:
HamiltonianPathSearchResult.Status.PATH_FOUND— the algorithm produced a Hamiltonian path; it is accessible viaHamiltonianPathSearchResult.getPath().HamiltonianPathSearchResult.Status.PROVEN_ABSENT— the algorithm ran to completion (or was rejected by a sound precheck) and proved that no Hamiltonian path exists.HamiltonianPathSearchResult.Status.ABORTED— the algorithm performed a bounded search that hit its limit before completing. Whether a Hamiltonian path exists in the graph is unknown.
Unbounded implementations only return
PATH_FOUNDorPROVEN_ABSENT. Implementations that accept an execution budget (e.g. a maximum state count) may also returnABORTED; such bounded variants must never reportPROVEN_ABSENTfor a search that was stopped early.- Parameters:
graph- the input graph- Returns:
- a
HamiltonianPathSearchResultdescribing the search outcome
-