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>
13 {
14 public:
21 
22  // only a const-edge_range!
23  using edge_range = std::pair<const_edge_iterator, const_edge_iterator>;
24 
25  using stack_type = std::vector<edge_range>;
26  using bfs_type = std::queue<edge_type>;
27 
28  using result_type = bool;
30 
31 public:
33  GraphWalker(const Graph<N,E> &);
34 
36  GraphWalker(const Graph<N,E> &, const N & );
37 
38  // operations
39 
41 
43 
45 
46  result_type next();
47 
48  inline value_type current() const;
49 
51  value_type current_bfs() const;
52 
53  void reset();
54 
55  const stack_type & stack() const { return stack_;}
56 
57  protected:
58  // stack_.back().first corresponds to index of the current node!
59  stack_type stack_; // hierarchical stack used in navigation
60  bfs_type queue_; // breath first search queue
61  edge_list root_; // root of the walker
62  const Graph<N,E> & graph_;
63 
64  private:
65  GraphWalker() = delete;
66 };
67 
68 template<class N, class E>
70  : graph_(g)
71 { // complexity = (no nodes) * (no edges)
72  graph_.findRoots(root_);
73  stack_.emplace_back(edge_range(root_.begin(),root_.end()));
74  if (!root_.empty()) {
75  queue_.push(root_[0]);
76  }
77 }
78 
79 template<class N, class E>
81  : graph_(g)
82 {
83  index_result rr = graph_.nodeIndex(root);
84  if (!rr.second) // no such root node, no walker can be created!
85  throw root;
86 
87  root_.emplace_back(edge_type(rr.first, 0));
88  stack_.emplace_back(edge_range(root_.begin(),root_.end()));
89  queue_.push(root_[0]);
90 }
91 
92 template<class N, class E>
94 {
95  const edge_range & er = stack_.back();
96  return value_type(graph_.nodeData(er.first->first), graph_.edgeData(er.first->second));
97 }
98 
99 template<class N, class E>
101 {
102  const edge_type & e = queue_.front();
103  return value_type(graph_.nodeData(e.first), graph_.edgeData(e.second));
104 }
105 
106 template<class N, class E>
108 {
109  stack_.clear();
110  stack_.emplace_back(edge_range(root_.begin(),root_.end()));
111  queue_.clear();
112  if (root_.size()) {
113  queue_.push(root_[0]);
114  }
115 }
116 
117 template<class N, class E>
119 {
120  result_type result = false;
121  const edge_range & adjEdges
122  = graph_.edges(stack_.back().first->first);
123  if (adjEdges.first != adjEdges.second) {
124  stack_.emplace_back(adjEdges);
125  result = true;
126  }
127  return result;
128 }
129 
130 template<class N, class E>
132 {
133  result_type result = false;
134  edge_range & siblings = stack_.back();
135  if (siblings.first != (siblings.second - 1) ) {
136  ++siblings.first;
137  result = true;
138  }
139  return result;
140 }
141 
142 template<class N, class E>
144 {
145  result_type result = false;
146  if (stack_.size()>1) {
147  stack_.pop_back();
148  result = true;
149  }
150  return result;
151 }
152 
153 template<class N, class E>
155 {
156  result_type result = false;
157  if (firstChild()) {
158  result = true;
159  }
160  else if(stack_.size()>1 && nextSibling()) {
161  result = true;
162  }
163  else {
164  while(parent()) {
165  if(stack_.size()>1 && nextSibling()) {
166  result = true;
167  break;
168  }
169  }
170  }
171  return result;
172 }
173 
174 template<class N, class E>
176 {
177  result_type result(false);
178  if (!queue_.empty()) {
179  const edge_type & e = queue_.front();
180  const edge_range & er = graph_.edges(e.first);
181  const_edge_iterator it(er.first), ed(er.second);
182  for (; it != ed; ++it) {
183  queue_.push(*it);
184  }
185  queue_.pop();
186  if (!queue_.empty()) {
187  result=true;
188  }
189  }
190  return result;
191 }
192 
193 } // namespase math
194 
195 #endif
std::vector< double >::size_type index_type
Definition: Graph.h:16
typename math::Graph< DDLogicalPart, DDPosData * >::value_type value_type
Definition: GraphWalker.h:29
std::pair< index_type, bool > index_result
Definition: Graph.h:137
typename math::Graph< DDLogicalPart, DDPosData * >::index_type index_type
Definition: GraphWalker.h:15
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
typename math::Graph< DDLogicalPart, DDPosData * >::const_edge_iterator const_edge_iterator
Definition: GraphWalker.h:20
result_type next_bfs()
Definition: GraphWalker.h:175
typename math::Graph< DDLogicalPart, DDPosData * >::index_result index_result
Definition: GraphWalker.h:16
edge_list::iterator edge_iterator
Definition: Graph.h:133
stack_type stack_
Definition: GraphWalker.h:59
result_type parent()
Definition: GraphWalker.h:143
result_type next()
Definition: GraphWalker.h:154
typename math::Graph< DDLogicalPart, DDPosData * >::edge_list edge_list
Definition: GraphWalker.h:18
result_type firstChild()
Definition: GraphWalker.h:118
std::pair< const_edge_iterator, const_edge_iterator > edge_range
Definition: GraphWalker.h:23
value_type current_bfs() const
Definition: GraphWalker.h:100
Definition: Error.h:16
result_type nextSibling()
Definition: GraphWalker.h:131
typename math::Graph< DDLogicalPart, DDPosData * >::edge_type edge_type
Definition: GraphWalker.h:17
std::pair< index_type, index_type > edge_type
Definition: Graph.h:18
#define N
Definition: blowfish.cc:9
const stack_type & stack() const
Definition: GraphWalker.h:55
std::vector< edge_type > edge_list
Definition: Graph.h:20
GraphWalker()=delete
edge_list root_
Definition: GraphWalker.h:61
const Graph< N, E > & graph_
Definition: GraphWalker.h:62
edge_list::const_iterator const_edge_iterator
Definition: Graph.h:134
typename math::Graph< DDLogicalPart, DDPosData * >::edge_iterator edge_iterator
Definition: GraphWalker.h:19
value_type current() const
Definition: GraphWalker.h:93