21#ifndef __PBeFS_MissionariesCannibals
22 #define __PBeFS_MissionariesCannibals
82 : f_m( m ) , f_c( c ) , f_b( b ) {
83 if( ( m < 0 ) || ( c < 0 ) || ( m > 65535 ) || ( c > 65535 ) ||
85 throw( std::invalid_argument(
"MissionariesCannibals::"
86 "MissionariesCannibals: bad sizes" ) );
92 [[nodiscard]]
static int missionaries( std::uint64_t s )
noexcept {
93 return(
int( s & 0xFFFF ) );
98 [[nodiscard]]
static int cannibals( std::uint64_t s )
noexcept {
99 return(
int( ( s >> 16 ) & 0xFFFF ) );
104 [[nodiscard]]
static bool boat_left( std::uint64_t s )
noexcept {
105 return( ( ( s >> 32 ) & 1 ) == 0 );
111 return( pack( f_m , f_c ,
true ) );
114 [[nodiscard]]
bool is_goal( std::uint64_t s )
const noexcept {
118 [[nodiscard]] std::uint64_t
hash( std::uint64_t s )
const noexcept {
119 return( ADS::splitmix64( s ) );
129 [[nodiscard]]
int heuristic( std::uint64_t s )
const noexcept {
135 h = f_b > 1 ? 2 * ( ( n - f_b + ( f_b - 1 ) - 1 ) / ( f_b - 1 ) ) + 1
149 const int am = left ? m : f_m - m , ac = left ? c : f_c - c;
150 for(
int dm = 0 ; dm <= std::min( am , f_b ) ; ++dm )
151 for(
int dc = dm ? 0 : 1 ; dc <= std::min( ac , f_b - dm ) ; ++dc ) {
152 const int nm = left ? m - dm : m + dm , nc = left ? c - dc : c + dc;
153 if( safe( nm , nc ) && safe( f_m - nm , f_c - nc ) ) {
154 const std::uint64_t t = pack( nm , nc , ! left );
164 return( std::size_t( f_m ) + f_c + 4 );
173 f( std::size_t( f_m ) + 1 +
cannibals( s ) );
174 f( std::size_t( f_m ) + f_c + (
boat_left( s ) ? 2 : 3 ) );
180 [[nodiscard]] std::uint64_t
perfect_hash( std::uint64_t s )
const noexcept {
189 static std::uint64_t pack(
int m ,
int c ,
bool left )
noexcept {
190 return( std::uint64_t( m ) | ( std::uint64_t( c ) << 16 ) |
191 ( std::uint64_t( left ? 0 : 1 ) << 32 ) );
195 static bool safe(
int m ,
int c )
noexcept {
196 return( ( m == 0 ) || ( m >= c ) );
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
static int missionaries(std::uint64_t s) noexcept
the missionaries on the left bank in the state s
Definition MissionariesCannibals.h:92
bool is_goal(std::uint64_t s) const noexcept
Definition MissionariesCannibals.h:114
static int cannibals(std::uint64_t s) noexcept
the cannibals on the left bank in the state s
Definition MissionariesCannibals.h:98
std::uint64_t hash(std::uint64_t s) const noexcept
Definition MissionariesCannibals.h:118
void for_each_feature(std::uint64_t s, F &&f) const
calls f( m ), f( M + 1 + c ) and f( M + C + 2 + boat ) for the m missionaries and c cannibals on the ...
Definition MissionariesCannibals.h:171
MissionariesCannibals(int m, int c, int b)
constructor of the problem with m missionaries, c cannibals and a boat of b seats,
Definition MissionariesCannibals.h:81
std::uint64_t state_type
the packed state
Definition MissionariesCannibals.h:73
int cost_type
the cost type
Definition MissionariesCannibals.h:74
std::uint64_t perfect_hash(std::uint64_t s) const noexcept
the perfect hash: the packed state
Definition MissionariesCannibals.h:180
std::size_t num_features(void) const noexcept
the number of features: the counts on the left bank and the boat
Definition MissionariesCannibals.h:163
void for_each_successor(std::uint64_t s, int, F &&f) const
calls f( t , 1 , h( t ) ) for each safe crossing of dm missionaries and dc cannibals,...
Definition MissionariesCannibals.h:146
static bool boat_left(std::uint64_t s) noexcept
true if the boat is on the left bank in the state s
Definition MissionariesCannibals.h:104
std::uint64_t initial_state(void) const noexcept
Definition MissionariesCannibals.h:110
int heuristic(std::uint64_t s) const noexcept
with people on the left bank, a full boat carries of them over and brings 1 back: at least crossin...
Definition MissionariesCannibals.h:129
namespace for the Parallel Best-First Search library
Definition AStar.h:83