HOG2
BFS.h
Go to the documentation of this file.
1 /*
2  * BFS.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 10/15/10.
6  * Copyright 2010 University of Denver. All rights reserved.
7  *
8  */
9 
10 #ifndef BFS_H
11 #define BFS_H
12 
13 #include "SearchEnvironment.h"
14 #include "FPUtil.h"
15 
16 #include <algorithm>
17 #include <iostream>
18 #include <unordered_map>
19 
20 template <class state, class action, class environment>
21 class BFS {
22 public:
23  BFS():stopAtGoal(true), nodeLimit(~(0ull)), verbose(true) {}
24  virtual ~BFS() {}
25  void DoBFS(environment *env, state from);
26  void GetPath(environment *env, state from, state to,
27  std::vector<state> &thePath);
28 
29  void SetNodeLimit(uint64_t value) {nodeLimit = value; }
30  void ClearNodeLimit() {nodeLimit = ~(0ull);}
31  void SetVerbose(bool v) {verbose = v;}
32  uint64_t GetNodesExpanded() { return nodesExpanded; }
33  uint64_t GetNodesTouched() { return nodesTouched; }
34  bool stopAtGoal;
35 private:
36  bool verbose;
37  uint64_t nodeLimit;
39 
40 };
41 
42 // pure BFS, just marking which states have been visited
43 // no path is saved
44 template <class state, class action, class environment>
45 void BFS<state, action, environment>::DoBFS(environment *env, state from)
46 {
47 // typedef std::unordered_map<uint64_t, bool, Hash64> BFSClosedList;
48 // BFSClosedList mClosed; // store parent id!
49  std::deque<state> mOpen;
50  std::deque<int> depth;
51  std::unordered_map<state, bool> mClosed;
52 
53  std::vector<state> successors;
54  nodesExpanded = nodesTouched = 0;
55 
56  mOpen.clear();
57  mClosed.clear();
58  depth.clear();
59 
60  depth.push_back(0);
61  mOpen.push_back(from);
62 
63  int currDepth = 0;
64  uint64_t lastNodes = 0, lastIter = 0;
65  while (mOpen.size() > 0)
66  {
67  assert(mOpen.size() == depth.size());
68  state s = mOpen.front();
69  mOpen.pop_front();
70  if (depth.front() != currDepth)
71  {
72 // printf("%ld tot %d inc %lld b %.2f\n", currDepth, nodesExpanded, nodesExpanded-lastNodes, (double)(nodesExpanded-lastNodes)/lastIter);
73  lastIter = nodesExpanded-lastNodes;
74  lastNodes = nodesExpanded;
75  }
76  currDepth = depth.front();
77  depth.pop_front();
78 
79  if (mClosed.find(s) != mClosed.end())
80  {
81 // if (mOpen.size() == 0)
82 // {
83 // std::cout << "Final state:\n" << s << std::endl;
84 // }
85  continue;
86  }
87  mClosed[s] = true;
88 
89  nodesExpanded++;
90  if (nodesExpanded > nodeLimit)
91  {
92  printf("Node limit hit. Aborting search\n");
93  return;
94  }
95  env->GetSuccessors(s, successors);
96  for (unsigned int x = 0; x < successors.size(); x++)
97  {
98  if (mClosed.find(successors[x]) == mClosed.end())
99  {
100  mOpen.push_back(successors[x]);
101  depth.push_back(currDepth+1);
102  }
103  }
104 // if (mOpen.size() == 0)
105 // {
106 // std::cout << "Final state:\n" << s << std::endl;
107 // }
108  }
109 // printf("Final depth: %d, Nodes Expanded %lu, Exponential BF: %f\n", currDepth, nodesExpanded, pow(nodesExpanded, (double)1.0/currDepth));
110 }
111 
112 // Richer BFS which saves information to allow the best path to be reconstructed.
113 template <class state, class action, class environment>
115  state from, state to,
116  std::vector<state> &thePath)
117 {
118 // typedef std::unordered_map<uint64_t, uint64_t, Hash64> BFSClosedList;
119  std::deque<std::pair<state, uint16_t>> mOpen;
120  //std::deque<int> depth;
121  std::unordered_map<state, state> mClosed; // store parent with each state
122 
123  thePath.resize(0);
124  bool goalFound = false;
125  int numGoals = 0;
126  nodesExpanded = nodesTouched = 0;
127 
128  mOpen.clear();
129  mClosed.clear();
130  //depth.clear();
131 
132  //depth.push_back(0);
133  mOpen.push_back({from, 0});
134  mClosed[from] = from; // root has itself as parent
135 
136  int currDepth = 0;
137  uint64_t lastNodes = 0, lastIter = 0;
138  state s;
139  state goal;
140  while (mOpen.size() > 0)
141  {
142  s = mOpen.front().first;
143  if (mOpen.front().second != currDepth)
144  {
145  if (verbose)
146  printf("%ld tot %d inc %lld b %.2f [%d]\n", currDepth, nodesExpanded, nodesExpanded-lastNodes, (double)(nodesExpanded-lastNodes)/lastIter, numGoals);
147  lastIter = nodesExpanded-lastNodes;
148  lastNodes = nodesExpanded;
149  }
150  currDepth = mOpen.front().second;//depth.front();
151  mOpen.pop_front();
152 // depth.pop_front();
153  if (env->GoalTest(s, to))
154  {
155  if (numGoals == 0)
156  goal = s;
157  goalFound = true;
158  numGoals++;
159  if (stopAtGoal)
160  break;
161  }
162  else { // don't expand goal nodes
163  nodesExpanded++;
164  if (nodesExpanded > nodeLimit)
165  {
166  printf("Node limit hit. Aborting search\n");
167  thePath.clear();
168  return;
169  }
170 
171  env->GetSuccessors(s, thePath);
172  for (unsigned int x = 0; x < thePath.size(); x++)
173  {
174  if (mClosed.find(thePath[x]) == mClosed.end())
175  {
176  mOpen.push_back({thePath[x], currDepth+1});
177  //depth.push_back(currDepth+1);
178  // printf("Setting parent of %" PRId64 " to be %" PRId64 "\n", env->GetStateHash(thePath[x]),
179  // env->GetStateHash(s));
180  mClosed[thePath[x]] = s;
181  }
182  }
183  }
184  }
185 // printf("%d tot %d inc %lld b %.2f\n", currDepth, nodesExpanded, nodesExpanded-lastNodes, (double)(nodesExpanded-lastNodes)/lastIter);
186 // std::cout << "Final state:\n" << s << std::endl;
187 
188  thePath.resize(0);
189  if (goalFound)
190  {
191  state parent;
192  s = goal;
193  // std::cout << s << std::endl;
194  do {
195  thePath.push_back(s);
196  parent = s;
197  s = mClosed[s];
198  } while (!(s == parent));
199  }
200  std::reverse(thePath.begin(), thePath.end());
201  // printf("Final depth: %d, Nodes Expanded %" PRId64 ", Exponential BF: %f\n", currDepth, nodesExpanded, pow(nodesExpanded, (double)1.0/currDepth));
202 }
203 
204 //template <class state, class action, class environment>
205 //void BFS<state, action>::GetPath(environment *env,
206 // state from, state to,
207 // std::vector<action> &thePath)
208 //{
209 // assert(!"not defined");
210 //}
211 
212 
213 #endif
BFS::nodeLimit
uint64_t nodeLimit
Definition: BFS.h:37
BFS::nodesTouched
uint64_t nodesTouched
Definition: BFS.h:38
BFS::DoBFS
void DoBFS(environment *env, state from)
Definition: BFS.h:45
BFS::stopAtGoal
bool stopAtGoal
Definition: BFS.h:34
FPUtil.h
BFS::GetNodesTouched
uint64_t GetNodesTouched()
Definition: BFS.h:33
BFS::GetPath
void GetPath(environment *env, state from, state to, std::vector< state > &thePath)
Definition: BFS.h:114
BFS::nodesExpanded
uint64_t nodesExpanded
Definition: BFS.h:38
BFS::SetNodeLimit
void SetNodeLimit(uint64_t value)
Definition: BFS.h:29
BFS::~BFS
virtual ~BFS()
Definition: BFS.h:24
BFS
Definition: BFS.h:21
verbose
const static int verbose
Definition: ClusterAbstraction.cpp:81
BFS::verbose
bool verbose
Definition: BFS.h:36
BFS::BFS
BFS()
Definition: BFS.h:23
BFS::GetNodesExpanded
uint64_t GetNodesExpanded()
Definition: BFS.h:32
BFS::ClearNodeLimit
void ClearNodeLimit()
Definition: BFS.h:30
SearchEnvironment.h
BFS::SetVerbose
void SetVerbose(bool v)
Definition: BFS.h:31