PBeFS
Parallel Best-First Search
Loading...
Searching...
No Matches
Grid.h
Go to the documentation of this file.
1/*--------------------------------------------------------------------------*/
2/*------------------------------ File Grid.h -------------------------------*/
3/*--------------------------------------------------------------------------*/
22/*--------------------------------------------------------------------------*/
23/*------------------------------ DEFINITIONS -------------------------------*/
24/*--------------------------------------------------------------------------*/
25
26#ifndef __PBeFS_Grid
27 #define __PBeFS_Grid
28 /* self-identification: #endif at the end of the file */
29
30/*--------------------------------------------------------------------------*/
31/*-------------------------------- INCLUDES --------------------------------*/
32/*--------------------------------------------------------------------------*/
33
34#include <algorithm>
35
36#include <cmath>
37
38#include <cstddef>
39
40#include <cstdint>
41
42#include <cstdlib>
43
44#include <iosfwd>
45
46#include <stdexcept>
47
48#include <type_traits>
49
50#include <vector>
51
52#include "PBeFS/astar/Domain.h"
53
55
56/*--------------------------------------------------------------------------*/
57/*------------------------------- NAMESPACE --------------------------------*/
58/*--------------------------------------------------------------------------*/
59
61namespace PBeFS_di_unipi_it
62{
63
64/*--------------------------------------------------------------------------*/
65/*----------------------------- CLASS GridMap ------------------------------*/
66/*--------------------------------------------------------------------------*/
68
72
73class GridMap {
74
75/*------------------------ PUBLIC PART OF THE CLASS ------------------------*/
76
77 public:
78
80
81 GridMap( int width = 0 , int height = 0 );
82
83/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
85
93
94 [[nodiscard]] static GridMap random( int width , int height , double p ,
95 std::uint64_t seed ,
96 int max_cost = 1 );
97
98/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
100
104
105 [[nodiscard]] static GridMap read_movingai( std::istream & in );
106
107/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
109
110 [[nodiscard]] int width( void ) const noexcept { return( f_width ); }
111
113
114 [[nodiscard]] int height( void ) const noexcept { return( f_height ); }
115
116/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
118
119 [[nodiscard]] int cost( int x , int y ) const noexcept {
120 if( ( x < 0 ) || ( y < 0 ) || ( x >= f_width ) || ( y >= f_height ) )
121 return( 0 );
122 return( v_cost[ std::size_t( y ) * f_width + x ] );
123 }
124
125/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
128
129 void set_cost( int x , int y , int c );
130
131/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
133
134 [[nodiscard]] int min_cost( void ) const noexcept;
135
136/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
138
139 [[nodiscard]] const std::vector< std::uint8_t > & costs( void ) const
140 noexcept {
141 return( v_cost );
142 }
143
144/*----------------------- PRIVATE PART OF THE CLASS ------------------------*/
145
146 private:
147
148 int f_width;
149 int f_height;
150 std::vector< std::uint8_t > v_cost;
151
152 }; // end( class( GridMap ) )
153
154/*--------------------------------------------------------------------------*/
155/*-------------------------------- CONSTANTS -------------------------------*/
156/*--------------------------------------------------------------------------*/
158
159inline constexpr double grid_sqrt2 = 1.41421356237309504880;
160
161/*--------------------------------------------------------------------------*/
162
163#if defined( PBEFS_STRUCTURES_STD ) || defined( PBEFS_STRUCTURES_BOOST )
164
165/*--------------------------------------------------------------------------*/
166/*-------------------------- CLASS GridAdjacency ---------------------------*/
167/*--------------------------------------------------------------------------*/
169
173
174template< int Moves >
175class GridAdjacency {
176
177/*------------------------ PUBLIC PART OF THE CLASS ------------------------*/
178
179 public:
180
182 using cost_type = std::conditional_t< Moves == 4 , int , double >;
183
185
186 explicit GridAdjacency( const GridMap & map ) : f_map( map ) {}
187
188/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
191
192 template< class F >
193 void for_each( std::uint32_t , int x , int y , F && f ) const {
194 static constexpr int dx[ 8 ] = { 0 , -1 , 1 , 0 , -1 , 1 , -1 , 1 };
195 static constexpr int dy[ 8 ] = { -1 , 0 , 0 , 1 , -1 , -1 , 1 , 1 };
196 const int w = f_map.width();
197 const cost_type c = cost_type( f_map.cost( x , y ) );
198 for( int k = 0 ; k < Moves ; ++k ) {
199 const int nx = x + dx[ k ] , ny = y + dy[ k ];
200 if( ! f_map.cost( nx , ny ) )
201 continue;
202 if( ( k >= 4 ) && // a diagonal: no corner cutting
203 ( ! f_map.cost( nx , y ) || ! f_map.cost( x , ny ) ) )
204 continue;
205 f( std::uint32_t( ny ) * std::uint32_t( w ) + std::uint32_t( nx ) ,
206 nx , ny , k >= 4 ? cost_type( c * grid_sqrt2 ) : c );
207 }
208 }
209
210/*----------------------- PRIVATE PART OF THE CLASS ------------------------*/
211
212 private:
213
214 const GridMap & f_map;
215
216 }; // end( class( GridAdjacency ) )
217
218#endif /* PBEFS_STRUCTURES_STD and PBEFS_STRUCTURES_BOOST */
219
220/*--------------------------------------------------------------------------*/
221
222} // end( namespace PBeFS_di_unipi_it )
223
224/*--------------------------------------------------------------------------*/
225/*------------------ THE ADJACENCY OF THE OTHER STRUCTURES -----------------*/
226/*--------------------------------------------------------------------------*/
227
228#if defined( PBEFS_STRUCTURES_ADS )
230#endif
231
232/*--------------------------------------------------------------------------*/
233
235namespace PBeFS_di_unipi_it
236{
237
238/*--------------------------------------------------------------------------*/
239/*------------------------------- CLASS Grid -------------------------------*/
240/*--------------------------------------------------------------------------*/
242
257
258template< int Moves = 4 >
259class Grid {
260
261 static_assert( ( Moves == 4 ) || ( Moves == 8 ) ,
262 "Grid: the moves are either 4 or 8" );
263
264/*------------------------ PUBLIC PART OF THE CLASS ------------------------*/
265
266 public:
267
268/*------------------------------ PUBLIC TYPES ------------------------------*/
269
270 using state_type = std::uint32_t;
271 using cost_type = std::conditional_t< Moves == 4 , int , double >;
273
274/*------------------------------ CONSTRUCTOR -------------------------------*/
275
277
281
282 Grid( const GridMap & map , int sx , int sy , int gx , int gy ,
283 int block = 100 , int nblock_side = 20 )
284 : f_map( map ) , f_adj( map ) , f_w( map.width() ) , f_h( map.height() ) ,
285 f_start( index( sx , sy ) ) , f_goal( index( gx , gy ) ) ,
286 f_gx( gx ) , f_gy( gy ) , f_min( map.min_cost() ) ,
287 f_block( block ) , f_nside( nblock_side ) {
288 if( ! map.cost( sx , sy ) || ! map.cost( gx , gy ) )
289 throw( std::invalid_argument( "Grid::Grid: blocked start or goal" ) );
290 if( ( block <= 0 ) || ( nblock_side <= 0 ) )
291 throw( std::invalid_argument( "Grid::Grid: blocks of side <= 0" ) );
292 f_bw = ( f_w + f_block - 1 ) / f_block;
293 f_bh = ( f_h + f_block - 1 ) / f_block;
294 f_nw = ( f_w + f_nside - 1 ) / f_nside;
295 f_nh = ( f_h + f_nside - 1 ) / f_nside;
296 }
297
298/*------------------------- METHODS OF THE DOMAIN --------------------------*/
300
301 [[nodiscard]] state_type initial_state( void ) const noexcept {
302 return( f_start );
303 }
304
306
307 [[nodiscard]] bool is_goal( state_type s ) const noexcept {
308 return( s == f_goal );
309 }
310
312
313 [[nodiscard]] std::uint64_t hash( state_type s ) const noexcept {
314 return( ADS::splitmix64( s ) );
315 }
316
317/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
319
320 [[nodiscard]] cost_type heuristic( state_type s ) const noexcept {
321 return( distance( int( s % f_w ) , int( s / f_w ) , f_gx , f_gy ) );
322 }
323
324/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
326
327 template< class F >
328 void for_each_successor( state_type s , cost_type , F && f ) const {
329 const int x = int( s % f_w ) , y = int( s / f_w );
330 f_adj.for_each( s , x , y , [ & ]( state_type t , int nx , int ny ,
331 cost_type c ) {
332 f( t , c , distance( nx , ny , f_gx , f_gy ) );
333 } );
334 }
335
336/*---------------------- FEATURES FOR ZOBRIST HASHING ----------------------*/
338
339 [[nodiscard]] std::size_t num_features( void ) const noexcept {
340 return( std::size_t( f_w ) + f_h );
341 }
342
345
346 template< class F >
347 void for_each_feature( state_type s , F && f ) const {
348 f( std::size_t( s % f_w ) );
349 f( std::size_t( f_w ) + s / f_w );
350 }
351
353
354 [[nodiscard]] std::size_t num_abstract_features( void ) const noexcept {
355 return( std::size_t( f_bw ) + f_bh );
356 }
357
359
360 [[nodiscard]] std::size_t abstract_feature( std::size_t i ) const noexcept
361 {
362 if( i < std::size_t( f_w ) )
363 return( i / f_block );
364 return( std::size_t( f_bw ) + ( i - f_w ) / f_block );
365 }
366
367/*--------------------------- STATE ABSTRACTIONS ---------------------------*/
369
370 [[nodiscard]] std::uint64_t abstract_state( state_type s ) const noexcept {
371 return( std::uint64_t( s / f_w / f_block ) * f_bw + s % f_w / f_block );
372 }
373
375
376 [[nodiscard]] std::size_t num_nblocks( void ) const noexcept {
377 return( std::size_t( f_nw ) * f_nh );
378 }
379
382
383 [[nodiscard]] std::size_t nblock( state_type s ) const noexcept {
384 return( std::size_t( s / f_w / f_nside ) * f_nw + s % f_w / f_nside );
385 }
386
388
389 template< class F >
390 void for_each_nblock_successor( std::size_t b , F && f ) const {
391 const int bx = int( b % f_nw ) , by = int( b / f_nw );
392 for( int dy = -1 ; dy <= 1 ; ++dy )
393 for( int dx = -1 ; dx <= 1 ; ++dx ) {
394 if( ( ! dx && ! dy ) || ( ( Moves == 4 ) && dx && dy ) )
395 continue;
396 const int nx = bx + dx , ny = by + dy;
397 if( ( nx >= 0 ) && ( ny >= 0 ) && ( nx < f_nw ) && ( ny < f_nh ) )
398 f( std::size_t( ny ) * f_nw + nx );
399 }
400 }
401
403
404 [[nodiscard]] int nblock_side( void ) const noexcept { return( f_nside ); }
405
407
408 [[nodiscard]] int block( void ) const noexcept { return( f_block ); }
409
410/*---------------------- OTHER HEURISTICS AND HASHES -----------------------*/
412
414 const noexcept {
415 return( distance( int( s % f_w ) , int( s / f_w ) ,
416 int( t % f_w ) , int( t / f_w ) ) );
417 }
418
420
421 [[nodiscard]] std::uint64_t perfect_hash( state_type s ) const noexcept {
422 return( s );
423 }
424
425/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
427
428 [[nodiscard]] state_type index( int x , int y ) const noexcept {
429 return( state_type( y ) * state_type( f_w ) + state_type( x ) );
430 }
431
432/*----------------------- PRIVATE PART OF THE CLASS ------------------------*/
433
434 private:
435
438 static constexpr double c_sqrt2 = grid_sqrt2;
439
440/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
441 // the Manhattan or octile distance times the smallest cost
442
443 [[nodiscard]] cost_type distance( int x , int y , int u , int v )
444 const noexcept {
445 const int ax = std::abs( x - u ) , ay = std::abs( y - v );
446 if constexpr( Moves == 4 )
447 return( ( ax + ay ) * f_min );
448 else
449 return( ( std::max( ax , ay ) + ( c_sqrt2 - 1 ) * std::min( ax , ay ) )
450 * f_min );
451 }
452
453/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/
454
455 const GridMap & f_map;
456 GridAdjacency< Moves > f_adj;
457 int f_w;
458 int f_h;
459 state_type f_start;
460 state_type f_goal;
461 int f_gx;
462 int f_gy;
463 int f_min;
464 int f_block;
465 int f_nside;
466 int f_bw;
467 int f_bh;
468 int f_nw;
469 int f_nh;
470
471 }; // end( class( Grid ) )
472
473/*--------------------------------------------------------------------------*/
474
475} // end( namespace PBeFS_di_unipi_it )
476
477/*--------------------------------------------------------------------------*/
478
479#endif /* __PBeFS_Grid */
480
481/*--------------------------------------------------------------------------*/
482/*---------------------------- End File Grid.h -----------------------------*/
483/*--------------------------------------------------------------------------*/
Header file for the concepts a search problem has to satisfy in order to be searched by the algorithm...
Header file for the class template GridAdjacency of the set of data structures of ADS [see Structures...
Header file for the choice of the set of data structures of A*: the arena of the nodes (NodePool),...
the moves from a cell of a GridMap and their costs, on the GridGraph of ADS
Definition GridAdjacency.h:58
GridAdjacency(const GridMap &map)
constructor, copying the costs of the cells of the map
Definition GridAdjacency.h:69
std::conditional_t< Moves==4, int, double > cost_type
the cost of a move: an integer with 4 moves, a real with 8
Definition GridAdjacency.h:65
void for_each(std::uint32_t s, int x, int y, F &&f) const
calls f( t , x' , y' , c ) for each free cell t = ( x' , y' ) next to the free cell s = ( x ,...
Definition GridAdjacency.h:83
a rectangular map of cells, each with a cost of traversal
Definition Grid.h:73
int height(void) const noexcept
the number of rows
Definition Grid.h:114
static GridMap random(int width, int height, double p, std::uint64_t seed, int max_cost=1)
a random map with blocked cells of probability p
static GridMap read_movingai(std::istream &in)
reads a map in the format of the benchmarks of Sturtevant (2012)
int min_cost(void) const noexcept
the smallest cost of a free cell (1 if there is none)
const std::vector< std::uint8_t > & costs(void) const noexcept
the costs of the cells, row by row
Definition Grid.h:139
int cost(int x, int y) const noexcept
the cost of the cell ( x , y ), 0 if blocked or outside the map
Definition Grid.h:119
GridMap(int width=0, int height=0)
constructor of a map of width by height free cells of cost 1
void set_cost(int x, int y, int c)
sets the cost of the cell ( x , y ) to c, in
int width(void) const noexcept
the number of columns
Definition Grid.h:110
std::size_t num_nblocks(void) const noexcept
the number of nblocks
Definition Grid.h:376
std::uint64_t perfect_hash(state_type s) const noexcept
the perfect hash of HDA*[P]: the cell index
Definition Grid.h:421
void for_each_feature(state_type s, F &&f) const
calls f( x ) and f( W + y ) for the cell of the state s
Definition Grid.h:347
std::uint64_t abstract_state(state_type s) const noexcept
the abstract state of AHDA*: the block of the cell
Definition Grid.h:370
std::size_t nblock(state_type s) const noexcept
the nblock of PBNF: the block of cells, being nblock_side()
Definition Grid.h:383
state_type initial_state(void) const noexcept
the start cell
Definition Grid.h:301
std::size_t num_abstract_features(void) const noexcept
the number of abstract features: the columns and rows of blocks
Definition Grid.h:354
std::size_t abstract_feature(std::size_t i) const noexcept
the abstract feature of a feature: the column or row of its block
Definition Grid.h:360
Grid(const GridMap &map, int sx, int sy, int gx, int gy, int block=100, int nblock_side=20)
constructor, taking the map (which must outlive the Grid) and the cells
Definition Grid.h:282
std::uint64_t hash(state_type s) const noexcept
the hash of a cell: its index, mixed
Definition Grid.h:313
cost_type heuristic(state_type s) const noexcept
the Manhattan (4 moves) or octile (8 moves) distance to the goal
Definition Grid.h:320
bool is_goal(state_type s) const noexcept
true if s is the goal cell
Definition Grid.h:307
void for_each_nblock_successor(std::size_t b, F &&f) const
calls f( b' ) for each nblock b' next to the nblock b
Definition Grid.h:390
std::size_t num_features(void) const noexcept
the number of features: the columns and the rows
Definition Grid.h:339
int nblock_side(void) const noexcept
the side of the nblocks
Definition Grid.h:404
state_type index(int x, int y) const noexcept
the cell index of ( x , y )
Definition Grid.h:428
std::conditional_t< Moves==4, int, double > cost_type
the cost type
Definition Grid.h:271
cost_type pairwise_heuristic(state_type s, state_type t) const noexcept
the heuristic of PA*SE: the distance between two cells
Definition Grid.h:413
int block(void) const noexcept
the side of the blocks of AZH and AHDA*
Definition Grid.h:408
void for_each_successor(state_type s, cost_type, F &&f) const
calls f( t , c , h( t ) ) for each free cell t next to s
Definition Grid.h:328
std::uint32_t state_type
a cell index
Definition Grid.h:270
namespace for the Parallel Best-First Search library
Definition AStar.h:83
constexpr double grid_sqrt2
, the cost of a diagonal move per unit of cost of a cell
Definition Grid.h:159