CMS 3D CMS Logo

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