andres::graph
digraph.hxx
1 #pragma once
2 #ifndef ANDRES_GRAPH_DIGRAPH_HXX
3 #define ANDRES_GRAPH_DIGRAPH_HXX
4 
5 #include <cassert>
6 #include <cstddef>
7 #include <iterator> // std::random_access_iterator
8 #include <vector>
9 #include <set>
10 #include <iostream>
11 #include <utility> // std::pair
12 #include <algorithm> // std::fill
13 
14 #include "adjacency.hxx"
15 #include "subgraph.hxx"
16 #include "visitor.hxx"
17 #include "detail/graph.hxx"
18 
19 namespace andres {
20 namespace graph {
21 
23 template<typename VISITOR = IdleGraphVisitor<std::size_t> >
24 class Digraph {
25 public:
26  typedef VISITOR Visitor;
27  typedef detail::VertexIterator VertexIterator;
28  typedef detail::EdgeIterator EdgeIterator;
29  typedef detail::Adjacencies::const_iterator AdjacencyIterator;
30 
31  typedef typename AdjacencyIterator::value_type AdjacencyType;
32 
33  // construction
34  Digraph(const Visitor& = Visitor());
35  Digraph(const std::size_t, const Visitor& = Visitor());
36  void assign(const Visitor& = Visitor());
37  void assign(const std::size_t, const Visitor& = Visitor());
38  void reserveVertices(const std::size_t);
39  void reserveEdges(const std::size_t);
40 
41  // iterator access
42  VertexIterator verticesFromVertexBegin(const std::size_t) const;
43  VertexIterator verticesFromVertexEnd(const std::size_t) const;
44  VertexIterator verticesToVertexBegin(const std::size_t) const;
45  VertexIterator verticesToVertexEnd(const std::size_t) const;
46  EdgeIterator edgesFromVertexBegin(const std::size_t) const;
47  EdgeIterator edgesFromVertexEnd(const std::size_t) const;
48  EdgeIterator edgesToVertexBegin(const std::size_t) const;
49  EdgeIterator edgesToVertexEnd(const std::size_t) const;
50  AdjacencyIterator adjacenciesFromVertexBegin(const std::size_t) const;
51  AdjacencyIterator adjacenciesFromVertexEnd(const std::size_t) const;
52  AdjacencyIterator adjacenciesToVertexBegin(const std::size_t) const;
53  AdjacencyIterator adjacenciesToVertexEnd(const std::size_t) const;
54 
55  // access
56  std::size_t numberOfVertices() const;
57  std::size_t numberOfEdges() const;
58  std::size_t numberOfEdgesFromVertex(const std::size_t) const;
59  std::size_t numberOfEdgesToVertex(const std::size_t) const;
60  std::size_t vertexOfEdge(const std::size_t, const std::size_t) const;
61  std::size_t edgeFromVertex(const std::size_t, const std::size_t) const;
62  std::size_t edgeToVertex(const std::size_t, const std::size_t) const;
63  std::size_t vertexFromVertex(const std::size_t, const std::size_t) const;
64  std::size_t vertexToVertex(const std::size_t, const std::size_t) const;
65  const AdjacencyType& adjacencyFromVertex(const std::size_t, const std::size_t) const;
66  const AdjacencyType& adjacencyToVertex(const std::size_t, const std::size_t) const;
67  std::pair<bool, std::size_t> findEdge(const std::size_t, const std::size_t) const;
68  bool multipleEdgesEnabled() const;
69 
70  // manipulation
71  std::size_t insertVertex();
72  std::size_t insertVertices(const std::size_t);
73  std::size_t insertEdge(const std::size_t, const std::size_t);
74  void eraseVertex(const std::size_t);
75  void eraseEdge(const std::size_t);
76  bool& multipleEdgesEnabled();
77 
78 private:
79  typedef detail::Adjacencies Adjacencies;
80  struct Vertex {
81  Vertex()
82  : from_(), to_()
83  {}
84  Adjacencies from_;
85  Adjacencies to_;
86  };
87  typedef detail::Edge<true> Edge;
88 
89  void insertAdjacenciesForEdge(const std::size_t);
90  void eraseAdjacenciesForEdge(const std::size_t);
91 
92  std::vector<Vertex> vertices_;
93  std::vector<Edge> edges_;
94  bool multipleEdgesEnabled_;
95  Visitor visitor_;
96 };
97 
98 // implementation of Digraph
99 
104 template<typename VISITOR>
105 inline
107  const Visitor& visitor
108 )
109 : vertices_(),
110  edges_(),
111  multipleEdgesEnabled_(false),
112  visitor_(visitor)
113 {}
114 
120 template<typename VISITOR>
121 inline
123  const std::size_t numberOfVertices,
124  const Visitor& visitor
125 )
126 : vertices_(numberOfVertices),
127  edges_(),
128  multipleEdgesEnabled_(false),
129  visitor_(visitor)
130 {
131  visitor_.insertVertices(0, numberOfVertices);
132 }
133 
138 template<typename VISITOR>
139 inline void
141  const Visitor& visitor
142 ) {
143  vertices_.clear();
144  edges_.clear();
145  multipleEdgesEnabled_ = false;
146  visitor_ = visitor;
147 }
148 
154 template<typename VISITOR>
155 inline void
157  const std::size_t numberOfVertices,
158  const Visitor& visitor
159 ) {
160  vertices_.resize(numberOfVertices);
161  std::fill(vertices_.begin(), vertices_.end(), Vertex());
162  edges_.clear();
163  multipleEdgesEnabled_ = false;
164  visitor_ = visitor;
165  visitor_.insertVertices(0, numberOfVertices);
166 }
167 
170 template<typename VISITOR>
171 inline std::size_t
173  return vertices_.size();
174 }
175 
178 template<typename VISITOR>
179 inline std::size_t
181  return edges_.size();
182 }
183 
190 template<typename VISITOR>
191 inline std::size_t
193  const std::size_t vertex
194 ) const {
195  return vertices_[vertex].to_.size();
196 }
197 
204 template<typename VISITOR>
205 inline std::size_t
207  const std::size_t vertex
208 ) const {
209  return vertices_[vertex].from_.size();
210 }
211 
217 template<typename VISITOR>
218 inline std::size_t
220  const std::size_t edge,
221  const std::size_t j
222 ) const {
223  assert(j < 2);
224 
225  return edges_[edge][j];
226 }
227 
235 template<typename VISITOR>
236 inline std::size_t
238  const std::size_t vertex,
239  const std::size_t j
240 ) const {
241  return vertices_[vertex].to_[j].edge();
242 }
243 
251 template<typename VISITOR>
252 inline std::size_t
254  const std::size_t vertex,
255  const std::size_t j
256 ) const {
257  return vertices_[vertex].from_[j].edge();
258 }
259 
267 template<typename VISITOR>
268 inline std::size_t
270  const std::size_t vertex,
271  const std::size_t j
272 ) const {
273  return vertices_[vertex].to_[j].vertex();
274 }
275 
283 template<typename VISITOR>
284 inline std::size_t
286  const std::size_t vertex,
287  const std::size_t j
288 ) const {
289  return vertices_[vertex].from_[j].vertex();
290 }
291 
298 template<typename VISITOR>
299 inline std::size_t
301  vertices_.push_back(Vertex());
302  visitor_.insertVertex(vertices_.size() - 1);
303  return vertices_.size() - 1;
304 }
305 
313 template<typename VISITOR>
314 inline std::size_t
316  const std::size_t number
317 ) {
318  std::size_t position = vertices_.size();
319  vertices_.insert(vertices_.end(), number, Vertex());
320  visitor_.insertVertices(position, number);
321  return position;
322 }
323 
330 template<typename VISITOR>
331 inline std::size_t
333  const std::size_t vertexIndex0,
334  const std::size_t vertexIndex1
335 ) {
336  assert(vertexIndex0 < numberOfVertices());
337  assert(vertexIndex1 < numberOfVertices());
338 
339  if(multipleEdgesEnabled()) {
340 insertEdgeMark:
341  edges_.push_back(Edge(vertexIndex0, vertexIndex1));
342  std::size_t edgeIndex = edges_.size() - 1;
343  insertAdjacenciesForEdge(edgeIndex);
344  visitor_.insertEdge(edgeIndex);
345  return edgeIndex;
346  }
347  else {
348  std::pair<bool, std::size_t> p = findEdge(vertexIndex0, vertexIndex1);
349  if(p.first) { // edge already exists
350  return p.second;
351  }
352  else {
353  goto insertEdgeMark;
354  }
355  }
356 }
357 
362 template<typename VISITOR>
363 void
365  const std::size_t vertexIndex
366 ) {
367  assert(vertexIndex < numberOfVertices());
368 
369  // erase all edges connected to the vertex
370  while(vertices_[vertexIndex].from_.size() != 0) {
371  eraseEdge(vertices_[vertexIndex].from_.begin()->edge());
372  }
373  while(vertices_[vertexIndex].to_.size() != 0) {
374  eraseEdge(vertices_[vertexIndex].to_.begin()->edge());
375  }
376 
377  if(vertexIndex == numberOfVertices() - 1) { // if the last vertex is to be erased
378  vertices_.pop_back(); // erase vertex
379  visitor_.eraseVertex(vertexIndex);
380  }
381  else { // if a vertex is to be erased which is not the last vertex
382  // move last vertex to the free position:
383 
384  // collect indices of edges affected by the move
385  std::size_t movingVertexIndex = numberOfVertices() - 1;
386  std::set<std::size_t> affectedEdgeIndices;
387  for(Adjacencies::const_iterator it = vertices_[movingVertexIndex].from_.begin();
388  it != vertices_[movingVertexIndex].from_.end(); ++it) {
389  affectedEdgeIndices.insert(it->edge());
390  }
391  for(Adjacencies::const_iterator it = vertices_[movingVertexIndex].to_.begin();
392  it != vertices_[movingVertexIndex].to_.end(); ++it) {
393  affectedEdgeIndices.insert(it->edge());
394  }
395 
396  // for all affected edges:
397  for(std::set<std::size_t>::const_iterator it = affectedEdgeIndices.begin();
398  it != affectedEdgeIndices.end(); ++it) {
399  // remove adjacencies
400  eraseAdjacenciesForEdge(*it);
401 
402  // adapt vertex labels
403  for(std::size_t j=0; j<2; ++j) {
404  if(edges_[*it][j] == movingVertexIndex) {
405  edges_[*it][j] = vertexIndex;
406  }
407  }
408  }
409 
410  // move vertex
411  vertices_[vertexIndex] = vertices_[movingVertexIndex]; // copy
412  vertices_.pop_back(); // erase
413 
414  // insert adjacencies for edges of moved vertex
415  for(std::set<std::size_t>::const_iterator it = affectedEdgeIndices.begin();
416  it != affectedEdgeIndices.end(); ++it) {
417  insertAdjacenciesForEdge(*it);
418  }
419 
420  visitor_.eraseVertex(vertexIndex);
421  visitor_.relabelVertex(movingVertexIndex, vertexIndex);
422  }
423 }
424 
429 template<typename VISITOR>
430 inline void
432  const std::size_t edgeIndex
433 ) {
434  assert(edgeIndex < numberOfEdges());
435 
436  eraseAdjacenciesForEdge(edgeIndex);
437  if(edgeIndex == numberOfEdges() - 1) { // if the last edge is erased
438  edges_.pop_back(); // delete
439  visitor_.eraseEdge(edgeIndex);
440  }
441  else {
442  std::size_t movingEdgeIndex = numberOfEdges() - 1;
443  eraseAdjacenciesForEdge(movingEdgeIndex);
444  edges_[edgeIndex] = edges_[movingEdgeIndex]; // copy
445  edges_.pop_back(); // delete
446  insertAdjacenciesForEdge(edgeIndex);
447  visitor_.eraseEdge(edgeIndex);
448  visitor_.relabelEdge(movingEdgeIndex, edgeIndex);
449  }
450 }
451 
459 template<typename VISITOR>
460 inline typename Digraph<VISITOR>::VertexIterator
462  const std::size_t vertex
463 ) const {
464  return vertices_[vertex].to_.begin();
465 }
466 
474 template<typename VISITOR>
475 inline typename Digraph<VISITOR>::VertexIterator
477  const std::size_t vertex
478 ) const {
479  return vertices_[vertex].to_.end();
480 }
481 
489 template<typename VISITOR>
490 inline typename Digraph<VISITOR>::VertexIterator
492  const std::size_t vertex
493 ) const {
494  return vertices_[vertex].from_.begin();
495 }
496 
504 template<typename VISITOR>
505 inline typename Digraph<VISITOR>::VertexIterator
507  const std::size_t vertex
508 ) const {
509  return vertices_[vertex].from_.end();
510 }
511 
519 template<typename VISITOR>
520 inline typename Digraph<VISITOR>::EdgeIterator
522  const std::size_t vertex
523 ) const {
524  return vertices_[vertex].to_.begin();
525 }
526 
534 template<typename VISITOR>
535 inline typename Digraph<VISITOR>::EdgeIterator
537  const std::size_t vertex
538 ) const {
539  return vertices_[vertex].to_.end();
540 }
541 
549 template<typename VISITOR>
550 inline typename Digraph<VISITOR>::EdgeIterator
552  const std::size_t vertex
553 ) const {
554  return vertices_[vertex].from_.begin();
555 }
556 
564 template<typename VISITOR>
565 inline typename Digraph<VISITOR>::EdgeIterator
567  const std::size_t vertex
568 ) const {
569  return vertices_[vertex].from_.end();
570 }
571 
579 template<typename VISITOR>
582  const std::size_t vertex
583 ) const {
584  return vertices_[vertex].to_.begin();
585 }
586 
594 template<typename VISITOR>
597  const std::size_t vertex
598 ) const {
599  return vertices_[vertex].to_.end();
600 }
601 
609 template<typename VISITOR>
612  const std::size_t vertex
613 ) const {
614  return vertices_[vertex].from_.begin();
615 }
616 
624 template<typename VISITOR>
627  const std::size_t vertex
628 ) const {
629  return vertices_[vertex].from_.end();
630 }
631 
636 template<typename VISITOR>
637 inline void
639  const std::size_t number
640 ) {
641  vertices_.reserve(number);
642 }
643 
648 template<typename VISITOR>
649 inline void
651  const std::size_t number
652 ) {
653  edges_.reserve(number);
654 }
655 
661 template<typename VISITOR>
662 inline const typename Digraph<VISITOR>::AdjacencyType&
664  const std::size_t vertex,
665  const std::size_t j
666 ) const {
667  return vertices_[vertex].to_[j];
668 }
669 
675 template<typename VISITOR>
676 inline const typename Digraph<VISITOR>::AdjacencyType&
678  const std::size_t vertex,
679  const std::size_t j
680 ) const {
681  return vertices_[vertex].from_[j];
682 }
683 
692 template<typename VISITOR>
693 inline std::pair<bool, std::size_t>
695  const std::size_t vertex0,
696  const std::size_t vertex1
697 ) const {
698  assert(vertex0 < numberOfVertices());
699  assert(vertex1 < numberOfVertices());
700 
701  VertexIterator it = std::lower_bound(
702  verticesFromVertexBegin(vertex0),
703  verticesFromVertexEnd(vertex0),
704  vertex1
705  ); // binary search
706  if(it != verticesFromVertexEnd(vertex0) && *it == vertex1) {
707  // access the corresponding edge in constant time
708  const std::size_t j = std::distance(verticesFromVertexBegin(vertex0), it);
709  return std::make_pair(true, edgeFromVertex(vertex0, j));
710  }
711  else {
712  return std::make_pair(false, 0);
713  }
714 }
715 
720 template<typename VISITOR>
721 inline bool
723  return multipleEdgesEnabled_;
724 }
725 
732 template<typename VISITOR>
733 inline bool&
735  return multipleEdgesEnabled_;
736 }
737 
738 template<typename VISITOR>
739 inline void
741  const std::size_t edgeIndex
742 ) {
743  const Edge& edge = edges_[edgeIndex];
744  const std::size_t vertexIndex0 = edge[0];
745  const std::size_t vertexIndex1 = edge[1];
746  vertices_[vertexIndex0].to_.insert(
747  AdjacencyType(vertexIndex1, edgeIndex)
748  );
749  vertices_[vertexIndex1].from_.insert(
750  AdjacencyType(vertexIndex0, edgeIndex)
751  );
752 }
753 
754 template<typename VISITOR>
755 inline void
756 Digraph<VISITOR>::eraseAdjacenciesForEdge(
757  const std::size_t edgeIndex
758 ) {
759  const Edge& edge = edges_[edgeIndex];
760  const std::size_t vertexIndex0 = edge[0];
761  const std::size_t vertexIndex1 = edge[1];
762  Vertex& vertex0 = vertices_[vertexIndex0];
763  Vertex& vertex1 = vertices_[vertexIndex1];
764 
765  AdjacencyType adj(vertexIndex1, edgeIndex);
766  RandomAccessSet<AdjacencyType>::iterator it = vertex0.to_.find(adj);
767  assert(it != vertex0.to_.end());
768  vertex0.to_.erase(it);
769 
770  adj.vertex() = vertexIndex0;
771  it = vertex1.from_.find(adj);
772  assert(it != vertex1.from_.end());
773  vertex1.from_.erase(it);
774 }
775 
776 } // namespace graph
777 } // namespace andres
778 
779 #endif // #ifndef ANDRES_GRAPH_DIGRAPH_HXX