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