21#ifndef __PBeFS_WaterJugs
22 #define __PBeFS_WaterJugs
84 : v_cap( std::move( capacity ) ) , f_goal( goal ) {
85 if( v_cap.empty() || ( v_cap.size() > 4 ) )
86 throw( std::invalid_argument(
"WaterJugs::WaterJugs: 1 to 4 jugs" ) );
87 for(
int c : v_cap ) {
88 if( ( c <= 0 ) || ( c > 65535 ) )
89 throw( std::invalid_argument(
"WaterJugs::WaterJugs: bad capacity" ) );
90 v_first.push_back( f_features );
91 f_features += std::size_t( c ) + 1;
98 [[nodiscard]]
static int level( std::uint64_t s , std::size_t j )
noexcept {
99 return(
int( ( s >> ( 16 * j ) ) & 0xFFFF ) );
104 [[nodiscard]] std::size_t
jugs(
void )
const noexcept {
105 return( v_cap.size() );
114 [[nodiscard]]
bool is_goal( std::uint64_t s )
const noexcept {
115 for( std::size_t j = 0 ; j < v_cap.size() ; ++j )
116 if(
level( s , j ) == f_goal )
121 [[nodiscard]] std::uint64_t
hash( std::uint64_t s )
const noexcept {
122 return( ADS::splitmix64( s ) );
125 [[nodiscard]]
int heuristic( std::uint64_t s )
const noexcept {
126 return(
is_goal( s ) ? 0 : 1 );
134 const auto with = [ & ]( std::uint64_t t , std::size_t j ,
int l ) {
135 return( ( t & ~( std::uint64_t( 0xFFFF ) << ( 16 * j ) ) ) |
136 ( std::uint64_t( l ) << ( 16 * j ) ) );
138 const auto move = [ & ]( std::uint64_t t ) {
142 for( std::size_t i = 0 ; i < v_cap.size() ; ++i ) {
143 move( with( s , i , v_cap[ i ] ) );
144 move( with( s , i , 0 ) );
145 for( std::size_t j = 0 ; j < v_cap.size() ; ++j )
147 const int q = std::min(
level( s , i ) , v_cap[ j ] -
level( s , j ) );
148 move( with( with( s , i ,
level( s , i ) - q ) , j ,
149 level( s , j ) + q ) );
158 return( f_features );
165 for( std::size_t j = 0 ; j < v_cap.size() ; ++j )
166 f( v_first[ j ] + std::size_t(
level( s , j ) ) );
172 [[nodiscard]] std::uint64_t
perfect_hash( std::uint64_t s )
const noexcept {
180 std::vector< int > v_cap;
182 std::vector< std::size_t > v_first;
183 std::size_t f_features = 0;
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
static int level(std::uint64_t s, std::size_t j) noexcept
the level of the jug j in the state s
Definition WaterJugs.h:98
WaterJugs(std::vector< int > capacity, int goal)
constructor of the jugs of the given capacities, the goal being a jug holding goal units
Definition WaterJugs.h:83
bool is_goal(std::uint64_t s) const noexcept
Definition WaterJugs.h:114
std::uint64_t hash(std::uint64_t s) const noexcept
Definition WaterJugs.h:121
void for_each_feature(std::uint64_t s, F &&f) const
calls f( i ) for the feature i of the level of each jug
Definition WaterJugs.h:164
std::uint64_t state_type
the packed levels
Definition WaterJugs.h:75
int cost_type
the cost type
Definition WaterJugs.h:76
std::uint64_t perfect_hash(std::uint64_t s) const noexcept
the perfect hash: the packed state
Definition WaterJugs.h:172
std::size_t num_features(void) const noexcept
the number of features: one per jug and level
Definition WaterJugs.h:157
void for_each_successor(std::uint64_t s, int, F &&f) const
calls f( t , 1 , h( t ) ) for each fill, empty and pour that changes s
Definition WaterJugs.h:133
std::size_t jugs(void) const noexcept
the number of jugs
Definition WaterJugs.h:104
std::uint64_t initial_state(void) const noexcept
Definition WaterJugs.h:110
int heuristic(std::uint64_t s) const noexcept
Definition WaterJugs.h:125
namespace for the Parallel Best-First Search library
Definition AStar.h:83