Search algorithms for the 8-puzzle solution
HillClimbingSolver.hpp
Go to the documentation of this file.
1 /**
2  * @author Douglas De Rizzo Meneghetti (douglasrizzom@gmail.com)
3  * @date 2017-6-26
4  * @brief Implementation of a hill-climbing optimization algorithm for the 8-puzzle.
5  */
6 
7 #ifndef SEARCH_HILLCLIMBINGSOLVER_HPP
8 #define SEARCH_HILLCLIMBINGSOLVER_HPP
9 
10 #include <OrderedList.hpp>
11 #include "Solver.hpp"
12 #include "Heuristic.hpp"
13 
14 //! Implementation of a hill-climbing optimization algorithm for the 8-puzzle.
15 class HillClimbingSolver : public Solver {
16  private:
17 
19  bool steepest;
20 
21  public:
22 
23  //! Initializes a regular hill-climbing 8-puzzle solver
24  //! \param h the heuristic to be minimized
25  explicit HillClimbingSolver(Heuristic *h) : heuristic(h), steepest(false) {
26  // not steep by default
27  }
28 
29  //! Initializes a hill-climbing 8-puzzle solver
30  //! \param h the heuristic to be minimized
31  //! \param steepest if true, always look for the best among all child states, otherwise choose the first one that is better than the parent state.
32  explicit HillClimbingSolver(Heuristic *h, bool steepest) : heuristic(h), steepest(steepest) {
33  }
34 
36  delete heuristic;
37  }
38 
39  //! Compares two states using the available heuristic.
40  //! The state that has the lowest heuristic is considered a more promising exploration candidate.
41  //! \param a
42  //! \param b
43  //! \return 1 if h(a) < h(b), -1 if h(a) > h(b), 0 if h(a) = h(b)
44  static int compare(GameState *a, GameState *b) {
45  Manhattan h;
46 
47  if (h.calc(*a) < h.calc(*b)) return 1;
48 
49  if (h.calc(*a) > h.calc(*b)) return - 1;
50 
51  return 0;
52  }
53 
55  // this algorithm has no memory, so no data structure to keep expanded states
56  GameState *only_one = &g0;
57  const clock_t start = clock();
58 
59  while (true) {
60  // check for goal
61  if (*game.getGoal() == *only_one) {
62  solved = true;
63  return endSearch(only_one, start);
64  }
65 
66  // expand children
68 
69  //variable to keep whether a child node has been chosen for exploration next
70  bool changed = false;
71  while (! children.isEmpty()) {
73 
74  // compare child with parent
75  if (compare(only_one, child) < 0) {
76  changed = true;
77  only_one = child;
78 
79  // if not steepest, stop after the first child that is better than the parent is found
80  if (! steepest) break;
81  }
82  }
83 
84  // if no new child nodes have been found, a local maximum has been found
85  if (! changed) {
86  cout << "WARNING: hill climbing procedure reached a local minimum\n";
87  solved = false;
88  return endSearch(only_one, start);
89  }
90  }
91  }
92 };
93 
94 #endif
HillClimbingSolver(Heuristic *h)
Initializes a regular hill-climbing 8-puzzle solver.
HillClimbingSolver(Heuristic *h, bool steepest)
Initializes a hill-climbing 8-puzzle solver.
Implementation of the Manhattan distance for the 8-puzzle.
Definition: Heuristic.hpp:23
virtual LinkedList< GameState * > solve(Game &g, GameState &gs)=0
Explores the game tree in search of the goal state.
static int compare(GameState *a, GameState *b)
Compares two states using the available heuristic.
int calc(GameState &currentState)
Calculates the heuristic value for a state.
Definition: Heuristic.hpp:26
LinkedList< GameState * > solve(Game &game, GameState &g0)
Explores the game tree in search of the goal state.
Describes a single state in the 8-puzzle.
Definition: GameState.hpp:18
Abtract class for heuristic functions.
Definition: Heuristic.hpp:13