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_].empty()) {
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
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>
241  edge_list &edges = adjl_[nodeIndex];
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);
264  const_edge_range result(emptyEdges_.begin(), emptyEdges_.end());
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
math::operator<<
std::ostream & operator<<(std::ostream &o, const std::vector< std::vector< std::pair< T, T > > > v)
Definition: Graph.h:372
math::Graph::const_iterator::operator==
bool operator==(const const_iterator &i) const
Definition: Graph.h:47
math::Graph< Node2, AnotherDummy2 >::adj_iterator
adj_list::iterator adj_iterator
Definition: Graph.h:104
math::Graph::const_iterator::adj_list
Graph::adj_list adj_list
Definition: Graph.h:28
math::Graph< Node2, AnotherDummy2 >::indexer_type
std::map< Node2, index_type > indexer_type
Definition: Graph.h:108
math::Graph< Node2, AnotherDummy2 >::index_result
std::pair< index_type, bool > index_result
Definition: Graph.h:117
math::Graph::edges_
edge_store edges_
Definition: Graph.h:195
mps_fire.i
i
Definition: mps_fire.py:428
math::Graph::addNode
index_type addNode(const N &)
Definition: Graph.h:205
math::Graph< Node2, AnotherDummy2 >::edge_type
std::pair< index_type, index_type > edge_type
Definition: Graph.h:17
funct::false
false
Definition: Factorize.h:29
dqmiodumpmetadata.n
n
Definition: dqmiodumpmetadata.py:28
math::Graph::value_type::first
const N & first
Definition: Graph.h:93
math::Graph::nodes_
node_list nodes_
Definition: Graph.h:192
math::Graph::const_iterator::index_type
Graph::index_type index_type
Definition: Graph.h:27
math::Graph::const_iterator::value_type::a_
index_type a_
Definition: Graph.h:41
math::Graph::const_iterator::operator>
bool operator>(const const_iterator &i) const
Definition: Graph.h:86
math::Graph::const_iterator
Definition: Graph.h:23
math::Graph< Node2, AnotherDummy2 >::const_indexer_iterator
typename indexer_type::const_iterator const_indexer_iterator
Definition: Graph.h:110
math::Graph::const_iterator::vt_
value_type vt_
Definition: Graph.h:82
to
math::Graph::const_iterator::operator*
const value_type & operator*() const
Definition: Graph.h:73
math::Graph::adjl_
adj_list adjl_
Definition: Graph.h:189
math::Graph::~Graph
~Graph()
Definition: Graph.h:122
math::Graph::indexer_
indexer_type indexer_
Definition: Graph.h:198
math::Graph::const_iterator::operator!=
bool operator!=(const const_iterator &i) const
Definition: Graph.h:51
findQualityFiles.v
v
Definition: findQualityFiles.py:179
watchdog.const
const
Definition: watchdog.py:83
math::Graph< Node2, AnotherDummy2 >::const_edge_iterator
edge_list::const_iterator const_edge_iterator
Definition: Graph.h:114
EcalTangentSkim_cfg.o
o
Definition: EcalTangentSkim_cfg.py:42
math::Graph::const_iterator::edge_list
Graph::edge_list edge_list
Definition: Graph.h:29
heavyIonCSV_trainingSettings.idx
idx
Definition: heavyIonCSV_trainingSettings.py:5
math::Graph::findRoots
void findRoots(edge_list &) const
Definition: Graph.h:287
math::Graph::const_iterator::value_type
Definition: Graph.h:31
trigger::size_type
uint16_t size_type
Definition: TriggerTypeDefs.h:18
math::Graph::const_iterator::value_type::from
const N & from(void) const
Definition: Graph.h:35
math::Graph< Node2, AnotherDummy2 >::edge_list
std::vector< edge_type > edge_list
Definition: Graph.h:19
mps_fire.end
end
Definition: mps_fire.py:242
N
#define N
Definition: blowfish.cc:9
math::Graph::const_iterator::operator++
void operator++()
Definition: Graph.h:55
math::Graph::nodeIndex
index_result nodeIndex(const N &) const
Definition: Graph.h:219
math::Graph::replaceEdge
bool replaceEdge(const E &ldEdge, const E &newEdge)
Definition: Graph.h:323
math::Graph::edge_size
size_t edge_size() const
Definition: Graph.h:169
math::Graph::const_iterator::operator->
const value_type * operator->() const
Definition: Graph.h:75
math::Graph::value_type::second
const E & second
Definition: Graph.h:94
math::Graph::begin_iter
const_iterator begin_iter() const
Definition: Graph.h:165
math::Graph::size
auto size() const -> adj_list::size_type
Definition: Graph.h:176
math::Graph::emptyEdges_
edge_list emptyEdges_
Definition: Graph.h:201
math::Graph::const_iterator::value_type::gr_
const Graph & gr_
Definition: Graph.h:40
math::Graph::edgeData
const E & edgeData(index_type i) const
Definition: Graph.h:158
funct::true
true
Definition: Factorize.h:173
math::Graph< Node2, AnotherDummy2 >::node_list
std::vector< Node2 > node_list
Definition: Graph.h:100
math::Graph::addEdge
void addEdge(const N &from, const N &to, const E &edge)
Definition: Graph.h:231
math::Graph::const_iterator::value_type::e_
index_type e_
Definition: Graph.h:41
math::Graph::end_iter
const_iterator end_iter() const
Definition: Graph.h:167
math::Graph::const_iterator::const_iterator
const_iterator(const Graph &g, index_type ait, index_type eit)
Definition: Graph.h:80
trackerHitRTTI::vector
Definition: trackerHitRTTI.h:21
reco::JetExtendedAssociation::value_type
Container::value_type value_type
Definition: JetExtendedAssociation.h:30
math::Graph::const_iterator::value_type::to
const N & to(void) const
Definition: Graph.h:36
SelectiveReadoutTask_cfi.edges
edges
Definition: SelectiveReadoutTask_cfi.py:107
math::Graph::value_type
Definition: Graph.h:91
math::Graph::end
const_adj_iterator end() const
Definition: Graph.h:175
math::Graph::begin
adj_iterator begin()
Definition: Graph.h:172
math::Graph::const_iterator::value_type::edge
const E & edge(void) const
Definition: Graph.h:37
math::Graph::const_iterator::operator<
bool operator<(const const_iterator &i) const
Definition: Graph.h:84
math::Graph::clear
void clear()
it clear everything!
Definition: Graph.h:338
math::Graph::value_type::value_type
value_type(const N &n, const E &e)
Definition: Graph.h:92
math::Graph::invert
void invert(Graph &g) const
Definition: Graph.h:346
math::Graph< Node2, AnotherDummy2 >::const_edge_range
std::pair< const_edge_iterator, const_edge_iterator > const_edge_range
Definition: Graph.h:116
math
Definition: choleskyInversion.h:19
math::Graph< Node2, AnotherDummy2 >::indexer_iterator
typename indexer_type::iterator indexer_iterator
Definition: Graph.h:109
math::Graph< Node2, AnotherDummy2 >::index_type
std::vector< double >::size_type index_type
Definition: Graph.h:15
math::Graph::begin
const_adj_iterator begin() const
Definition: Graph.h:173
math::Graph::swap
void swap(Graph< N, E > &)
Definition: Graph.h:363
math::Graph::end
adj_iterator end()
Definition: Graph.h:174
math::Graph::Graph
Graph()
Definition: Graph.h:121
math::Graph
Definition: Graph.h:13
math::Graph::const_iterator::const_iterator
const_iterator(const Graph &g)
Definition: Graph.h:78
mps_fire.result
result
Definition: mps_fire.py:311
math::Graph< Node2, AnotherDummy2 >::edge_iterator
edge_list::iterator edge_iterator
Definition: Graph.h:113
math::Graph::replace
bool replace(const N &oldNode, const N &newNode)
Definition: Graph.h:310
math::Graph::edges
edge_range edges(index_type nodeIndex)
Definition: Graph.h:240
math::Graph::value_type::firstToValue
N firstToValue() const
Definition: Graph.h:95
math::Graph::nodeData
const N & nodeData(const edge_type &) const
Definition: Graph.h:272
math::Graph< Node2, AnotherDummy2 >::adj_list
std::vector< edge_list > adj_list
Definition: Graph.h:21
math::Graph< Node2, AnotherDummy2 >::edge_range
std::pair< edge_iterator, edge_iterator > edge_range
Definition: Graph.h:115
math::Graph::value_type::secondToValue
E secondToValue() const
Definition: Graph.h:96
math::Graph< Node2, AnotherDummy2 >::edge_store
std::vector< AnotherDummy2 > edge_store
Definition: Graph.h:101
g
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
RemoveAddSevLevel.flag
flag
Definition: RemoveAddSevLevel.py:116
findQualityFiles.size
size
Write out results.
Definition: findQualityFiles.py:443
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
math::Graph< Node2, AnotherDummy2 >::const_adj_iterator
adj_list::const_iterator const_adj_iterator
Definition: Graph.h:105