CMS 3D CMS Logo

Graph.h
Go to the documentation of this file.
1 #ifndef DATA_FORMATS_MATH_GRAPH_H
2 #define DATA_FORMATS_MATH_GRAPH_H
3 
4 #include <iostream>
5 #include <map>
6 #include <vector>
7 
8 // Adjecencylist Graph
9 namespace math {
10 
11 // N,E must be concepts of default constructable, assignable, copyable, operator<
12 template <class N, class E>
13 class Graph
14 {
15 public:
17  // (node-index target, edge)
18  using edge_type = std::pair<index_type, index_type>;
19  // (std::vector of edge_types for the adj_list)
20  using edge_list = std::vector<edge_type>;
21  // (node-index -> edge_list) the adjacency-list
22  using adj_list = std::vector<edge_list>;
23 
25  {
26  friend class Graph<N, E>;
27  public:
31 
32  struct value_type
33  {
34  friend class Graph<N,E>::const_iterator;
35  value_type( const Graph & g, index_type a, index_type e )
36  : gr_( g ), a_( a ), e_( e )
37  { }
38 
39  const N & from( void ) const { return gr_.nodeData( a_ ); }
40  const N & to( void ) const { return gr_.nodeData( gr_.adjl_[a_][e_].first ); }
41  const E & edge( void ) const { return gr_.edgeData( gr_.adjl_[a_][e_].second ); }
42 
43  private:
44  const Graph & gr_;
46  };
47 
49  using pointer = value_type*;
50 
51  bool operator==( const const_iterator & i ) const {
52  return (( vt_.a_ == i.vt_.a_ ) && ( vt_.e_ == i.vt_.e_ )) ? true : false;
53  }
54 
55  bool operator!=( const const_iterator & i ) const {
56  return (( vt_.a_ == i.vt_.a_ ) && ( vt_.e_ == i.vt_.e_ )) ? false : true;
57  }
58 
59  void operator++() {
60  while( vt_.gr_.size() > vt_.a_ )
61  {
62  index_type i = vt_.gr_.adjl_[vt_.a_].size();
63  if( i > vt_.e_+1 )
64  {
65  ++vt_.e_;
66  return;
67  }
68  vt_.e_=0;
69  ++vt_.a_;
70  while( vt_.gr_.size() > vt_.a_ )
71  {
72  if( vt_.gr_.adjl_[vt_.a_].size())
73  {
74  return;
75  }
76  ++vt_.a_;
77  }
78  }
79  }
80 
81  const value_type & operator*() const {
82  return vt_;
83  }
84 
85  const value_type * operator->() const {
86  return &vt_;
87  }
88 
89  private:
90  explicit const_iterator( const Graph & g )
91  : vt_( g, 0, 0 )
92  {}
93 
94  const_iterator( const Graph & g, index_type ait, index_type eit )
95  : vt_( g, ait, eit )
96  {}
97 
99 
100  bool operator<( const const_iterator & i ) const {
101  return ( vt_.a_ < i.vt_.a_ ) && ( vt_.e_ < i.vt_.e_ );
102  }
103 
104  bool operator>(const const_iterator & i) const {
105  return ( vt_.a_ > i.vt_.a_ ) && ( vt_.e_ > i.vt_.e_ );
106  }
107  };
108 
109  // Graphtypes
110 
111  struct value_type {
112  value_type(const N & n, const E & e) : first(n), second(e) { }
113  const N & first;
114  const E & second;
115  N firstToValue() const { return first; }
116  E secondToValue() const { return second; }
117  };
118 
119  // (node-index -> node)
120  using node_list = std::vector<N>;
121  using edge_store = std::vector<E>;
122 
123  // (node-index -> edge_list) the adjacency-list
124  using adj_iterator = adj_list::iterator;
125  using const_adj_iterator = adj_list::const_iterator;
126 
127  // assigns a node-index to the node
128  using indexer_type = std::map<N, index_type>;
129  using indexer_iterator = typename indexer_type::iterator;
130  using const_indexer_iterator = typename indexer_type::const_iterator;
131 
132  // supported iterators and ranges
133  using edge_iterator = edge_list::iterator;
134  using const_edge_iterator = edge_list::const_iterator;
135  using edge_range = std::pair<edge_iterator, edge_iterator>;
136  using const_edge_range = std::pair<const_edge_iterator, const_edge_iterator>;
137  using index_result = std::pair<index_type, bool>;
138 
139 public:
140  // creation, deletion
141  Graph() : edges_(1) { }
142  ~Graph() { }
143 
144  // operations
145 
146  // O(log(n)), n...number of nodes
147  index_type addNode(const N &);
148  // O(log(n*e)), n,e...number of nodes,edges
149  void addEdge(const N & from, const N & to, const E & edge);
150 
151  // O(1)
152  //index_type addNode(const node_type &);
153  // O(log(e))
154  //index_type addEdge(const node_type & from, const node_type & to, const E & e);
155 
156  inline index_result nodeIndex(const N &) const;
157 
158  //index_type edgeIndex(const E &) const;
159 
160  // indexed edge_ranges, O(1) operation
161  inline edge_range edges(index_type nodeIndex);
162  inline const_edge_range edges(index_type nodeIndex) const;
163 
164  // indexed edge_ranges, O(log(n)) operation, n...number of nodes
165  inline edge_range edges(const N &);
166  inline const_edge_range edges(const N &) const;
167 
168  inline const N & nodeData(const edge_type &) const;
169  inline const N & nodeData(index_type) const;
170  inline const N & nodeData(const const_adj_iterator &) const;
171 
172  // replace oldNode by newNode O(log(n))
173  bool replace(const N & oldNode , const N & newNode );
174 
175  //replace oldEdge by newEdge
176  bool replaceEdge(const E & ldEdge, const E &newEdge );
177 
178  const E & edgeData(index_type i) const { return edges_[i]; }
179  // const N & nodeData(const adj_iterator &) const;
180  // index of a node (O(log(n))
181 
183  void clear();
184  // access to the linear-iterator
185  const_iterator begin_iter() const { return const_iterator(*this); }
186 
187  const_iterator end_iter() const { return const_iterator(*this, adjl_.size(),0); }
188 
189  size_t edge_size() const { return edges_.size(); }
190 
191  // access to the adjacency-list
192  adj_iterator begin() { return adjl_.begin(); }
193  const_adj_iterator begin() const { return adjl_.begin(); }
194  adj_iterator end() { return adjl_.end(); }
195  const_adj_iterator end() const { return adjl_.end(); }
196  auto size() const -> adj_list::size_type { return adjl_.size(); }
197 
198  // finds all roots of the Graph and puts them into the edge_list
199  void findRoots(edge_list &) const;
200 
201  // inverts the directed Graph, i.e. edge(A,B) -> edge(B,A)
202  void invert(Graph & g) const;
203 
204  void swap( Graph<N, E> & );
205 
206  // Data
207 private:
208 
209  // adjacency list
211 
212  // std::mapping of index to node
214 
215  // std::mapping of indes to edge
217 
218  // indexer for N and E
219  indexer_type indexer_; // eIndexer_;
220 
221  // dummy
223 
224 };
225 
226 
227 
228 template<class N, class E>
230 {
231  index_type idx = indexer_.size() ; // +1;
232  std::pair<indexer_iterator,bool> result
233  = indexer_.insert(typename indexer_type::value_type(node,idx));
234 
235  if ( result.second ) { // new index!
236  nodes_.emplace_back(node);
237  adjl_.emplace_back(edge_list());
238  }
239  else {
240  idx = result.first->second;
241  }
242  return idx;
243 }
244 
245 
246 template<class N, class E>
248 {
249  typename indexer_type::const_iterator result = indexer_.find(node);
250  index_type idx = 0;
251  bool flag = false;
252  if (result != indexer_.end()) {
253  flag = true;
254  idx = result->second;
255  }
256  return index_result(idx, flag);
257 }
258 
259 
260 template<class N, class E>
261 void Graph<N,E>::addEdge(const N & from, const N & to, const E & edge)
262 {
263  index_type iFrom = addNode(from);
264  index_type iTo = addNode(to);
265 
266  adjl_[iFrom].emplace_back(edge_type(iTo,edges_.size()));
267  edges_.emplace_back(edge);
268 }
269 
270 
271 template<class N, class E>
273 {
275  return edge_range(edges.begin(), edges.end());
276 }
277 
278 
279 template<class N, class E>
281 {
282  const edge_list & edges = adjl_[nodeIndex];
283  return const_edge_range(edges.begin(), edges.end());
284 }
285 
286 
287 template<class N, class E>
289 {
290  index_result idxResult = nodeIndex(node);
291  edge_range result(emptyEdges_.begin(),emptyEdges_.end());
292  if (idxResult.second) {
293  result = edges(idxResult.first);
294  }
295  return result;
296 }
297 
298 
299 template<class N, class E>
301 {
302  index_result idxResult = nodeIndex(node);
304  if (idxResult.second) {
305  result = edges(idxResult.first);
306  }
307  return result;
308 }
309 
310 
311 template<class N, class E>
312 const N & Graph<N,E>::nodeData(const edge_type & edge) const
313 {
314  return nodes_[edge.first];
315 }
316 
317 
318 template<class N, class E>
320 {
321  return nodes_[i];
322 }
323 
324 
325 template<class N, class E>
326 const N & Graph<N,E>::nodeData(const const_adj_iterator & it) const
327 {
328  return nodes_[it-adjl_.begin()];
329 }
330 
331 template<class N, class E>
333 {
334  result.clear();
335 
336  const_adj_iterator it = begin();
337  const_adj_iterator ed = end();
338  std::vector<bool> rootCandidate(size(), true);
339 
340  for (; it != ed; ++it) {
341  const edge_list & el = *it;
342  for (auto const & el_it : el) {
343  rootCandidate[el_it.first]=false;
344  }
345  }
347  std::vector<bool>::size_type v_ed = rootCandidate.size();
348  for (; v_sz < v_ed; ++v_sz) {
349  if (rootCandidate[v_sz]) {
350  result.emplace_back(edge_type(v_sz,0));
351  }
352  }
353 }
354 
355 template<class N, class E>
356 bool Graph<N,E>::replace(const N & oldNode, const N & newNode)
357 {
358  typename indexer_type::iterator it = indexer_.find(oldNode);
359  if (it != indexer_.end()) {
360  index_type oldIndex = it->second;
361  nodes_[oldIndex]=newNode;
362  indexer_[newNode]=oldIndex;
363  indexer_.erase(it);
364  }
365  else throw(oldNode);
366  return true;
367 }
368 
369 template<class N, class E>
370 bool Graph<N,E>::replaceEdge(const E & oldEdge, const E & newEdge)
371 {
372  typename edge_store::size_type it = 0;
373  typename edge_store::size_type ed = edges_.size();
374  bool result = false;
375  for (; it < ed; ++it) {
376  if ( edges_[it] == oldEdge ) {
377  result = true;
378  edges_[it] = newEdge;
379  break;
380  }
381  }
382  return result;
383 }
384 
385 template<class N, class E>
387 {
388  adjl_.clear();
389  nodes_.clear();
390  edges_.clear();
391  indexer_.clear();
392 }
393 
394 template<class N, class E>
396 {
397  adj_list::size_type it = 0;
398  adj_list::size_type ed = adjl_.size();
399  // loop over adjacency-list of this Graph
400  for (; it < ed; ++it) {
401  const edge_list & el = adjl_[it];
402  edge_list::size_type eit = 0;
403  edge_list::size_type eed = el.size();
404  // loop over edges of current node
405  for (; eit < eed; ++eit) {
406  const edge_type & e = el[eit];
407  g.addEdge(nodeData(e.first), nodeData(it), edgeData(e.second));
408  }
409  }
410 }
411 
412 template<class N, class E>
414  adjl_.swap(g.adjl_);
415  nodes_.swap(g.nodes_);
416  edges_.swap(g.edges_);
417  indexer_.swap(g.indexer_);
418  emptyEdges_.swap(g.emptyEdges_);
419 }
420 
421 template<typename T> std::ostream & operator<<(std::ostream & o, const std::vector< std::vector<std::pair<T,T> > > v)
422 {
423  typedef typename std::vector<std::vector<std::pair<T,T> > > v_t;
424  typedef typename std::vector<std::pair<T,T> > i_t;
425 
426  typename v_t::const_iterator it(v.begin()), ed(v.end());
427  for (; it != ed; ++it) {
428  typename i_t::const_iterator iit(it->begin()), ied(it->end());
429  for(; iit != ied; ++iit) {
430  o << iit->first << ':' << iit->second << std::endl;
431  }
432  }
433  return o;
434 }
435 
436 } // namespace math
437 
438 #endif
edge_store edges_
Definition: Graph.h:216
node_list nodes_
Definition: Graph.h:213
bool operator!=(const const_iterator &i) const
Definition: Graph.h:55
const_adj_iterator begin() const
Definition: Graph.h:193
const_iterator(const Graph &g)
Definition: Graph.h:90
std::vector< double >::size_type index_type
Definition: Graph.h:16
Graph::adj_list adj_list
Definition: Graph.h:29
bool operator<(const const_iterator &i) const
Definition: Graph.h:100
const N & to(void) const
Definition: Graph.h:40
N firstToValue() const
Definition: Graph.h:115
edge_range edges(index_type nodeIndex)
Definition: Graph.h:272
void addEdge(const N &from, const N &to, const E &edge)
Definition: Graph.h:261
std::pair< const_edge_iterator, const_edge_iterator > const_edge_range
Definition: Graph.h:136
index_type addNode(const N &)
Definition: Graph.h:229
std::pair< index_type, bool > index_result
Definition: Graph.h:137
const_iterator end_iter() const
Definition: Graph.h:187
void invert(Graph &g) const
Definition: Graph.h:395
std::vector< AnotherDummy2 > edge_store
Definition: Graph.h:121
uint16_t size_type
const E & second
Definition: Graph.h:114
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
U second(std::pair< T, U > const &p)
bool replace(const N &oldNode, const N &newNode)
Definition: Graph.h:356
edge_list::iterator edge_iterator
Definition: Graph.h:133
E secondToValue() const
Definition: Graph.h:116
std::pair< edge_iterator, edge_iterator > edge_range
Definition: Graph.h:135
edge_list emptyEdges_
Definition: Graph.h:222
const_iterator begin_iter() const
Definition: Graph.h:185
adj_list::iterator adj_iterator
Definition: Graph.h:124
const N & nodeData(const edge_type &) const
Definition: Graph.h:312
const E & edgeData(index_type i) const
Definition: Graph.h:178
const_adj_iterator end() const
Definition: Graph.h:195
void findRoots(edge_list &) const
Definition: Graph.h:332
index_result nodeIndex(const N &) const
Definition: Graph.h:247
const value_type & operator*() const
Definition: Graph.h:81
void swap(Graph< N, E > &)
Definition: Graph.h:413
~Graph()
Definition: Graph.h:142
void clear()
it clear everything!
Definition: Graph.h:386
size_t edge_size() const
Definition: Graph.h:189
std::map< Node2, index_type > indexer_type
Definition: Graph.h:128
Definition: Error.h:16
std::vector< Node2 > node_list
Definition: Graph.h:120
const value_type * operator->() const
Definition: Graph.h:85
std::pair< index_type, index_type > edge_type
Definition: Graph.h:18
Graph::index_type index_type
Definition: Graph.h:28
adj_iterator end()
Definition: Graph.h:194
std::vector< edge_list > adj_list
Definition: Graph.h:22
#define N
Definition: blowfish.cc:9
std::vector< edge_type > edge_list
Definition: Graph.h:20
const_iterator(const Graph &g, index_type ait, index_type eit)
Definition: Graph.h:94
auto size() const -> adj_list::size_type
Definition: Graph.h:196
typename indexer_type::iterator indexer_iterator
Definition: Graph.h:129
adj_iterator begin()
Definition: Graph.h:192
const E & edge(void) const
Definition: Graph.h:41
value_type(const N &n, const E &e)
Definition: Graph.h:112
edge_list::const_iterator const_edge_iterator
Definition: Graph.h:134
Graph::edge_list edge_list
Definition: Graph.h:30
bool operator>(const const_iterator &i) const
Definition: Graph.h:104
adj_list::const_iterator const_adj_iterator
Definition: Graph.h:125
indexer_type indexer_
Definition: Graph.h:219
const N & from(void) const
Definition: Graph.h:39
bool operator==(const const_iterator &i) const
Definition: Graph.h:51
typename indexer_type::const_iterator const_indexer_iterator
Definition: Graph.h:130
bool replaceEdge(const E &ldEdge, const E &newEdge)
Definition: Graph.h:370
adj_list adjl_
Definition: Graph.h:210