TravelingSalesman
Declared in astar/TravelingSalesman.h; the same class on the site of Doxygen.
-
class TravelingSalesman
the traveling salesperson problem on at most 32 cities
The tour starts and ends at the city 0. A state is the current city and the set of the visited ones, packed as the visited cities in the bits \( 0 , \ldots , 31 \), the current city in the bits \( 32 , \ldots , 36 \) and, in the bit 37, whether the tour has gone back to the city 0; the word is also its perfect hash. The heuristic is the cost of a minimum spanning tree (by the algorithm of Prim) of the unvisited cities together with the current and the first one, which is admissible because the rest of the tour is a path through all of them.
The features of Zobrist hashing are the visit of the city \( k \) (numbered \( k < n \)), the current city \( c \) (numbered \( n + c \)) and the closing of the tour (numbered \( 2 n \)).
Public Types
-
using state_type = std::uint64_t
a packed state
-
using cost_type = double
the cost type
-
using matrix_type = std::vector<std::vector<double>>
the distances
Public Functions
-
inline explicit TravelingSalesman(matrix_type dist)
constructor, taking the \( n \times n \) distances, \( 2 \leq n \leq 32 \)
-
inline std::uint64_t initial_state(void) const noexcept
-
inline bool is_goal(std::uint64_t s) const noexcept
-
inline std::uint64_t hash(std::uint64_t s) const noexcept
-
inline double heuristic(std::uint64_t s) const
the cost of a minimum spanning tree of the cities still to be touched
-
template<class F>
inline void for_each_successor(std::uint64_t s, double, F &&f) const calls f( t , c , h( t ) ) for each unvisited city, or for the way back to the city 0 once all are visited
-
inline std::size_t num_features(void) const noexcept
the number of features: the visited cities, the current one, the end
-
template<class F>
inline void for_each_feature(std::uint64_t s, F &&f) const calls f( k ) for each visited city \( k \), f( n + c ) for the current city \( c \) and f( 2 n ) if the tour is closed
-
inline std::uint64_t perfect_hash(std::uint64_t s) const noexcept
the perfect hash: the packed state
-
inline double held_karp(void) const
the cost of an optimal tour by the dynamic program of Held and Karp
With \( d_{jk} \) the distance from the city \( j \) to the city \( k \) and \( C( S , j ) \) the least cost of a path that starts at the city 0, visits exactly the cities of the set \( S \ni 0 \) and ends at \( j \in S \), the dynamic program of Held and Karp (Journal of the Society for Industrial and Applied Mathematics, 1962) rests on the recurrence
\[ C( S \cup \{ k \} , k ) = \min_{j \in S} \{ C( S , j ) + d_{jk} \} , \qquad k \notin S , \]and the cost of an optimal tour is \( \min_{j \neq 0} \{ C( V , j ) + d_{j0} \} \), \( V \) being the set of all the cities:1 procedure HELDKARP(d, n) 2 C({0}, 0) ← 0; C(S, j) ← ∞ for each other pair 3 for each set S ∋ 0, by increasing value of its bits, do 4 for each j ∈ S with C(S, j) < ∞ do 5 for each k ∉ S do 6 C(S ∪ {k}, k) ← min(C(S ∪ {k}, k), C(S, j) + d(j, k)) 7 return min over j ≠ 0 of C(V, j) + d(j, 0)Line 3 visits each set after all its subsets, since adding a city raises the value of the bits; the table has \( 2^n n \) entries and lines 3 to 6 take \( O( 2^n n^2 ) \) time, and therefore the method is meant for checking the searches on small instances (the example TravelingSalesman uses it up to 20 cities).
-
inline int size(void) const noexcept
the number of cities
Public Static Functions
-
static inline matrix_type random_cities(int n, std::uint64_t seed)
the Euclidean distances of n random points of the unit square, drawn from the seed
-
static inline int city(std::uint64_t s) noexcept
the current city of the state s
-
using state_type = std::uint64_t