CMS 3D CMS Logo

GraphWalker.h
Go to the documentation of this file.
1 #ifndef DATA_FORMATS_MATH_GRAPH_WALKER_H
2 #define DATA_FORMATS_MATH_GRAPH_WALKER_H
3 
5 #include <queue>
6 #include <vector>
7 
8 namespace math {
9 
11  template <class N, class E>
12  class GraphWalker {
13  public:
20 
21  // only a const-edge_range!
22  using edge_range = std::pair<const_edge_iterator, const_edge_iterator>;
23 
24  using stack_type = std::vector<edge_range>;
25  using bfs_type = std::queue<edge_type>;
26 
27  using result_type = bool;
29 
30  public:
32  GraphWalker(const Graph<N, E> &);
33 
35  GraphWalker(const Graph<N, E> &, const N &);
36 
37  // operations
38 
40 
42 
44 
45  result_type next();
46 
47  inline value_type current() const;
48 
50  value_type current_bfs() const;
51 
52  void reset();
53 
54  const stack_type &stack() const { return stack_; }
55 
56  protected:
57  // stack_.back().first corresponds to index of the current node!
58  stack_type stack_; // hierarchical stack used in navigation
59  bfs_type queue_; // breath first search queue
60  edge_list root_; // root of the walker
62 
63  private:
64  GraphWalker() = delete;
65  };
66 
67  template <class N, class E>
68  GraphWalker<N, E>::GraphWalker(const Graph<N, E> &g) : graph_(g) { // complexity = (no nodes) * (no edges)
69  graph_.findRoots(root_);
70  stack_.emplace_back(edge_range(root_.begin(), root_.end()));
71  if (!root_.empty()) {
72  queue_.push(root_[0]);
73  }
74  }
75 
76  template <class N, class E>
78  index_result rr = graph_.nodeIndex(root);
79  if (!rr.second) // no such root node, no walker can be created!
80  throw root;
81 
82  root_.emplace_back(edge_type(rr.first, 0));
83  stack_.emplace_back(edge_range(root_.begin(), root_.end()));
84  queue_.push(root_[0]);
85  }
86 
87  template <class N, class E>
89  const edge_range &er = stack_.back();
90  return value_type(graph_.nodeData(er.first->first), graph_.edgeData(er.first->second));
91  }
92 
93  template <class N, class E>
95  const edge_type &e = queue_.front();
96  return value_type(graph_.nodeData(e.first), graph_.edgeData(e.second));
97  }
98 
99  template <class N, class E>
101  stack_.clear();
102  stack_.emplace_back(edge_range(root_.begin(), root_.end()));
103  queue_.clear();
104  if (root_.size()) {
105  queue_.push(root_[0]);
106  }
107  }
108 
109  template <class N, class E>
111  result_type result = false;
112  const edge_range &adjEdges = graph_.edges(stack_.back().first->first);
113  if (adjEdges.first != adjEdges.second) {
114  stack_.emplace_back(adjEdges);
115  result = true;
116  }
117  return result;
118  }
119 
120  template <class N, class E>
122  result_type result = false;
123  edge_range &siblings = stack_.back();
124  if (siblings.first != (siblings.second - 1)) {
125  ++siblings.first;
126  result = true;
127  }
128  return result;
129  }
130 
131  template <class N, class E>
133  result_type result = false;
134  if (stack_.size() > 1) {
135  stack_.pop_back();
136  result = true;
137  }
138  return result;
139  }
140 
141  template <class N, class E>
143  result_type result = false;
144  if (firstChild()) {
145  result = true;
146  } else if (stack_.size() > 1 && nextSibling()) {
147  result = true;
148  } else {
149  while (parent()) {
150  if (stack_.size() > 1 && nextSibling()) {
151  result = true;
152  break;
153  }
154  }
155  }
156  return result;
157  }
158 
159  template <class N, class E>
161  result_type result(false);
162  if (!queue_.empty()) {
163  const edge_type &e = queue_.front();
164  const edge_range &er = graph_.edges(e.first);
165  const_edge_iterator it(er.first), ed(er.second);
166  for (; it != ed; ++it) {
167  queue_.push(*it);
168  }
169  queue_.pop();
170  if (!queue_.empty()) {
171  result = true;
172  }
173  }
174  return result;
175  }
176 
177 } // namespace math
178 
179 #endif
const Graph< N, E > & graph_
Definition: GraphWalker.h:61
typename math::Graph< DDLogicalPart, DDPosData * >::edge_iterator edge_iterator
Definition: GraphWalker.h:18
std::vector< double >::size_type index_type
Definition: Graph.h:15
typename math::Graph< DDLogicalPart, DDPosData * >::index_result index_result
Definition: GraphWalker.h:15
std::pair< index_type, bool > index_result
Definition: Graph.h:117
typename math::Graph< DDLogicalPart, DDPosData * >::edge_type edge_type
Definition: GraphWalker.h:16
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
result_type next_bfs()
Definition: GraphWalker.h:160
edge_list::iterator edge_iterator
Definition: Graph.h:113
stack_type stack_
Definition: GraphWalker.h:58
result_type parent()
Definition: GraphWalker.h:132
typename math::Graph< DDLogicalPart, DDPosData * >::value_type value_type
Definition: GraphWalker.h:28
result_type next()
Definition: GraphWalker.h:142
result_type firstChild()
Definition: GraphWalker.h:110
std::pair< const_edge_iterator, const_edge_iterator > edge_range
Definition: GraphWalker.h:22
value_type current_bfs() const
Definition: GraphWalker.h:94
Definition: Error.h:15
result_type nextSibling()
Definition: GraphWalker.h:121
std::pair< index_type, index_type > edge_type
Definition: Graph.h:17
#define N
Definition: blowfish.cc:9
const stack_type & stack() const
Definition: GraphWalker.h:54
std::vector< edge_type > edge_list
Definition: Graph.h:19
typename math::Graph< DDLogicalPart, DDPosData * >::index_type index_type
Definition: GraphWalker.h:14
GraphWalker()=delete
edge_list root_
Definition: GraphWalker.h:60
edge_list::const_iterator const_edge_iterator
Definition: Graph.h:114
typename math::Graph< DDLogicalPart, DDPosData * >::edge_list edge_list
Definition: GraphWalker.h:17
value_type current() const
Definition: GraphWalker.h:88
typename math::Graph< DDLogicalPart, DDPosData * >::const_edge_iterator const_edge_iterator
Definition: GraphWalker.h:19