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