HOG2
UnitCostBidirectionalBFS.h
Go to the documentation of this file.
1 /*
2  * UnitCostBidirectionalBFS.h
3  * hog2
4  *
5  * Created by Nathan Sturtevant on 12/6/09.
6  * Copyright 2009 NS Software. All rights reserved.
7  *
8  */
9 
10 #ifndef UNITCOSTBIDIRECTIONALBFS
11 #define UNITCOSTBIDIRECTIONALBFS
12 
13 #include <iostream>
14 #include "SearchEnvironment.h"
15 #include <unordered_map>
16 #include "FPUtil.h"
17 
18 template <class state, class action>
20 public:
23  void GetPath(SearchEnvironment<state, action> *env, state from, state to,
24  std::vector<state> &thePath);
25  void GetPath(SearchEnvironment<state, action> *env, state from, state to,
26  std::vector<action> &thePath);
27 
28  uint64_t GetNodesExpanded() { return nodesExpanded; }
29  uint64_t GetNodesTouched() { return nodesTouched; }
30 private:
31  typedef std::unordered_map<uint64_t, state, Hash64> BFSClosedList;
32 
34  std::vector<state> &thePath);
36  std::vector<state> &nodesToExpand,
37  std::vector<state> &expansionLocation,
38  BFSClosedList &duplicateHash,
39  BFSClosedList &completionHash);
40 
41  unsigned long nodesExpanded, nodesTouched;
42 
43  std::vector<state> startOpenA;
44  std::vector<state> startOpenB;
45  std::vector<state> goalOpenA;
46  std::vector<state> goalOpenB;
47 // std::vector<state> closed;
48 
49  BFSClosedList startNodeTable; // store parent id!
51  state middle;
52 };
53 
54 template <class state, class action>
56  state from, state to,
57  std::vector<state> &thePath)
58 {
59  nodesExpanded = nodesTouched = 0;
60 
61  startNodeTable.clear();
62  goalNodeTable.clear();
63  startOpenA.clear();
64  startOpenB.clear();
65  goalOpenA.clear();
66  goalOpenB.clear();
67 
68  startOpenA.push_back(from);
69  goalOpenA.push_back(to);
70  startNodeTable[env->GetStateHash(from)] = from;
71  goalNodeTable[env->GetStateHash(to)] = to;
72 
73  // cheating and not return path
74 // thePath.push_back(from);
75 // thePath.push_back(to);
76  int cost = 0;
77  while (1)
78  {
79  cost++;
80  //printf("Expanding from start. List size %d\n", (int)startOpenA.size());
81  if (ExpandLayer(env, startOpenA, startOpenB, startNodeTable, goalNodeTable))
82  {
83  //printf("Found goal with cost %d\n", cost);
84  break;
85  }
86  if (startOpenB.size() == 0) break;
87  //printf("%d nodes generated in search\n", (int)startOpenB.size());
88  cost++;
89  //printf("Expanding from goal. List size %d\n", (int)goalOpenA.size());
90  if (ExpandLayer(env, goalOpenA, goalOpenB, goalNodeTable, startNodeTable))
91  {
92  //printf("Found goal with cost %d\n", cost);
93  break;
94  }
95  if (goalOpenB.size() == 0) break;
96  //printf("%d nodes generated in search\n", (int)goalOpenB.size());
97  cost++;
98  //printf("Expanding from start. List size %d\n", (int)startOpenB.size());
99  if (ExpandLayer(env, startOpenB, startOpenA, startNodeTable, goalNodeTable))
100  {
101  //printf("Found goal with cost %d\n", cost);
102  break;
103  }
104  if (startOpenA.size() == 0) break;
105  //printf("%d nodes generated in search\n", (int)startOpenA.size());
106  cost++;
107  //printf("Expanding from goal. List size %d\n", (int)goalOpenB.size());
108  if (ExpandLayer(env, goalOpenB, goalOpenA, goalNodeTable, startNodeTable))
109  {
110  //printf("Found goal with cost %d\n", cost);
111  break;
112  }
113  if (goalOpenA.size() == 0) break;
114  //printf("%d nodes generated in search\n", (int)goalOpenA.size());
115  }
116  ExtractPath(env, thePath);
117 }
118 
119 template <class state, class action>
121  state from, state to,
122  std::vector<action> &thePath)
123 {
124  assert(!"not defined");
125 }
126 
127 template <class state, class action>
129  std::vector<state> &thePath)
130 {
131  thePath.clear();
132  std::vector<state> forwardPart;
133  std::vector<state> backwardPart;
134 
135  forwardPart.push_back(middle);
136  backwardPart.push_back(middle);
137  while (1)
138  {
139  if (startNodeTable.find(env->GetStateHash(forwardPart.back())) != startNodeTable.end())
140  {
141  state s = startNodeTable[env->GetStateHash(forwardPart.back())];
142  if (forwardPart.back() == s) // reached the start state
143  {
144  break;
145  }
146  else {
147  forwardPart.push_back(s);
148  }
149 
150  }
151  else {
152  return false;
153  }
154  }
155  while (1)
156  {
157  if (goalNodeTable.find(env->GetStateHash(backwardPart.back())) != goalNodeTable.end())
158  {
159  state s = goalNodeTable[env->GetStateHash(backwardPart.back())];
160  if (backwardPart.back() == s) // reached the goal state
161  {
162  break;
163  }
164  else {
165  backwardPart.push_back(s);
166  }
167 
168  }
169  else {
170  return false;
171  }
172  }
173 
174  while (forwardPart.size() > 0)
175  {
176  thePath.push_back(forwardPart.back());
177  forwardPart.pop_back();
178  }
179  for (unsigned int x = 1; x < backwardPart.size(); x++)
180  {
181  thePath.push_back(backwardPart[x]);
182  }
183  // BFSClosedList startNodeTable; // store parent id!
184 // BFSClosedList goalNodeTable;
185  return true;
186 }
187 
188 template <class state, class action>
190  std::vector<state> &nodesToExpand,
191  std::vector<state> &expansionLocation,
192  BFSClosedList &duplicateHash,
193  BFSClosedList &completionHash)
194 {
195  while (nodesToExpand.size() > 0)
196  {
197  state s = nodesToExpand.back();
198  nodesToExpand.pop_back();
199 
200  //std::cout << "Expanding " << s << std::endl;
201 
202  // this doesn't belong here. Just pretending we aren't uniform cost
203  // check state against duplicateHash and completionHash
204  if (completionHash.find(env->GetStateHash(s)) != completionHash.end())
205  {
206  middle = s;
207  assert(startNodeTable.find(env->GetStateHash(s)) != startNodeTable.end());
208  assert(goalNodeTable.find(env->GetStateHash(s)) != goalNodeTable.end());
209  return true;
210  }
211 
212  // expand s
213  std::vector<state> succ;
214  env->GetSuccessors(s, succ);
215  nodesExpanded++;
216  for (unsigned int x = 0; x < succ.size(); x++)
217  {
218  nodesTouched++;
219 // // check successors against duplicateHash and completionHash
220  if (completionHash.find(env->GetStateHash(succ[x])) != completionHash.end())
221  {
222  //std::cout << "Successor: " << succ[x] << " [other frontier]" << std::endl;
223  duplicateHash[env->GetStateHash(succ[x])] = s;
224  middle = succ[x];
225  assert(startNodeTable.find(env->GetStateHash(middle)) != startNodeTable.end());
226  assert(goalNodeTable.find(env->GetStateHash(middle)) != goalNodeTable.end());
227  return true;
228  }
229  if (duplicateHash.find(env->GetStateHash(succ[x])) != duplicateHash.end())
230  {
231  //std::cout << "Successor: " << succ[x] << " [this frontier]" << std::endl;
232  continue;
233  }
234 
235  //std::cout << "Successor: " << succ[x] << " [new node]" << std::endl;
236  // then add to expansionLocation
237  duplicateHash[env->GetStateHash(succ[x])] = s;
238  expansionLocation.push_back(succ[x]);
239  }
240  }
241  return false;
242 }
243 
244 #endif
UnitCostBidirectionalBFS::nodesExpanded
unsigned long nodesExpanded
Definition: UnitCostBidirectionalBFS.h:41
UnitCostBidirectionalBFS::nodesTouched
unsigned long nodesTouched
Definition: UnitCostBidirectionalBFS.h:41
UnitCostBidirectionalBFS::GetNodesTouched
uint64_t GetNodesTouched()
Definition: UnitCostBidirectionalBFS.h:29
FPUtil.h
UnitCostBidirectionalBFS::GetNodesExpanded
uint64_t GetNodesExpanded()
Definition: UnitCostBidirectionalBFS.h:28
UnitCostBidirectionalBFS::goalOpenB
std::vector< state > goalOpenB
Definition: UnitCostBidirectionalBFS.h:46
UnitCostBidirectionalBFS::GetPath
void GetPath(SearchEnvironment< state, action > *env, state from, state to, std::vector< state > &thePath)
Definition: UnitCostBidirectionalBFS.h:55
UnitCostBidirectionalBFS::goalNodeTable
BFSClosedList goalNodeTable
Definition: UnitCostBidirectionalBFS.h:50
UnitCostBidirectionalBFS::startOpenB
std::vector< state > startOpenB
Definition: UnitCostBidirectionalBFS.h:44
UnitCostBidirectionalBFS::UnitCostBidirectionalBFS
UnitCostBidirectionalBFS()
Definition: UnitCostBidirectionalBFS.h:21
UnitCostBidirectionalBFS::BFSClosedList
std::unordered_map< uint64_t, state, Hash64 > BFSClosedList
Definition: UnitCostBidirectionalBFS.h:31
UnitCostBidirectionalBFS::startOpenA
std::vector< state > startOpenA
Definition: UnitCostBidirectionalBFS.h:43
SearchEnvironment::GetSuccessors
virtual void GetSuccessors(const state &nodeID, std::vector< state > &neighbors) const =0
UnitCostBidirectionalBFS::middle
state middle
Definition: UnitCostBidirectionalBFS.h:51
UnitCostBidirectionalBFS::ExtractPath
bool ExtractPath(SearchEnvironment< state, action > *env, std::vector< state > &thePath)
Definition: UnitCostBidirectionalBFS.h:128
UnitCostBidirectionalBFS::startNodeTable
BFSClosedList startNodeTable
Definition: UnitCostBidirectionalBFS.h:49
UnitCostBidirectionalBFS
Definition: UnitCostBidirectionalBFS.h:19
UnitCostBidirectionalBFS::~UnitCostBidirectionalBFS
virtual ~UnitCostBidirectionalBFS()
Definition: UnitCostBidirectionalBFS.h:22
SearchEnvironment::GetStateHash
virtual uint64_t GetStateHash(const state &node) const =0
UnitCostBidirectionalBFS::ExpandLayer
bool ExpandLayer(SearchEnvironment< state, action > *env, std::vector< state > &nodesToExpand, std::vector< state > &expansionLocation, BFSClosedList &duplicateHash, BFSClosedList &completionHash)
Definition: UnitCostBidirectionalBFS.h:189
SearchEnvironment
Definition: SearchEnvironment.h:30
SearchEnvironment.h
UnitCostBidirectionalBFS::goalOpenA
std::vector< state > goalOpenA
Definition: UnitCostBidirectionalBFS.h:45