PBeFS
Parallel Best-First Search
Loading...
Searching...
No Matches
MissionariesCannibals.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*/
2/*---------------------- File MissionariesCannibals.h ----------------------*/
3/*--------------------------------------------------------------------------*/
17/*--------------------------------------------------------------------------*/
18/*------------------------------ DEFINITIONS -------------------------------*/
19/*--------------------------------------------------------------------------*/
20
21#ifndef __PBeFS_MissionariesCannibals
22 #define __PBeFS_MissionariesCannibals
23 /* self-identification: #endif at the end of the file */
24
25/*--------------------------------------------------------------------------*/
26/*-------------------------------- INCLUDES --------------------------------*/
27/*--------------------------------------------------------------------------*/
28
29#include <algorithm>
30
31#include <cstddef>
32
33#include <cstdint>
34
35#include <stdexcept>
36
37#include "PBeFS/astar/Domain.h"
38
39/*--------------------------------------------------------------------------*/
40/*------------------------------- NAMESPACE --------------------------------*/
41/*--------------------------------------------------------------------------*/
42
44namespace PBeFS_di_unipi_it
45{
46
47/*--------------------------------------------------------------------------*/
48/*---------------------- CLASS MissionariesCannibals -----------------------*/
49/*--------------------------------------------------------------------------*/
51
64
66
67/*------------------------ PUBLIC PART OF THE CLASS ------------------------*/
68
69 public:
70
71/*------------------------------ PUBLIC TYPES ------------------------------*/
72
73 using state_type = std::uint64_t;
74 using cost_type = int;
75
76/*------------------------------ CONSTRUCTOR -------------------------------*/
77
80
81 MissionariesCannibals( int m , int c , int b )
82 : f_m( m ) , f_c( c ) , f_b( b ) {
83 if( ( m < 0 ) || ( c < 0 ) || ( m > 65535 ) || ( c > 65535 ) ||
84 ( b < 1 ) )
85 throw( std::invalid_argument( "MissionariesCannibals::"
86 "MissionariesCannibals: bad sizes" ) );
87 }
88
89/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
91
92 [[nodiscard]] static int missionaries( std::uint64_t s ) noexcept {
93 return( int( s & 0xFFFF ) );
94 }
95
97
98 [[nodiscard]] static int cannibals( std::uint64_t s ) noexcept {
99 return( int( ( s >> 16 ) & 0xFFFF ) );
100 }
101
103
104 [[nodiscard]] static bool boat_left( std::uint64_t s ) noexcept {
105 return( ( ( s >> 32 ) & 1 ) == 0 );
106 }
107
108/*------------------------- METHODS OF THE DOMAIN --------------------------*/
109
110 [[nodiscard]] std::uint64_t initial_state( void ) const noexcept {
111 return( pack( f_m , f_c , true ) );
112 }
113
114 [[nodiscard]] bool is_goal( std::uint64_t s ) const noexcept {
115 return( ( missionaries( s ) == 0 ) && ( cannibals( s ) == 0 ) );
116 }
117
118 [[nodiscard]] std::uint64_t hash( std::uint64_t s ) const noexcept {
119 return( ADS::splitmix64( s ) );
120 }
121
122/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
128
129 [[nodiscard]] int heuristic( std::uint64_t s ) const noexcept {
130 const int n = missionaries( s ) + cannibals( s );
131 if( n == 0 )
132 return( 0 );
133 int h = 1;
134 if( n > f_b )
135 h = f_b > 1 ? 2 * ( ( n - f_b + ( f_b - 1 ) - 1 ) / ( f_b - 1 ) ) + 1
136 : 2 * n - 1;
137 return( boat_left( s ) ? h : h + 1 );
138 }
139
140/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
144
145 template< class F >
146 void for_each_successor( std::uint64_t s , int , F && f ) const {
147 const bool left = boat_left( s );
148 const int m = missionaries( s ) , c = cannibals( s );
149 const int am = left ? m : f_m - m , ac = left ? c : f_c - c; // aboard
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 );
155 f( t , 1 , heuristic( t ) );
156 }
157 }
158 }
159
160/*---------------------- FEATURES FOR ZOBRIST HASHING ----------------------*/
162
163 [[nodiscard]] std::size_t num_features( void ) const noexcept {
164 return( std::size_t( f_m ) + f_c + 4 );
165 }
166
169
170 template< class F >
171 void for_each_feature( std::uint64_t s , F && f ) const {
172 f( std::size_t( missionaries( s ) ) );
173 f( std::size_t( f_m ) + 1 + cannibals( s ) );
174 f( std::size_t( f_m ) + f_c + ( boat_left( s ) ? 2 : 3 ) );
175 }
176
177/*------------------------------ OTHER HASHES ------------------------------*/
179
180 [[nodiscard]] std::uint64_t perfect_hash( std::uint64_t s ) const noexcept {
181 return( s );
182 }
183
184/*----------------------- PRIVATE PART OF THE CLASS ------------------------*/
185
186 private:
187
188 // the state with m missionaries and c cannibals on the left bank
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 ) );
192 }
193
194 // true if m missionaries and c cannibals on a bank are safe
195 static bool safe( int m , int c ) noexcept {
196 return( ( m == 0 ) || ( m >= c ) );
197 }
198
199 int f_m;
200 int f_c;
201 int f_b;
202
203 }; // end( class( MissionariesCannibals ) )
204
205/*--------------------------------------------------------------------------*/
206
207} // end( namespace PBeFS_di_unipi_it )
208
209/*--------------------------------------------------------------------------*/
210
211#endif /* __PBeFS_MissionariesCannibals */
212
213/*--------------------------------------------------------------------------*/
214/*-------------------- End File MissionariesCannibals.h --------------------*/
215/*--------------------------------------------------------------------------*/
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