<
size_tN = 3>
63std::array<std::array<uint32_t, N>, N>
66std::vector<std::pair<int8_t, int8_t>>
moves= {
78 for(
size_ti = 0; i < N; ++i) {
79 for(
size_tj = 0; j < N; ++j) {
92 inline bool in_range(
constuint32_t value)
const{
returnvalue < N; }
104uint32_t
get(
size_ti,
size_tj)
const{
113std::array<std::array<uint32_t, N>, N>
get_state() {
returnboard; }
124 for(
size_ti = 0; i < N; ++i) {
125 for(
size_tj = 0; j < N; ++j) {
126board[i][j] = ((i * 3 + j + 1) % (N * N));
134 explicit EightPuzzle(
conststd::array<std::array<uint32_t, N>, N> &init)
148: board(std::move(A.board)) {}
168board = std::move(A.board);
181std::vector<EightPuzzle<N>> NewStates;
182 for(
auto&move :
moves) {
183 if(
in_range(zero_pos.first + move.first) &&
184 in_range(zero_pos.second + move.second)) {
186std::array<std::array<uint32_t, N>, N> new_config = board;
187std::swap(new_config[zero_pos.first][zero_pos.second],
188new_config[zero_pos.first + move.first]
189[zero_pos.second + move.second]);
192NewStates.emplace_back(new_state);
203 if(check.get_size() != N) {
206 for(
size_ti = 0; i < N; ++i) {
207 for(
size_tj = 0; j < N; ++j) {
208 if(board[i][j] != check.board[i][j]) {
221 for(
size_ti = 0; i < N; ++i) {
222 for(
size_tj = 0; j < N; ++j) {
223 if(board[i][j] != check.board[i][j]) {
224 returnboard[i][j] < check.board[i][j];
236 for(
size_ti = 0; i < N; ++i) {
237 for(
size_tj = 0; j < N; ++j) {
238 if(board[i][j] != check.board[i][j]) {
239 returnboard[i][j] < check.board[i][j];
254 for(
size_ti = 0; i < N; ++i) {
255 for(
size_tj = 0; j < N; ++j) {
256op << SomeState.board[i][j] <<
" ";
289template<
typenamePuzzle>
296std::shared_ptr<Puzzle> state;
309 explicit Info(
constPuzzle &A) : state(std::make_shared<Puzzle>(A)) {}
317 Info(
constPuzzle &A,
size_th_value,
size_td)
318: state(std::make_shared<Puzzle>(A)),
327: state(std::make_shared<Puzzle>(A.state)),
336: state(std::make_shared<Puzzle>(std::move(A.state))),
338 depth(std::move(A.depth)) {}
356state = std::move(A.state);
358 depth= std::move(A.depth);
367std::shared_ptr<Info> Initial;
368std::shared_ptr<Info> Final;
373 booloperator()(
conststd::shared_ptr<Info> &a,
374 conststd::shared_ptr<Info> &b)
const{
375 return*(a->state) < *(b->state);
380 usingMapOfPuzzleInfoWithPuzzleInfo =
381std::map<std::shared_ptr<Info>, std::shared_ptr<Info>,
384 usingMapOfPuzzleInfoWithInteger =
387 usingSetOfPuzzleInfo =
395Initial = std::make_shared<Info>(initial);
396Final = std::make_shared<Info>(
final);
408std::shared_ptr<Info> FinalState,
409 constMapOfPuzzleInfoWithPuzzleInfo &parent_of) {
411 autocurrent_state = FinalState;
416std::vector<Puzzle> answer;
417 while(current_state !=
nullptr) {
418answer.emplace_back(*current_state->state);
419current_state = parent_of.find(current_state)->second;
432 conststd::function<uint32_t(
constPuzzle &,
constPuzzle &)> &dist,
433 constuint32_t permissible_depth = 30) {
434MapOfPuzzleInfoWithPuzzleInfo
436MapOfPuzzleInfoWithInteger g_score;
437SetOfPuzzleInfo open_list;
438SetOfPuzzleInfo closed_list;
441open_list.emplace(Initial);
442parent_of[Initial] =
nullptr;
443g_score[Initial] = 0;
445 while(!open_list.empty()) {
447 typenameSetOfPuzzleInfo::iterator it_low_f_score;
448uint32_t min_f_score = 1e9;
449 for(
autoiter = open_list.begin(); iter != open_list.end();
453uint32_t f_score = (*iter)->heuristic_value + (*iter)->depth;
454 if(f_score < min_f_score) {
455min_f_score = f_score;
456it_low_f_score = iter;
461std::shared_ptr<Info> current_state = *it_low_f_score;
464 if(*(current_state->state) == *(Final->state)) {
465 return Solution(current_state, parent_of);
468open_list.erase(it_low_f_score);
471 if(current_state->depth >= permissible_depth) {
476std::vector<Puzzle> total_possible_moves =
477current_state->state->generate_possible_moves();
479 for(Puzzle &neighbor : total_possible_moves) {
482std::shared_ptr<Info> Neighbor = std::make_shared<Info>(
483neighbor, dist(neighbor, *(Final->state)),
484current_state->depth + 1U);
485uint32_t temp_g_score = Neighbor->depth;
490 autoclosed_list_iter = closed_list.find(Neighbor);
491 if(closed_list_iter != closed_list.end()) {
495 if(Neighbor->depth < (*closed_list_iter)->depth) {
496closed_list.erase(closed_list_iter);
501 autoneighbor_g_score_iter = g_score.find(Neighbor);
504 if(neighbor_g_score_iter != g_score.end()) {
505 if(neighbor_g_score_iter->second > temp_g_score) {
506neighbor_g_score_iter->second = temp_g_score;
507parent_of[Neighbor] = current_state;
510g_score[Neighbor] = temp_g_score;
511parent_of[Neighbor] = current_state;
516 autoiter = open_list.find(Neighbor);
517 if(iter == open_list.end()) {
518open_list.emplace(Neighbor);
519}
else if((*iter)->depth > Neighbor->depth) {
520(*iter)->depth = Neighbor->depth;
523closed_list.emplace(current_state);
526 returnstd::vector<Puzzle>(0);
538 usingmatrix3 = std::array<std::array<uint32_t, 3>, 3>;
539 usingrow3 = std::array<uint32_t, 3>;
540 usingmatrix4 = std::array<std::array<uint32_t, 4>, 4>;
541 usingrow4 = std::array<uint32_t, 4>;
544puzzle[0] = row3({0, 2, 3});
545puzzle[1] = row3({1, 5, 6});
546puzzle[2] = row3({4, 7, 8});
549ideal[0] = row3({1, 2, 3});
550ideal[1] = row3({4, 5, 6});
551ideal[2] = row3({7, 8, 0});
556 automanhattan_distance =
560 for(
size_ti = 0; i < first.
get_size(); ++i) {
561 for(
size_tj = 0; j < first.
get_size(); ++j) {
562uint32_t
find= first.
get(i, j);
564 for(
size_tk = 0;
k< second.get_size(); ++
k) {
565 for(
size_tl = 0;
l< second.get_size(); ++
l) {
566 if(find == second.get(k, l)) {
567std::tie(m, n) = std::make_pair(k, l);
576ret += (std::max(m, i) - std::min(m, i)) +
577(std::max(n, j) - std::min(n, j));
590std::vector<matrix3> answer;
593matrix3({row3({0, 2, 3}), row3({1, 5, 6}), row3({4, 7, 8})}));
595matrix3({row3({1, 2, 3}), row3({0, 5, 6}), row3({4, 7, 8})}));
597matrix3({row3({1, 2, 3}), row3({4, 5, 6}), row3({0, 7, 8})}));
599matrix3({row3({1, 2, 3}), row3({4, 5, 6}), row3({7, 0, 8})}));
601matrix3({row3({1, 2, 3}), row3({4, 5, 6}), row3({7, 8, 0})}));
604std::cout <<
Solution.size() << std::endl;
606assert(
Solution.size() == answer.size());
610assert(it->get_state() == answer[i]);
616puzzle[0] = row3({5, 7, 3});
617puzzle[1] = row3({2, 0, 6});
618puzzle[2] = row3({1, 4, 8});
620ideal[0] = row3({1, 2, 3});
621ideal[1] = row3({4, 5, 6});
622ideal[2] = row3({7, 8, 0});
632std::cout <<
Solution.size() << std::endl;
636assert(
Solution[0].get_state() == ideal);
638std::cout << *it << std::endl;
644puzzle2[0] = row4({10, 1, 6, 2});
645puzzle2[1] = row4({5, 8, 4, 3});
646puzzle2[2] = row4({13, 0, 7, 11});
647puzzle2[3] = row4({14, 9, 15, 12});
650ideal2[0] = row4({1, 2, 3, 4});
651ideal2[1] = row4({5, 6, 7, 8});
652ideal2[2] = row4({9, 10, 11, 12});
653ideal2[3] = row4({13, 14, 15, 0});
661search2(Puzzle2, Ideal2);
665 automanhattan_distance2 =
669 for(
size_ti = 0; i < first.
get_size(); ++i) {
670 for(
size_tj = 0; j < first.
get_size(); ++j) {
671uint32_t
find= first.
get(i, j);
673 for(
size_tk = 0;
k< second.get_size(); ++
k) {
674 for(
size_tl = 0;
l< second.get_size(); ++
l) {
675 if(find == second.get(k, l)) {
676std::tie(m, n) = std::make_pair(k, l);
685ret += (std::max(m, i) - std::min(m, i)) +
686(std::max(n, j) - std::min(n, j));
693 autosol2 = search2.a_star_search(manhattan_distance2);
694std::cout << sol2.size() << std::endl;
697assert(24 == sol2.size());
699assert(sol2[0].get_state() == ideal2);
701 for(
autoit = sol2.rbegin(); it != sol2.rend(); ++it) {
702std::cout << *it << std::endl;
A class defining A* search algorithm. for some initial state and final state.
std::vector< Puzzle > Solution(std::shared_ptr< Info > FinalState, const MapOfPuzzleInfoWithPuzzleInfo &parent_of)
A helper solution: launches when a solution for AyStarSearch is found.
struct machine_learning::aystar_search::AyStarSearch::Info Info
Struct that handles all the information related to the current state.
std::vector< Puzzle > a_star_search(const std::function< uint32_t(const Puzzle &, const Puzzle &)> &dist, const uint32_t permissible_depth=30)
AyStarSearch(const Puzzle &initial, const Puzzle &final)
Parameterized constructor for AyStarSearch.
A class defining EightPuzzle/15-Puzzle game.
EightPuzzle & operator=(EightPuzzle &&A) noexcept
Move assignment operator.
~EightPuzzle()=default
Destructor of EightPuzzle.
std::vector< EightPuzzle< N > > generate_possible_moves()
Find all possible states after processing all possible moves, given the current state of the puzzle.
EightPuzzle()
Default constructor for EightPuzzle.
EightPuzzle & operator=(const EightPuzzle &A)
Copy assignment operator.
bool in_range(const uint32_t value) const
check whether the index value is bounded within the puzzle area
bool operator<(const EightPuzzle< N > &check) const
check whether one board is lexicographically smaller
std::pair< uint32_t, uint32_t > find_zero()
A helper array to evaluate the next state from current state;.
friend std::ostream & operator<<(std::ostream &op, const EightPuzzle< N > &SomeState)
friend operator to display EightPuzzle<>
bool operator==(const EightPuzzle< N > &check) const
check whether two boards are equal
uint32_t get(size_t i, size_t j) const
get the value from i units from right and j units from left side of the board
std::vector< std::pair< int8_t, int8_t > > moves
N x N array to store the current state of the Puzzle.
EightPuzzle(const std::array< std::array< uint32_t, N >, N > &init)
Parameterized Constructor for EightPuzzle.
EightPuzzle(const EightPuzzle< N > &A)
Copy constructor.
std::array< std::array< uint32_t, N >, N > get_state()
Returns the current state of the board.
size_t get_size() const
returns the size of the EightPuzzle (number of row / column)
EightPuzzle(const EightPuzzle< N > &&A) noexcept
Move constructor.
bool operator<=(const EightPuzzle< N > &check) const
check whether one board is lexicographically smaller or equal
double k(double x)
Another test function.
double l(double x)
Another test function.
static void test()
Self-test implementations.
int main()
Main function.
Functions for A* Search implementation.
size_t depth
stores h score
size_t heuristic_value
Holds the current state.
Info(const Info &A)
Copy constructor.
Info(const Puzzle &A)
constructor having Puzzle as parameter
Info(const Info &&A) noexcept
Move constructor.
~Info()=default
Destructor for Info.
Info()=default
stores g score
Info & operator=(const Info &A)
copy assignment operator
Info(const Puzzle &A, size_t h_value, size_t d)
constructor having three parameters
Info & operator=(Info &&A) noexcept
move assignment operator
Custom comparator for open_list.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4