symbolic
a_star.h
1 
10 #ifndef SYMBOLIC_PLANNING_A_STAR_H_
11 #define SYMBOLIC_PLANNING_A_STAR_H_
12 
13 #include <cstddef> // ptrdiff_t
14 #include <iterator> // std::input_iterator_tag
15 #include <queue> // std::priority_queue
16 #include <vector> // std::vector
17 
18 namespace symbolic {
19 
20 template <typename NodeT>
21 struct SearchNode {
22  SearchNode(const NodeT& node, const std::vector<NodeT>& ancestors)
23  : node(node), ancestors(ancestors) {}
24 
25  SearchNode(NodeT&& node, std::vector<NodeT>&& ancestors)
26  : node(std::move(node)), ancestors(std::move(ancestors)) {}
27 
28  NodeT node;
29  std::vector<NodeT> ancestors;
30 };
31 
32 template <typename NodeT, typename Compare>
33 class AStar {
34  public:
35  class iterator;
36 
37  AStar(const Compare& compare, const NodeT& root, size_t max_depth)
38  : kMaxDepth(max_depth), compare_(compare), root_(root) {}
39 
40  iterator begin() {
41  iterator it(compare_, root_, kMaxDepth);
42  return ++it;
43  }
44  iterator end() { return iterator(compare_); }
45 
46  private:
47  const size_t kMaxDepth;
48 
49  const Compare& compare_;
50  const NodeT& root_;
51 };
52 
53 template <typename NodeT, typename Compare>
54 class AStar<NodeT, Compare>::iterator {
55  public:
56  using iterator_category = std::input_iterator_tag;
57  using value_type = std::vector<NodeT>;
58  using difference_type = ptrdiff_t;
59  using pointer = const value_type*;
60  using reference = const value_type&;
61 
62  explicit iterator(const Compare& compare) : queue_(compare) {}
63  iterator(const Compare& compare, const NodeT& root, size_t max_depth)
64  : queue_(compare), kMaxDepth(max_depth) {
65  queue_.emplace(root, std::vector<NodeT>());
66  }
67 
68  iterator& operator++();
69  bool operator==(const iterator& other) const {
70  return queue_.empty() && other.queue_.empty();
71  }
72  bool operator!=(const iterator& other) const { return !(*this == other); }
73  reference operator*() const { return ancestors_; }
74 
75  private:
76  const size_t kMaxDepth = 0;
77 
78  std::priority_queue<SearchNode<NodeT>, std::vector<SearchNode<NodeT>>,
79  Compare>
80  queue_;
81  std::vector<NodeT> ancestors_;
82 };
83 
84 template <typename NodeT, typename Compare>
87  while (!queue_.empty()) {
88  SearchNode<NodeT> top = queue_.top();
89 
90  // Take ancestors list and append current node
91  ancestors_.swap(top.ancestors);
92  ancestors_.push_back(std::move(top.node));
93  queue_.pop();
94 
95  // Return if node evaluates to true
96  const NodeT& node = ancestors_.back();
97  if (node) break;
98 
99  // Skip children if max depth has been reached
100  if (ancestors_.size() > kMaxDepth) continue;
101 
102  // Add node's children to queue
103  for (const NodeT& child : node) {
104  queue_.emplace(child, ancestors_);
105  }
106  }
107  return *this;
108 }
109 
110 } // namespace symbolic
111 
112 #endif // SYMBOLIC_PLANNING_A_STAR_H_
symbolic
Definition: action.cc:329
symbolic::AStar::iterator
Definition: a_star.h:54
symbolic::AStar
Definition: a_star.h:33
symbolic::SearchNode
Definition: a_star.h:21