bitrl & cuberl Documentation
Simulation engine for reinforcement learning agents
Loading...
Searching...
No Matches
a_star_search.h
Go to the documentation of this file.
1#ifndef A_STAR_SEARCH_H
2#define A_STAR_SEARCH_H
3
4#include "cubeai/base/cubeai_types.h"
5
6//#include "cubeai/data_structs/searchable_priority_queue.h"
7//#include "kernel/utilities/map_utilities.h"
8
9#include <utility>
10#include <set>
11#include <queue>
12#include <map>
13
14namespace cubeai{
15namespace astar_impl{
16
17
18
26template<typename MapType,
27 typename KeyArgType,
28 typename ValueArgType>
29typename MapType::iterator
30add_or_update_map(MapType& map, const KeyArgType& k, const ValueArgType& v){
31
32//find where k is or should be
33typename MapType::iterator lb = map.lower_bound(k);
34
35//if lb points to a pair whose key is equivalent to k
36//update the pair's value and return the iterator
37if(lb != map.end() &&
38 !(map.key_comp()(k,lb->first))){
39
40 lb->second = v;
41 return lb;
42 }
43 else{ //add pair (k,v) to map and return an iterator
44 //to the new map element
45
46 typedef typename MapType::value_type MVT;
47 return map.insert(lb,MVT(k,v));
48
49 }
50}
51
53{
54 template<typename NodeTp>
55 bool operator()(const NodeTp& n1,const NodeTp& n2)const;
56};
57
58template<typename NodeTp>
59bool
60fcost_astar_node_compare::operator()(const NodeTp& n1,const NodeTp& n2)const{
61
62 if(n1.data.f_cost > n2.data.f_cost){
63 return true;
64 }
65
66 return false;
67}
68
70{
71 template<typename NodeTp>
72 bool operator()(const NodeTp& n1,const NodeTp& n2)const;
73};
74
75template<typename NodeTp>
76bool
77id_astar_node_compare::operator()(const NodeTp& n1,const NodeTp& n2)const{
78
79 if(n1.id > n2.id){
80 return true;
81 }
82
83 return false;
84}
85} //astar_impl
86
92template<typename GraphTp, typename H>
93std::multimap<uint_t, uint_t>
94a_star_search(GraphTp& g, typename GraphTp::vertex_type& start, typename GraphTp::vertex_type& end, const H& h){
95
96 // for each node hodls where it
97 // came form
98 std::multimap<uint_t, uint_t> came_from;
99
100 if(start == end){
101
102 //we don't have to search for anything
103 came_from.insert(start.id, start.id);
104 return came_from;
105 }
106
107 typedef typename H::cost_type cost_t;
108 typedef typename GraphTp::vertex_type vertex_t;
109 typedef typename GraphTp::adjacency_iterator adjacency_iterator;
110 typedef typename GraphTp::vertex_type node_t;
111 typedef std::priority_queue<node_t, std::vector<node_t>, astar_impl::fcost_astar_node_compare> searchable_priority_queue;
112
113 std::set<node_t,astar_impl::id_astar_node_compare> explored;
114 searchable_priority_queue open;
115
116 //the cost of the path so far leading to this
117 //node is obviously zero at the start node
118 start.data.g_cost = 0.0;
119
120 //calculate the fCost from start node to the goal
121 //at the moment this can be done only heuristically
122 //start.data.fcost = h(start.data.position, end.data.position);
123 start.data.f_cost = h(start, end);
124 open.push(start);
125
126 while(!open.empty()){
127
128 //the vertex currently examined
129 const node_t cv = open.top();
130 open.pop();
131
132 //check if this is the goal
133 if(cv == end){
134 break;
135 }
136
137 //current node is not the goal so proceed
138 //add it to the explored (or else called closed) set
139 explored.insert(cv);
140
141 //get the adjacent neighbors
142 std::pair<adjacency_iterator,adjacency_iterator> neighbors = g.get_vertex_neighbors(cv);
143 auto itr = neighbors.first;
144
145 // loop over the neighbors
146 for(; itr != neighbors.second; itr++){
147
148 node_t& nv = g.get_vertex(itr);
149
150 if(open.contains(nv)){
151 continue;
152 }
153 else{
154
155 // we cannot move to the neighbor
156 // so no reason checking
157 if(!nv.data.can_move()){
158 explored.insert(nv);
159 continue;
160 }
161 }
162
163 // node id
164 uint_t nid = nv.id;
165
166 //search explored set by id
167 auto itr = std::find_if(explored.begin(), explored.end(),
168 [=](const node_t& n){return (n.id == nid);});
169
170 //the node has been explored
171 if(itr != explored.end()){
172 continue;
173 }
174
175 //this actually the cost of the path from the current node
176 //to reach its neighbor
177 cost_t tg_cost = cv.data.g_cost + h(cv, nv);//h(cv.data.position, nv.data.position);
178
179 if (tg_cost >= nv.data.g_cost) {
180 continue; //this is not a better path
181 }
182
183 // This path is the best until now. Record it!
184 astar_impl::add_or_update_map(came_from,nv.id,cv.id);
185
186 //came_from.put(nv.id,cv.id);
187 nv.data.g_cost = tg_cost;
188
189 //acutally calculate f(nn) = g(nn)+h(nn)
190 nv.data.f_cost = nv.data.g_cost + h(nv, end);//h(nv.data.position, end.data.position);
191
192 //if the neighbor not in open set add it
193 open.push(nv);
194
195 }
196 }
197
198 return came_from;
199}
200
201template<typename IdTp>
202std::vector<IdTp>
203reconstruct_a_star_path(const std::multimap<IdTp, IdTp>& map, const IdTp& start){
204
205 if(map.empty()){
206 return std::vector<IdTp>();
207 }
208
209 std::vector<IdTp> path;
210 path.push_back(start);
211
212 auto next_itr = map.find(start);
213
214 if(next_itr == map.end()){
215
216 //such a key does not exist
217 throw std::logic_error("Key: "+std::to_string(start)+" does not exist");
218 }
219
220 IdTp next = next_itr->second;
221 path.push_back(next);
222
223 while(next_itr!=map.end()){
224
225 next_itr = map.find(next);
226 if(next_itr != map.end()){
227 next = next_itr->second;
228 path.push_back(next);
229 }
230 }
231
232 //let's reverse the path
233 std::vector<IdTp> the_path;
234 the_path.reserve(path.size());
235 auto itrb = path.rbegin();
236 auto itre = path.rend();
237
238 while(itrb != itre){
239 the_path.push_back(*itrb++);
240 }
241
242 return the_path;
243}
244
245
246}
247
248#endif // A_STAR_SEARCH_H
MapType::iterator add_or_update_map(MapType &map, const KeyArgType &k, const ValueArgType &v)
See Scott Meyers Effective STL Item 24 for this function. If k isn't in the map efficiently add pair ...
Definition a_star_search.h:30
Definition mc_tree_search_solver.h:22
std::vector< IdTp > reconstruct_a_star_path(const std::multimap< IdTp, IdTp > &map, const IdTp &start)
Definition a_star_search.h:203
std::multimap< uint_t, uint_t > a_star_search(GraphTp &g, typename GraphTp::vertex_type &start, typename GraphTp::vertex_type &end, const H &h)
Simple implementation of A* algorithm at the moment the algorithm is only usable with a boost_unidire...
Definition a_star_search.h:94
bool operator()(const NodeTp &n1, const NodeTp &n2) const
Definition a_star_search.h:60
Definition a_star_search.h:70
bool operator()(const NodeTp &n1, const NodeTp &n2) const
Definition a_star_search.h:77