1 /** \file
2 * \brief Pure declaration header, find template implementation in
3 * Graph.h
4 *
5 * Declaration of NodeElement, EdgeElement, and Graph classes.
6 *
7 * \author Carsten Gutwenger
8 *
9 * \par License:
10 * This file is part of the Open Graph Drawing Framework (OGDF).
11 *
12 * \par
13 * Copyright (C)<br>
14 * See README.md in the OGDF root directory for details.
15 *
16 * \par
17 * This program is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU General Public License
19 * Version 2 or 3 as published by the Free Software Foundation;
20 * see the file LICENSE.txt included in the packaging of this file
21 * for details.
22 *
23 * \par
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * \par
30 * You should have received a copy of the GNU General Public
31 * License along with this program; if not, see
32 * http://www.gnu.org/copyleft/gpl.html
33 */
34
35 #pragma once
36
37 #include <ogdf/basic/GraphList.h>
38 #include <ogdf/basic/internal/graph_iterators.h>
39 #include <array>
40 #include <mutex>
41
42 #ifdef OGDF_DEBUG
43 # include <set>
44 #endif
45
46 namespace ogdf {
47
48 //
49 // in embedded graphs, adjacency lists are given in clockwise order.
50 //
51
52
53 class OGDF_EXPORT Graph;
54 class OGDF_EXPORT NodeElement;
55 class OGDF_EXPORT EdgeElement;
56 class OGDF_EXPORT AdjElement;
57 class OGDF_EXPORT FaceElement;
58 class OGDF_EXPORT ClusterElement;
59
60
61 //! The type of nodes.
62 //! @ingroup graphs
63 using node = NodeElement*;
64
65 //! The type of edges.
66 //! @ingroup graphs
67 using edge = EdgeElement*;
68
69 //! The type of adjacency entries.
70 //! @ingroup graphs
71 using adjEntry = AdjElement*;
72
73
74 //! Class for adjacency list elements.
75 /**
76 * Adjacency list elements represent the occurrence of an edges in
77 * the adjacency list of a node.
78 */
79 class OGDF_EXPORT AdjElement : private internal::GraphElement {
80 friend class Graph;
81 friend class internal::GraphListBase;
82 friend class internal::GraphList<AdjElement>;
83
84 AdjElement *m_twin; //!< The corresponding adjacency entry (same edge)
85 edge m_edge; //!< The associated edge.
86 node m_node; //!< The node whose adjacency list contains this entry.
87 int m_id; //!< The (unique) index of the adjacency entry.
88
89 //! Constructs an adjacency element for a given node.
AdjElement(node v)90 explicit AdjElement(node v) : m_node(v) { }
91 //! Constructs an adjacency entry for a given edge and index.
AdjElement(edge e,int id)92 AdjElement(edge e, int id) : m_edge(e), m_id(id) { }
93
94 public:
95 //! Returns the edge associated with this adjacency entry.
theEdge()96 edge theEdge() const { return m_edge; }
97 //! Conversion to edge.
edge()98 operator edge() const { return m_edge; }
99 //! Returns the node whose adjacency list contains this element.
theNode()100 node theNode() const { return m_node; }
101 //! Casts to the node whose adjacency list contains this element.
node()102 operator node() const { return m_node; }
103
104 //! Returns the corresponding adjacency element associated with the same edge.
twin()105 adjEntry twin() const { return m_twin; }
106
107 //! Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
twinNode()108 node twinNode() const { return m_twin->m_node; }
109
110 //! Returns the index of this adjacency element.
index()111 int index() const { return m_id; }
112
113 //! Returns \c true iff this is the source adjacency entry of the corresponding edge.
114 bool isSource() const;
115
116 /**
117 * Returns whether this adjacency entry lies between \c adjBefore and \c adjAfter
118 * in clockwise rotation.
119 *
120 * Note that this operation takes time linear in the degree of the node.
121 *
122 * @param adjBefore First adjacency entry. Must be at the same node as this.
123 * @param adjAfter Last adjacency entry. Must be at the same node as this.
124 * @return \c true iff this adjacency entry is in between
125 */
126 bool isBetween(adjEntry adjBefore, adjEntry adjAfter) const;
127
128 // traversing faces in clockwise (resp. counter-clockwise) order
129 // (if face is an interior face)
130
131 //! Returns the clockwise successor in face. Use faceCycleSucc instead!
clockwiseFaceSucc()132 adjEntry clockwiseFaceSucc() const { return m_twin->cyclicPred(); }
133 //! Returns the clockwise predecessor in face. Use faceCycleSucc instead!
clockwiseFacePred()134 adjEntry clockwiseFacePred() const { return cyclicSucc()->m_twin; }
135 //! Returns the counter-clockwise successor in face.
counterClockwiseFaceSucc()136 adjEntry counterClockwiseFaceSucc() const { return m_twin->cyclicSucc(); }
137 //! Returns the counter-clockwise predecessor in face.
counterClockwiseFacePred()138 adjEntry counterClockwiseFacePred() const { return cyclicPred()->m_twin; }
139
140 // default is traversing faces in clockwise order
141 //! Returns the cyclic successor in face.
faceCycleSucc()142 adjEntry faceCycleSucc() const { return clockwiseFaceSucc(); }
143 //! Returns the cyclic predecessor in face.
faceCyclePred()144 adjEntry faceCyclePred() const { return clockwiseFacePred(); }
145
146
147 //! Returns the successor in the adjacency list.
succ()148 adjEntry succ() const { return static_cast<adjEntry>(m_next); }
149 //! Returns the predecessor in the adjacency list.
pred()150 adjEntry pred() const { return static_cast<adjEntry>(m_prev); }
151
152 //! Returns the cyclic successor in the adjacency list.
153 adjEntry cyclicSucc() const;
154 //! Returns the cyclic predecessor in the adjacency list.
155 adjEntry cyclicPred() const;
156
157 #ifdef OGDF_DEBUG
158 const Graph *graphOf() const;
159 #endif
160
161 //! Standard Comparer
compare(const AdjElement & x,const AdjElement & y)162 static int compare(const AdjElement& x,const AdjElement& y) { return x.m_id-y.m_id; }
163 OGDF_AUGMENT_STATICCOMPARER(AdjElement)
164
165 OGDF_NEW_DELETE
166 };
167
168 //! Class for the representation of nodes.
169 class OGDF_EXPORT NodeElement : private internal::GraphElement {
170 friend class Graph;
171 friend class internal::GraphList<NodeElement>;
172
173 //GraphList<AdjElement> m_adjEdges; //!< The adjacency list of the node.
174 int m_indeg; //!< The indegree of the node.
175 int m_outdeg; //!< The outdegree of the node.
176 int m_id; //!< The (unique) index of the node.
177
178 #ifdef OGDF_DEBUG
179 // we store the graph containing this node for debugging purposes
180 const Graph *m_pGraph; //!< The graph containg this node (debug only).
181 #endif
182
183
184 //! Constructs a node element with index \p id.
185 #ifdef OGDF_DEBUG
186 /**
187 * \remarks The parameter \p pGraph is only passed in a debug build.
188 * It is used, e.g., by NodeArray for checking if a node belongs to
189 * the correct graph.
190 */
NodeElement(const Graph * pGraph,int id)191 NodeElement(const Graph *pGraph, int id) :
192 m_indeg(0), m_outdeg(0), m_id(id), m_pGraph(pGraph) { }
193 #else
NodeElement(int id)194 NodeElement(int id) : m_indeg(0), m_outdeg(0), m_id(id) { }
195 #endif
196
197
198 public:
199 //! The container containing all entries in the adjacency list of this node.
200 internal::GraphObjectContainer<AdjElement> adjEntries;
201
202 //! Returns the (unique) node index.
index()203 int index() const { return m_id; }
204
205 //! Returns the indegree of the node.
indeg()206 int indeg() const { return m_indeg; }
207 //! Returns the outdegree of the node.
outdeg()208 int outdeg() const { return m_outdeg; }
209 //! Returns the degree of the node (indegree + outdegree).
degree()210 int degree() const { return m_indeg + m_outdeg; }
211
212 //! Returns the first entry in the adjaceny list.
firstAdj()213 adjEntry firstAdj() const { return adjEntries.head(); }
214 //! Returns the last entry in the adjacency list.
lastAdj()215 adjEntry lastAdj () const { return adjEntries.tail(); }
216
217 //! Returns the successor in the list of all nodes.
succ()218 node succ() const { return static_cast<node>(m_next); }
219 //! Returns the predecessor in the list of all nodes.
pred()220 node pred() const { return static_cast<node>(m_prev); }
221
222 //! Returns a list with all adjacency entries of this node.
223 /**
224 * @tparam ADJLIST is the type of adjacency entry list, which is returned.
225 * @param adjList is assigned the list of all adjacency entries of this node.
226 */
227 template<class ADJLIST>
allAdjEntries(ADJLIST & adjList)228 void allAdjEntries(ADJLIST &adjList) const {
229 adjList.clear();
230 for(adjEntry adj : this->adjEntries) {
231 adjList.pushBack(adj);
232 }
233 }
234
235 //! Returns a list with all edges incident to this node.
236 /**
237 * Note that each self-loop of this node is contained twice in the list.
238 *
239 * @tparam EDGELIST is the type of edge list, which is returned.
240 * @param edgeList is assigned the list of all edges incident to this node
241 * (including incoming and outcoming edges).
242 */
243 template<class EDGELIST>
adjEdges(EDGELIST & edgeList)244 void adjEdges(EDGELIST &edgeList) const {
245 edgeList.clear();
246 for(adjEntry adj : this->adjEntries) {
247 edgeList.pushBack(adj->theEdge());
248 }
249 }
250
251 //! Returns a list with all incoming edges of this node.
252 /**
253 * @tparam EDGELIST is the type of edge list, which is returned.
254 * @param edgeList is assigned the list of all incoming edges incident to this node.
255 */
256 template<class EDGELIST>
257 void inEdges(EDGELIST &edgeList) const;
258
259 //! Returns a list with all outgoing edges of this node.
260 /**
261 * @tparam EDGELIST is the type of edge list, which is returned.
262 * @param edgeList is assigned the list of all outgoing edges incident to this node.
263 */
264 template<class EDGELIST>
265 void outEdges(EDGELIST &edgeList) const;
266
267 #ifdef OGDF_DEBUG
268 //! Returns the graph containing this node (debug only).
graphOf()269 const Graph *graphOf() const { return m_pGraph; }
270 #endif
271
272 //! Standard Comparer
compare(const NodeElement & x,const NodeElement & y)273 static int compare(const NodeElement& x,const NodeElement& y) { return x.m_id-y.m_id; }
274 OGDF_AUGMENT_STATICCOMPARER(NodeElement)
275
276 OGDF_NEW_DELETE
277 };
278
cyclicSucc()279 inline adjEntry AdjElement::cyclicSucc() const
280 {
281 return (m_next) ? static_cast<adjEntry>(m_next) : m_node->firstAdj();
282 }
283
cyclicPred()284 inline adjEntry AdjElement::cyclicPred() const
285 {
286 return (m_prev) ? static_cast<adjEntry>(m_prev) : m_node->lastAdj();
287 }
288
289
290
291 //! Class for the representation of edges.
292 class OGDF_EXPORT EdgeElement : private internal::GraphElement {
293 friend class Graph;
294 friend class internal::GraphList<EdgeElement>;
295
296 node m_src; //!< The source node of the edge.
297 node m_tgt; //!< The target node of the edge.
298 AdjElement *m_adjSrc; //!< Corresponding adjacancy entry at source node.
299 AdjElement *m_adjTgt; //!< Corresponding adjacancy entry at target node.
300 int m_id; // The (unique) index of the node.
301
302 //! Constructs an edge element (\p src,\p tgt).
303 /**
304 * @param src is the source node of the edge.
305 * @param tgt is the target node of the edge.
306 * @param adjSrc is the corresponding adjacency entry at source node.
307 * @param adjTgt is the corresponding adjacency entry at target node.
308 * @param id is the index of the edge.
309 */
EdgeElement(node src,node tgt,AdjElement * adjSrc,AdjElement * adjTgt,int id)310 EdgeElement(node src, node tgt, AdjElement *adjSrc, AdjElement *adjTgt, int id) :
311 m_src(src), m_tgt(tgt), m_adjSrc(adjSrc), m_adjTgt(adjTgt), m_id(id) { }
312
313 //! Constructs an edge element (\p src,\p tgt).
314 /**
315 * @param src is the source node of the edge.
316 * @param tgt is the target node of the edge.
317 * @param id is the index of the edge.
318 */
EdgeElement(node src,node tgt,int id)319 EdgeElement(node src, node tgt, int id) :
320 m_src(src), m_tgt(tgt), m_id(id) { }
321
322 public:
323 //! Returns the index of the edge.
index()324 int index() const { return m_id; }
325 //! Returns the source node of the edge.
source()326 node source() const { return m_src; }
327 //! Returns the target node of the edge.
target()328 node target() const { return m_tgt; }
329 //! Returns a list of adjacent nodes. If this edge is a self-loop, both entries will be the same node.
nodes()330 std::array<node, 2> nodes() const { return std::array<node, 2>{{m_src, m_tgt}}; }
331
332 //! Returns the corresponding adjacancy entry at source node.
adjSource()333 adjEntry adjSource() const { return m_adjSrc; }
334 //! Returns the corresponding adjacancy entry at target node.
adjTarget()335 adjEntry adjTarget() const { return m_adjTgt; }
336
337 //! Returns the adjacent node different from \p v.
opposite(node v)338 node opposite(node v) const { return (v == m_src) ? m_tgt : m_src; }
339
340 //! Returns true iff the edge is a self-loop (source node = target node).
isSelfLoop()341 bool isSelfLoop() const { return m_src == m_tgt; }
342
343 //! Returns true iff edge \p e is an inverted edge to this (directed) edge
isInvertedDirected(edge e)344 bool isInvertedDirected(edge e) const { return m_src == e->target() && m_tgt == e->source(); }
345
346 //! Returns true iff edge \p e is parallel to this (directed) edge (or if it is the same edge)
isParallelDirected(edge e)347 bool isParallelDirected(edge e) const { return m_src == e->source() && m_tgt == e->target(); }
348
349 //! Returns true iff edge \p e is parallel to this (undirected) edge (or if it is the same edge)
isParallelUndirected(edge e)350 bool isParallelUndirected(edge e) const { return isParallelDirected(e) || isInvertedDirected(e); }
351
352 //! Returns the successor in the list of all edges.
succ()353 edge succ() const { return static_cast<edge>(m_next); }
354 //! Returns the predecessor in the list of all edges.
pred()355 edge pred() const { return static_cast<edge>(m_prev); }
356
357 #ifdef OGDF_DEBUG
358 //! Returns the graph containing this node (debug only).
graphOf()359 const Graph *graphOf() const { return m_src->graphOf(); }
360 #endif
361
362 //! Returns true iff \p v is incident to the edge.
isIncident(node v)363 bool isIncident(node v) const { return v == m_src || v == m_tgt; }
364
365 //! Returns true iff \p e is adjacent to the edge.
isAdjacent(edge e)366 bool isAdjacent(edge e) const { return isIncident(e->m_src) || isIncident(e->m_tgt); }
367
368 //! Returns the common node of the edge and \p e. Returns nullptr if the two edges are not adjacent.
commonNode(edge e)369 node commonNode(edge e) const { return (m_src==e->m_src || m_src==e->m_tgt) ? m_src : ((m_tgt==e->m_src || m_tgt==e->m_tgt) ? m_tgt: nullptr); }
370
371 //! Returns an adjacency entry of this edge at node \c v.
372 //! If this is a self-loop the source adjacency entry will always be returned.
getAdj(node v)373 adjEntry getAdj(node v) const {
374 OGDF_ASSERT(this->isIncident(v));
375 return v == m_src ? m_adjSrc : m_adjTgt;
376 }
377
378 //! Standard Comparer
compare(const EdgeElement & x,const EdgeElement & y)379 static int compare(const EdgeElement& x,const EdgeElement& y) { return x.m_id-y.m_id; }
380 OGDF_AUGMENT_STATICCOMPARER(EdgeElement)
381
382 OGDF_NEW_DELETE
383
384 #ifdef OGDF_DEBUG
385 private:
386 bool m_hidden = false;
387 #endif
388 };
389
390 #ifdef OGDF_DEBUG
graphOf()391 inline const Graph *AdjElement::graphOf() const {
392 return m_node->graphOf();
393 }
394 #endif
395
isSource()396 inline bool AdjElement::isSource() const {
397 return this == m_edge->adjSource();
398 }
399
isBetween(adjEntry adjBefore,adjEntry adjAfter)400 inline bool AdjElement::isBetween(adjEntry adjBefore, adjEntry adjAfter) const {
401 #ifdef OGDF_DEBUG
402 node v = this->theNode();
403 OGDF_ASSERT(adjBefore->theNode() == v);
404 OGDF_ASSERT(adjAfter->theNode() == v);
405 #endif
406 bool result = this != adjBefore && this != adjAfter && adjBefore != adjAfter;
407
408 if (result) {
409 adjEntry adj = adjBefore;
410 for (; adj != this && adj != adjAfter; adj = adj->cyclicSucc());
411 result = adj == this;
412 }
413
414 return result;
415 }
416
417 template<class EDGELIST>
inEdges(EDGELIST & edgeList)418 void NodeElement::inEdges(EDGELIST &edgeList) const {
419 edgeList.clear();
420 for(adjEntry adj : this->adjEntries) {
421 edge e = adj->theEdge();
422 if (adj == e->adjTarget()) edgeList.pushBack(e);
423 }
424 }
425
426 template<class EDGELIST>
outEdges(EDGELIST & edgeList)427 void NodeElement::outEdges(EDGELIST &edgeList) const {
428 edgeList.clear();
429 for(adjEntry adj : this->adjEntries) {
430 edge e = adj->theEdge();
431 if (adj == e->adjSource()) edgeList.pushBack(e);
432 }
433 }
434
435 class NodeArrayBase;
436 class EdgeArrayBase;
437 class AdjEntryArrayBase;
438 template<class T> class NodeArray;
439 template<class T> class EdgeArray;
440 template<class T> class AdjEntryArray;
441 class OGDF_EXPORT GraphObserver;
442
443 namespace internal {
444 template<typename CONTAINER> inline void getAllNodes(const Graph& G, CONTAINER& nodes);
445 template<typename CONTAINER> inline void getAllEdges(const Graph& G, CONTAINER& edges);
446 }
447
448 //! Data type for general directed graphs (adjacency list representation).
449 /**
450 * @ingroup graphs
451 *
452 * <H3>Thread Safety</H3>
453 * The class Graph allows shared access of threads to const methods only.
454 * If one thread executes a non-const method, shared access is no longer thread-safe.
455 *
456 * <H3>Iteration</H3>
457 * You may iterate over the nodes and edges of a graph using C++11 range-based for loops.
458 * Find some examples below.
459 *
460 * <ul>
461 * <li>Iterate over all nodes \a v of graph \a G using c++11 syntax :
462 * \code
463 * for(node v : G.nodes) {
464 * // do stuff with node v
465 * }
466 * \endcode
467 *
468 * <li>Iterate over all nodes \a v of graph \a G :
469 * \code
470 * for(node v = G.firstNode(); v != nullptr; v = v->succ()) {
471 * // do stuff with node v
472 * }
473 * \endcode
474 *
475 * <li>Iterate over all edges \a e of graph \a G using c++11 syntax :
476 * \code
477 * for(edge e : G.edges) {
478 * // do stuff with node v
479 * }
480 * \endcode
481 *
482 * <li>Iterate over all incident edges of node \a v using c++11 syntax:
483 * \code
484 * for(adjEntry adj : v->adjEntries) {
485 * edge e = adj->theEdge();
486 * // do stuff with edge e
487 * }
488 * \endcode
489 * </ul>
490 */
491
492 class OGDF_EXPORT Graph
493 {
494 public:
495 class HiddenEdgeSet;
496 private:
497 int m_nodeIdCount; //!< The Index that will be assigned to the next created node.
498 int m_edgeIdCount; //!< The Index that will be assigned to the next created edge.
499
500 int m_nodeArrayTableSize; //!< The current table size of node arrays associated with this graph.
501 int m_edgeArrayTableSize; //!< The current table size of edge arrays associated with this graph.
502
503 mutable ListPure<NodeArrayBase*> m_regNodeArrays; //!< The registered node arrays.
504 mutable ListPure<EdgeArrayBase*> m_regEdgeArrays; //!< The registered edge arrays.
505 mutable ListPure<AdjEntryArrayBase*> m_regAdjArrays; //!< The registered adjEntry arrays.
506 mutable ListPure<GraphObserver*> m_regStructures; //!< The registered graph structures.
507
508 #ifndef OGDF_MEMORY_POOL_NTS
509 mutable std::mutex m_mutexRegArrays; //!< The critical section for protecting shared acces to register/unregister methods.
510 #endif
511
512 List<HiddenEdgeSet*> m_hiddenEdgeSets; //!< The list of hidden edges.
513
514 public:
515
516 /**
517 * @name Iterators
518 * These types are used for graph object iterators, which are returned by graph object containers
519 * like nodes and edges.
520 */
521 //@{
522
523 //! Provides a bidirectional iterator to a node in a graph.
524 using node_iterator = internal::GraphIterator<node>;
525 //! Provides a bidirectional iterator to an edge in a graph.
526 using edge_iterator = internal::GraphIterator<edge>;
527 //! Provides a bidirectional iterator to an entry in an adjacency list.
528 using adjEntry_iterator = internal::GraphIterator<adjEntry>;
529
530 //@}
531 /**
532 * @name Enumerations
533 * These enumerations are mainly meant for advanced or internal usage scenarios.
534 */
535 //@{
536
537 //! The type of edges (only used in derived classes).
538 enum class EdgeType {
539 association = 0,
540 generalization = 1,
541 dependency = 2
542 };
543
544 //! The type of nodes.
545 enum class NodeType {
546 vertex = 0,
547 dummy = 1,
548 generalizationMerger = 2,
549 generalizationExpander = 3,
550 highDegreeExpander = 4,
551 lowDegreeExpander = 5,
552 associationClass = 6
553 };
554
555 //@}
556
557
558 /**
559 * @name Graph object containers
560 * These containers maintain the nodes and edges of the graph, and provide node and edge iterators.
561 */
562 //@{
563
564 //! The container containing all node objects.
565 internal::GraphObjectContainer<NodeElement> nodes;
566
567 //! The container containing all edge objects.
568 internal::GraphObjectContainer<EdgeElement> edges;
569
570 //@}
571
572
573 //! Constructs an empty graph.
574 Graph();
575
576 //! Constructs a graph that is a copy of \p G.
577 /**
578 * The constructor assures that the adjacency lists of nodes in the
579 * constructed graph are in the same order as the adjacency lists in \p G.
580 * This is in particular important when dealing with embedded graphs.
581 *
582 * @param G is the graph that will be copied.
583 */
584 Graph(const Graph &G);
585
586 //! Destructor.
587 virtual ~Graph();
588
589 /**
590 * @name Access methods
591 */
592 //@{
593
594 //! Returns true iff the graph is empty, i.e., contains no nodes.
empty()595 bool empty() const { return nodes.empty(); }
596
597 //! Returns the number of nodes in the graph.
numberOfNodes()598 int numberOfNodes() const { return nodes.size(); }
599
600 //! Returns the number of edges in the graph.
numberOfEdges()601 int numberOfEdges() const { return edges.size(); }
602
603 //! Returns the largest used node index.
maxNodeIndex()604 int maxNodeIndex() const { return m_nodeIdCount-1; }
605 //! Returns the largest used edge index.
maxEdgeIndex()606 int maxEdgeIndex() const { return m_edgeIdCount-1; }
607 //! Returns the largest used adjEntry index.
maxAdjEntryIndex()608 int maxAdjEntryIndex() const { return (m_edgeIdCount<<1)-1; }
609
610 //! Returns the table size of node arrays associated with this graph.
nodeArrayTableSize()611 int nodeArrayTableSize() const { return m_nodeArrayTableSize; }
612 //! Returns the table size of edge arrays associated with this graph.
edgeArrayTableSize()613 int edgeArrayTableSize() const { return m_edgeArrayTableSize; }
614 //! Returns the table size of adjEntry arrays associated with this graph.
adjEntryArrayTableSize()615 int adjEntryArrayTableSize() const { return m_edgeArrayTableSize << 1; }
616
617 //! Returns the first node in the list of all nodes.
firstNode()618 node firstNode() const { return nodes.head(); }
619 //! Returns the last node in the list of all nodes.
lastNode()620 node lastNode () const { return nodes.tail(); }
621
622 //! Returns the first edge in the list of all edges.
firstEdge()623 edge firstEdge() const { return edges.head(); }
624 //! Returns the last edge in the list of all edges.
lastEdge()625 edge lastEdge () const { return edges.tail(); }
626
627 /**
628 * Returns a random node.
629 *
630 * \c nullptr is returned if no feasible node exists.
631 *
632 * @see chooseIteratorFrom
633 */
634 node chooseNode(std::function<bool(node)> includeNode = [](node) { return true; }, bool isFastTest = true) const;
635
636 /**
637 * Returns a random edge.
638 *
639 * \c nullptr is returned if no feasible edge exists.
640 *
641 * @see chooseIteratorFrom
642 */
643 edge chooseEdge(std::function<bool(edge)> includeEdge = [](edge) { return true; }, bool isFastTest = true) const;
644
645 //! Returns a container with all nodes of the graph.
646 /**
647 * @tparam CONTAINER is the type of node container which is returned.
648 * @param nodeContainer is assigned the container of all nodes.
649 */
650 template<class CONTAINER>
allNodes(CONTAINER & nodeContainer)651 void allNodes(CONTAINER& nodeContainer) const {
652 internal::getAllNodes<CONTAINER>(*this, nodeContainer);
653 }
654
655 //! Returns a container with all edges of the graph.
656 /**
657 * @tparam CONTAINER is the type of the edge container which is returned.
658 * @param edgeContainer is assigned the list of all edges.
659 */
660 template<class CONTAINER>
allEdges(CONTAINER & edgeContainer)661 void allEdges(CONTAINER &edgeContainer) const {
662 internal::getAllEdges<CONTAINER>(*this, edgeContainer);
663 }
664
665 //@}
666 /**
667 * @name Creation of new nodes and edges
668 */
669 //@{
670
671 //! Creates a new node and returns it.
672 node newNode();
673
674 //! Creates a new node with predefined index and returns it.
675 /**
676 * \pre \p index is currently not the index of any other node in the graph.
677 *
678 * \attention Passing a node index that is already in use results in an inconsistent
679 * data structure. Only use this method if you know what you're doing!
680 *
681 * @param index is the index that will be assigned to the newly created node.
682 * @return the newly created node.
683 */
684 node newNode(int index);
685
686 //! Creates a new edge (\p v,\p w) and returns it.
687 /**
688 * @param v is the source node of the newly created edge.
689 * @param w is the target node of the newly created edge.
690 * @return the newly created edge.
691 */
692 edge newEdge(node v, node w);
693
694 //! Creates a new edge (\p v,\p w) with predefined index and returns it.
695 /**
696 * \pre \p index is currently not the index of any other edge in the graph.
697 *
698 * \attention Passing an edge index that is already in use results in an inconsistent
699 * data structure. Only use this method if you know what you're doing!
700 *
701 * @param v is the source node of the newly created edge.
702 * @param w is the target node of the newly created edge.
703 * @param index is the index that will be assigned to the newly created edge.
704 * @return the newly created edge.
705 */
706 edge newEdge(node v, node w, int index);
707
708 //! Creates a new edge at predefined positions in the adjacency lists.
709 /**
710 * Let \a v be the node whose adjacency list contains \p adjSrc,
711 * and \a w the node whose adjacency list contains \p adjTgt. Then,
712 * the created edge is (\a v,\a w).
713 *
714 * @param adjSrc is the adjacency entry after which the new edge is inserted
715 * in the adjacency list of \a v.
716 * @param adjTgt is the adjacency entry after which the new edge is inserted
717 * in the adjacency list of \a w.
718 * @param dir specifies if the edge is inserted before or after the given
719 * adjacency entries.
720 * @return the newly created edge.
721 */
722 edge newEdge(adjEntry adjSrc, adjEntry adjTgt, Direction dir = Direction::after);
723
724 //! Creates a new edge at predefined positions in the adjacency lists.
725 /**
726 * Let \a w be the node whose adjacency list contains \p adjTgt. Then,
727 * the created edge is (\p v,\a w).
728 *
729 * @param v is the source node of the new edge; the edge is added at the end
730 * of the adjacency list of \p v.
731 * @param adjTgt is the adjacency entry after which the new edge is inserted
732 * in the adjacency list of \a w.
733 * @return the newly created edge.
734 */
735 edge newEdge(node v, adjEntry adjTgt);
736
737 //! Creates a new edge at predefined positions in the adjacency lists.
738 /**
739 * Let \a v be the node whose adjacency list contains \p adjSrc. Then,
740 * the created edge is (\a v,\p w).
741 *
742 * @param adjSrc is the adjacency entry after which the new edge is inserted
743 * in the adjacency list of \a v.
744 * @param w is the source node of the new edge; the edge is added at the end
745 * of the adjacency list of \p w.
746 * @return the newly created edge.
747 */
748 edge newEdge(adjEntry adjSrc, node w);
749
750
751 //@}
752 /**
753 * @name Removing nodes and edges
754 */
755 //@{
756
757 //! Removes node \p v and all incident edges from the graph.
758 virtual void delNode(node v);
759
760 //! Removes edge \p e from the graph.
761 virtual void delEdge(edge e);
762
763 //! Removes all nodes and all edges from the graph.
764 virtual void clear();
765
766 //@}
767
768 /**
769 * @brief Functionality for temporarily hiding edges in constant time.
770 *
771 * Hidden edges are removed from the
772 * list of all edges and their corresponding adjacency entries from the repsective
773 * adjacency lists, but the edge objects themselves are not destroyed. Hidden edges
774 * can later be reactivated using #restore(). Restoring edges will not preserve the adjacency order.
775 *
776 * Hiding or restoring an edge takes constant time.
777 * Thus, hiding edges may be more performant than creating a ogdf::GraphCopy and modifying it.
778 *
779 * Hidden edge sets can be restored as a whole. Alternatively a single edge of a such a set can be restored.
780 *
781 * Note that all hidden edges are restored when the set of hidden edges is destroyed.
782
783 * Do not delete any nodes incident to hidden edges.
784 * Do not hide edges while iterating over the edges of a ogdf::Graph.
785 * Instead, iterate over a copied list of all edges.
786 */
787 class OGDF_EXPORT HiddenEdgeSet
788 {
789 friend class Graph;
790 friend class EdgeElement;
791
792 public:
793 /**
794 * Creates a new set of hidden edges.
795 *
796 * @param graph the graph to be modified
797 */
HiddenEdgeSet(Graph & graph)798 explicit HiddenEdgeSet(Graph &graph) : m_graph(&graph)
799 {
800 m_it = m_graph->m_hiddenEdgeSets.pushFront(this);
801 }
802
803 /**
804 * Restores all hidden edges.
805 */
~HiddenEdgeSet()806 ~HiddenEdgeSet()
807 {
808 if (m_graph) {
809 restore();
810 m_graph->m_hiddenEdgeSets.del(m_it);
811 }
812 }
813
814 /**
815 * Hides the given edge.
816 *
817 * \pre the edge is currently not hidden.
818 * \pre the graph associated with this set does still exist.
819 */
820 void hide(edge e);
821
822 /**
823 * Reveals the given edge.
824 *
825 * \pre the edge is currently hidden using this set.
826 * \pre the graph associated with this set does still exist.
827 */
828 void restore(edge e);
829
830 /**
831 * Restores all edges contained in this set.
832 * The set will remain valid.
833 *
834 * \pre the graph associated with this set does still exist.
835 */
836 void restore();
837
838 /**
839 * Returns the number of edges contained in this set.
840 */
841 int size();
842
843 private:
844 internal::GraphList<EdgeElement> m_edges;
845 ListIterator<HiddenEdgeSet*> m_it;
846 Graph *m_graph;
847
848 // prevent copying
849 HiddenEdgeSet(const HiddenEdgeSet&);
850 HiddenEdgeSet& operator=(const HiddenEdgeSet&);
851 };
852
853 /**
854 * @name Advanced modification methods
855 */
856 //@{
857
858 /**
859 * @copydoc ogdf::Graph::insert(const Graph&)
860 * @param nodeMap is assigned a mapping from nodes in \p G to nodes in this Graph.
861 */
862 void insert(const Graph &G, NodeArray<node> &nodeMap);
863
864 //! Inserts Graph \p G as a subgraph into this Graph.
865 /**
866 * @param G is the Graph to be inserted into this Graph.
867 */
868 void insert(const Graph &G);
869
870 //! Splits edge \p e into two edges introducing a new node.
871 /**
872 * Let \p e=(\a v,\a w). Then, the resulting two edges are \a e=(\a v,\a u)
873 * and \a e'=(\a u,\a w), where \a u is a new node.
874 *
875 * \note The edge \p e is modified by this operation.
876 *
877 * @param e is the edge to be split.
878 * @return The edge \a e'.
879 */
880 virtual edge split(edge e);
881
882 //! Undoes a split operation.
883 /**
884 * Removes node \p u by joining the two edges adjacent to \p u. The
885 * outgoing edge of \p u is removed and the incoming edge \a e is reused
886 *
887 * \pre \p u has exactly one incoming and one outgoing edge, and
888 * none of them is a self-loop.
889 *
890 * @param u is the node to be unsplit.
891 * @return The edge \a e.
892 */
893 void unsplit(node u);
894
895 //! Undoes a split operation.
896 /**
897 * For two edges \p eIn = (\a x,\a u) and \p eOut = (\a u,\a y), removes
898 * node \a u by joining \p eIn and \p eOut. Edge \p eOut is removed and
899 * \p eIn is reused.
900 *
901 * \pre \p eIn and \p eOut are the only edges incident with \a u and
902 * none of them is a self-loop.
903 *
904 * @param eIn is the (only) incoming edge of \a u.
905 * @param eOut is the (only) outgoing edge of \a u.
906 */
907 virtual void unsplit(edge eIn, edge eOut);
908
909 //! Splits a node while preserving the order of adjacency entries.
910 /**
911 * This method splits a node \a v into two nodes \a vl and \a vr. Node
912 * \a vl receives all adjacent edges of \a v from \p adjStartLeft until
913 * the edge preceding \p adjStartRight, and \a vr the remaining nodes
914 * (thus \p adjStartRight is the first edge that goes to \a vr). The
915 * order of adjacency entries is preserved. Additionally, a new edge
916 * (\a vl,\a vr) is created, such that this edge is inserted before
917 * \p adjStartLeft and \p adjStartRight in the the adjacency lists of
918 * \a vl and \a vr.
919 *
920 * Node \a v is modified to become node \a vl, and node \a vr is returned.
921 * This method is useful when modifying combinatorial embeddings.
922 *
923 * @param adjStartLeft is the first entry that goes to the left node.
924 * @param adjStartRight is the first entry that goes to the right node.
925 * @return the newly created node.
926 */
927 node splitNode(adjEntry adjStartLeft, adjEntry adjStartRight);
928
929 //! Contracts edge \p e while preserving the order of adjacency entries.
930 /**
931 * @attention Edges parallel to \p e will also be contracted (they do not result in self-loops).
932 * @param e is the edge to be contracted.
933 * @return The endpoint of \p e to which all edges have been moved. The implementation ensures this to be the source of the former edge \p e.
934 */
935 node contract(edge e);
936
937 //! Moves edge \p e to a different adjacency list.
938 /**
939 * The source adjacency entry of \p e is moved to the adjacency list containing
940 * \p adjSrc and is inserted before or after \p adjSrc, and its target adjacency entry
941 * to the adjacency list containing \p adjTgt and is inserted before or after
942 * \p adjTgt; \p e is afterwards an edge from owner(\p adjSrc) to owner(\p adjTgt).
943 *
944 * @param e is the edge to be moved.
945 * @param adjSrc is the adjaceny entry before or after which the source adjacency entry
946 * of \p e will be inserted.
947 * @param dirSrc specifies if the source adjacency entry of \p e will be inserted before or after \p adjSrc.
948 * @param adjTgt is the adjaceny entry before or after which the target adjacency entry
949 * of \p e will be inserted.
950 * @param dirTgt specifies if the target adjacency entry of \p e will be inserted before or after \p adjTgt.
951 */
952 void move(edge e, adjEntry adjSrc, Direction dirSrc,
953 adjEntry adjTgt, Direction dirTgt);
954
955 //! Moves the target node of edge \p e to node \p w.
956 /**
957 * If \p e=(\a v,\a u) before, then \p e=(\a v,\p w) afterwards.
958 *
959 * @param e is the edge whose target node is moved.
960 * @param w is the new target node of \p e.
961 */
962 void moveTarget(edge e, node w);
963
964 //! Moves the target node of edge \p e to a specific position in an adjacency list.
965 /**
966 * Let \a w be the node containing \p adjTgt. If \p e=(\a v,\a u) before, then \a e=(\a v,\a w) afterwards.
967 * Inserts the adjacency entry before or after \p adjTgt according to \p dir.
968 *
969 * @param e is the edge whose target node is moved.
970 * @param adjTgt is the adjacency entry before or after which the target adjacency entry of \p e is inserted.
971 * @param dir specifies if the target adjacency entry of \p e is inserted before or after \p adjTgt.
972 */
973 void moveTarget(edge e, adjEntry adjTgt, Direction dir);
974
975 //! Moves the source node of edge \p e to node \p w.
976 /**
977 * If \p e=(\a v,\a u) before, then \p e=(\p w,\a u) afterwards.
978 *
979 * @param e is the edge whose source node is moved.
980 * @param w is the new source node of \p e.
981 */
982 void moveSource(edge e, node w);
983
984 //! Moves the source node of edge \p e to a specific position in an adjacency list.
985 /**
986 * Let \a w be the node containing \p adjSrc. If \p e=(\a v,\a u) before, then \a e=(\a w,\a u) afterwards.
987 * Inserts the adjacency entry before or after \p adjSrc according to \p dir.
988 *
989 * @param e is the edge whose source node is moved.
990 * @param adjSrc is the adjacency entry before or after which the source adjacency entry of \p e is inserted.
991 * @param dir specifies if the source adjacency entry of \p e is inserted before or after \p adjSrc.
992 */
993 void moveSource(edge e, adjEntry adjSrc, Direction dir);
994
995 //! Searches and returns an edge connecting nodes \p v and \p w in time \a O( min(deg(\p v ), deg(\p w ))).
996 /**
997 * @param v is the first endpoint of the edge to be searched.
998 * @param w is the second endpoint of the edge to be searched.
999 * @param directed iff set to true, enforces that
1000 * \p v must be the source node and \p w the target node of the edge.
1001 * @return an edge (\p v,\p w) (or (\p w,\p v) for !\p directed)
1002 * if such an edge exists, nullptr otherwise.
1003 */
1004 edge searchEdge (node v, node w, bool directed = false) const;
1005
1006 //! Reverses the edge \p e, i.e., exchanges source and target node.
1007 void reverseEdge(edge e);
1008
1009 //! Reverses all edges in the graph.
1010 void reverseAllEdges();
1011
1012 //! Collapses all nodes in the list \p nodesToCollapse to the first node in the list.
1013 /**
1014 * Parallel edges are removed.
1015 *
1016 * @tparam NODELIST is the type of input node list.
1017 * @param nodesToCollapse is the list of nodes that will be collapsed. This list will be empty after the call.
1018 */
1019 template<class NODELIST>
collapse(NODELIST & nodesToCollapse)1020 void collapse(NODELIST &nodesToCollapse){
1021 node v = nodesToCollapse.popFrontRet();
1022 while (!nodesToCollapse.empty())
1023 {
1024 node w = nodesToCollapse.popFrontRet();
1025 adjEntry adj = w->firstAdj();
1026 while (adj != nullptr)
1027 {
1028 adjEntry succ = adj->succ();
1029 edge e = adj->theEdge();
1030 if (e->source() == v || e->target() == v)
1031 delEdge(e);
1032 else if (e->source() == w)
1033 moveSource(e,v);
1034 else
1035 moveTarget(e,v);
1036 adj = succ;
1037 }
1038 delNode(w);
1039 }
1040 }
1041
1042 //! Sorts the adjacency list of node \p v according to \p newOrder.
1043 /**
1044 * \pre \p newOrder contains exactly the adjacency entries of \p v!
1045 *
1046 * @tparam ADJ_ENTRY_LIST is the type of the input adjacency entry list.
1047 * @param v is the node whose adjacency list will be sorted.
1048 * @param newOrder is the list of adjacency entries of \p v in the new order.
1049 */
1050 template<class ADJ_ENTRY_LIST>
sort(node v,const ADJ_ENTRY_LIST & newOrder)1051 void sort(node v, const ADJ_ENTRY_LIST &newOrder) {
1052 #ifdef OGDF_DEBUG
1053 std::set<int> entries;
1054 int counter = 0;
1055
1056 for(adjEntry adj : newOrder) {
1057 entries.insert(adj->index());
1058 OGDF_ASSERT(adj->theNode() == v);
1059 counter++;
1060 }
1061
1062 OGDF_ASSERT(counter == v->degree());
1063 OGDF_ASSERT(entries.size() == static_cast<unsigned int>(v->degree()));
1064 #endif
1065 v->adjEntries.sort(newOrder);
1066 }
1067
1068 //! Reverses the adjacency list of \p v.
1069 /**
1070 * @param v is the node whose adjacency list will be reveresed.
1071 */
reverseAdjEdges(node v)1072 void reverseAdjEdges(node v) {
1073 v->adjEntries.reverse();
1074 }
1075
1076 //! Moves adjacency entry \p adjMove before or after \p adjPos.
1077 /**
1078 * \pre \p adjMove and adjAfter are distinct entries in the same adjacency list.
1079 *
1080 * @param adjMove is an entry in the adjacency list of a node in this graph.
1081 * @param adjPos is an entry in the same adjacency list as \p adjMove.
1082 * @param dir specifies if \p adjMove is moved before or after \p adjPos.
1083 */
moveAdj(adjEntry adjMove,Direction dir,adjEntry adjPos)1084 void moveAdj(adjEntry adjMove, Direction dir, adjEntry adjPos) {
1085 OGDF_ASSERT(adjMove != nullptr);
1086 OGDF_ASSERT(adjPos != nullptr);
1087 OGDF_ASSERT(adjMove->graphOf() == this);
1088 OGDF_ASSERT(adjPos->graphOf() == this);
1089 internal::GraphList<AdjElement> &adjList = adjMove->m_node->adjEntries;
1090 adjList.move(adjMove, adjList, adjPos, dir);
1091 }
1092
1093 //! Moves adjacency entry \p adjMove after \p adjAfter.
1094 /**
1095 * \pre \p adjMove and \p adjAfter are distinct entries in the same adjacency list.
1096 *
1097 * @param adjMove is an entry in the adjacency list of a node in this graph.
1098 * @param adjAfter is an entry in the same adjacency list as \p adjMove.
1099 */
moveAdjAfter(adjEntry adjMove,adjEntry adjAfter)1100 void moveAdjAfter(adjEntry adjMove, adjEntry adjAfter) {
1101 OGDF_ASSERT(adjMove != nullptr);
1102 OGDF_ASSERT(adjAfter != nullptr);
1103 OGDF_ASSERT(adjMove->graphOf() == this);
1104 OGDF_ASSERT(adjAfter->graphOf() == this);
1105 adjMove->m_node->adjEntries.moveAfter(adjMove,adjAfter);
1106 }
1107
1108 //! Moves adjacency entry \p adjMove before \p adjBefore.
1109 /**
1110 * \pre \p adjMove and \p adjBefore are distinct entries in the same adjacency list.
1111 *
1112 * @param adjMove is an entry in the adjacency list of a node in this graph.
1113 * @param adjBefore is an entry in the same adjacency list as \p adjMove.
1114 */
moveAdjBefore(adjEntry adjMove,adjEntry adjBefore)1115 void moveAdjBefore(adjEntry adjMove, adjEntry adjBefore) {
1116 OGDF_ASSERT(adjMove != nullptr);
1117 OGDF_ASSERT(adjBefore != nullptr);
1118 OGDF_ASSERT(adjMove->graphOf() == this);
1119 OGDF_ASSERT(adjBefore->graphOf() == this);
1120 adjMove->m_node->adjEntries.moveBefore(adjMove,adjBefore);
1121 }
1122
1123 //! Reverses all adjacency lists.
1124 void reverseAdjEdges();
1125
1126 //! Exchanges two entries in an adjacency list.
1127 /**
1128 * \pre \p adj1 and \p adj2 must be belong to the same adjacency list.
1129 *
1130 * @param adj1 the first adjacency entry to be swapped.
1131 * @param adj2 the secomd adjacency entry to be swapped.
1132 */
swapAdjEdges(adjEntry adj1,adjEntry adj2)1133 void swapAdjEdges(adjEntry adj1, adjEntry adj2) {
1134 OGDF_ASSERT(adj1->theNode() == adj2->theNode());
1135 OGDF_ASSERT(adj1->graphOf() == this);
1136
1137 adj1->theNode()->adjEntries.swap(adj1,adj2);
1138 }
1139
1140
1141 //@}
1142 /**
1143 * @name Miscellaneous
1144 */
1145 //@{
1146
1147 //! Returns the genus of the graph's embedding.
1148 /**
1149 * The genus of a graph is defined as follows. Let \a G be a graph
1150 * with \a m edges, \a n nodes, \a c connected components, \a nz
1151 * isolated vertices, and \a fc face cycles. Then,
1152 * \f[
1153 * genus(G) = (m/2 + 2c - n -nz -fc)/2
1154 * \f]
1155 *
1156 * @return the genus of the graph's current embedding; if this is 0, then the graph is planarly embedded.
1157 */
1158 int genus() const;
1159
1160 //! Returns true iff the graph represents a combinatorial embedding.
1161 /**
1162 * @return true if the current embedding (given by the adjacency lists) represents a combinatorial embedding, false otherwise.
1163 */
representsCombEmbedding()1164 bool representsCombEmbedding() const {
1165 return genus() == 0;
1166 }
1167
1168 #ifdef OGDF_DEBUG
1169 //! Asserts that this graph is consistent.
1170 void consistencyCheck() const;
1171 #endif
1172
1173 //@}
1174 /**
1175 * @name Registering arrays and observers
1176 * These methods are used by various graph array types like NodeArray or EdgeArray.
1177 * There should be no need to use them directly in user code.
1178 */
1179 //@{
1180
1181 //! Registers a node array.
1182 /**
1183 * \remark This method is automatically called by node arrays; it should not be called manually.
1184 *
1185 * @param pNodeArray is a pointer to the node array's base; this node array must be associated with this graph.
1186 * @return an iterator pointing to the entry for the registered node array in the list of registered node arrays.
1187 * This iterator is required for unregistering the node array again.
1188 */
1189 ListIterator<NodeArrayBase*> registerArray(NodeArrayBase *pNodeArray) const;
1190
1191 //! Registers an edge array.
1192 /**
1193 * \remark This method is automatically called by edge arrays; it should not be called manually.
1194 *
1195 * @param pEdgeArray is a pointer to the edge array's base; this edge array must be associated with this graph.
1196 * @return an iterator pointing to the entry for the registered edge array in the list of registered edge arrays.
1197 * This iterator is required for unregistering the edge array again.
1198 */
1199 ListIterator<EdgeArrayBase*> registerArray(EdgeArrayBase *pEdgeArray) const;
1200
1201 //! Registers an adjEntry array.
1202 /**
1203 * \remark This method is automatically called by adjacency entry arrays; it should not be called manually.
1204 *
1205 * @param pAdjArray is a pointer to the adjacency entry array's base; this adjacency entry array must be
1206 * associated with this graph.
1207 * @return an iterator pointing to the entry for the registered adjacency entry array in the list of registered
1208 * adjacency entry arrays. This iterator is required for unregistering the adjacency entry array again.
1209 */
1210 ListIterator<AdjEntryArrayBase*> registerArray(AdjEntryArrayBase *pAdjArray) const;
1211
1212 //! Registers a graph observer (e.g. a ClusterGraph).
1213 /**
1214 * @param pStructure is a pointer to the graph observer that shall be registered; this graph observer must be
1215 * associated with this graph.
1216 * @return an iterator pointing to the entry for the registered graph observer in the list of registered
1217 * graph observers. This iterator is required for unregistering the graph observer again.
1218 */
1219 ListIterator<GraphObserver*> registerStructure(GraphObserver *pStructure) const;
1220
1221 //! Unregisters a node array.
1222 /**
1223 * @param it is an iterator pointing to the entry in the list of registered node arrays for the node array to
1224 * be unregistered.
1225 */
1226 void unregisterArray(ListIterator<NodeArrayBase*> it) const;
1227
1228 //! Unregisters an edge array.
1229 /**
1230 * @param it is an iterator pointing to the entry in the list of registered edge arrays for the edge array to
1231 * be unregistered.
1232 */
1233 void unregisterArray(ListIterator<EdgeArrayBase*> it) const;
1234
1235 //! Unregisters an adjEntry array.
1236 /**
1237 * @param it is an iterator pointing to the entry in the list of registered adjacency entry arrays for the
1238 * adjacency entry array to be unregistered.
1239 */
1240 void unregisterArray(ListIterator<AdjEntryArrayBase*> it) const;
1241
1242 //! Unregisters a graph observer.
1243 /**
1244 * @param it is an iterator pointing to the entry in the list of registered graph observers for the graph
1245 * observer to be unregistered.
1246 */
1247 void unregisterStructure(ListIterator<GraphObserver*> it) const;
1248
1249 //! Move the registration \p it of an graph element array to \p pArray (used with move semantics for graph element arrays).
1250 template<class ArrayBase>
moveRegisterArray(ListIterator<ArrayBase * > it,ArrayBase * pArray)1251 void moveRegisterArray(ListIterator<ArrayBase*> it, ArrayBase *pArray) const {
1252 #ifndef OGDF_MEMORY_POOL_NTS
1253 std::lock_guard<std::mutex> guard(m_mutexRegArrays);
1254 #endif
1255 *it = pArray;
1256 }
1257
1258 //! Resets the edge id count to \p maxId.
1259 /**
1260 * The next edge will get edge id \p maxId +1. Use this function with caution!
1261 * It is provided as an efficient way to reduce the edge id count. The Graph class
1262 * increments the edge id count whenever an edge is created; free edge ids resulting
1263 * from removing edges are not reused (there is not something like a freelist).
1264 *
1265 * This function is , e.g., useful, when a lot of edges has been added and
1266 * <em>all</em> these edges are removed again (without creating other new edges
1267 * meanwile). Then, it is safe to reduce the edge id count to the value it had
1268 * before, cf. the following code snippet:
1269 * \code
1270 * int oldIdCount = G.maxEdgeIndex();
1271 * Create some edges
1272 * ...
1273 * Remove all these edges again
1274 * G.resetEdgeIdCount(oldIdCount);
1275 * \endcode
1276 *
1277 * Reducing the edge id count will reduce the memory consumption of edge arrays
1278 * associated with the graph.
1279 *
1280 * \pre -1 <= \p maxId <= maximal edge id in the graph.
1281 *
1282 * @param maxId is an upper bound of the edge ids in the graph.
1283 */
1284 void resetEdgeIdCount(int maxId);
1285
1286
1287 //@}
1288 /**
1289 * @name Operators
1290 */
1291 //@{
1292 //! Assignment operator.
1293 /**
1294 * The assignment operature assures that the adjacency lists of nodes in the
1295 * constructed graph are in the same order as the adjacency lists in \p G.
1296 * This is in particular important when dealing with embedded graphs.
1297 *
1298 * @param G is the graph to be copied.
1299 * @return this graph.
1300 */
1301 Graph &operator=(const Graph &G);
1302
1303 OGDF_MALLOC_NEW_DELETE
1304
1305 //@}
1306
1307 public:
1308
1309 //! Info structure for maintaining connected components.
1310 class OGDF_EXPORT CCsInfo {
1311
1312 const Graph *m_graph; //!< points to the associated graph.
1313 int m_numCC; //!< the number of connected components.
1314
1315 Array<node> m_nodes; //!< array of all nodes.
1316 Array<edge> m_edges; //!< array of all edges.
1317 Array<int> m_startNode; //!< start node of each connected component in m_nodes.
1318 Array<int> m_startEdge; //!< start edge of each connected component in m_edges.
1319
1320 public:
1321 //! Creates a info structure associated with no graph.
CCsInfo()1322 CCsInfo() : m_graph(nullptr), m_numCC(0) { }
1323
1324 //! Creates a info structure associated with graph \p G.
1325 explicit CCsInfo(const Graph& G);
1326
1327 //! Returns the associated graph.
constGraph()1328 const Graph &constGraph() const { return *m_graph; }
1329
1330 //! Returns the number of connected components.
numberOfCCs()1331 int numberOfCCs() const { return m_numCC; }
1332
1333 //! Returns the number of nodes in connected component \p cc.
numberOfNodes(int cc)1334 int numberOfNodes(int cc) const { return stopNode(cc) - startNode(cc); }
1335
1336 //! Returns the number of edges in connected component \p cc.
numberOfEdges(int cc)1337 int numberOfEdges(int cc) const { return stopEdge(cc) - startEdge(cc); }
1338
1339 //! Returns the index of the first node in connected component \p cc.
startNode(int cc)1340 int startNode(int cc) const { return m_startNode[cc]; }
1341
1342 //! Returns the index of (one past) the last node in connected component \p cc.
stopNode(int cc)1343 int stopNode (int cc) const { return m_startNode[cc+1]; }
1344
1345 //! Returns the index of the first edge in connected component \p cc.
startEdge(int cc)1346 int startEdge(int cc) const { return m_startEdge[cc]; }
1347
1348 //! Returns the index of (one past) the last edge in connected component \p cc.
stopEdge(int cc)1349 int stopEdge (int cc) const { return m_startEdge[cc+1]; }
1350
1351 //! Returns the node with index \p i.
v(int i)1352 node v(int i) const { return m_nodes[i]; }
1353
1354 //! Returns the edge with index \p i.
e(int i)1355 edge e(int i) const { return m_edges[i]; }
1356 };
1357
1358 protected:
1359 void construct(const Graph &G, NodeArray<node> &mapNode, EdgeArray<edge> &mapEdge);
1360
1361 void assign(const Graph &G, NodeArray<node> &mapNode, EdgeArray<edge> &mapEdge);
1362
1363 //! Constructs a copy of the subgraph of \p G induced by \p nodeList.
1364 /**
1365 * This method preserves the order in the adjacency lists, i.e., if
1366 * \p G is embedded, its embedding induces the embedding of the copy.
1367 */
1368 void constructInitByNodes(
1369 const Graph &G,
1370 const List<node> &nodeList,
1371 NodeArray<node> &mapNode,
1372 EdgeArray<edge> &mapEdge);
1373
1374 void constructInitByActiveNodes(
1375 const List<node> &nodeList,
1376 const NodeArray<bool> &activeNodes,
1377 NodeArray<node> &mapNode,
1378 EdgeArray<edge> &mapEdge);
1379
1380 //! Constructs a copy of connected component \p cc in \p info.
1381 void constructInitByCC(
1382 const CCsInfo &info,
1383 int cc,
1384 NodeArray<node> &mapNode,
1385 EdgeArray<edge> &mapEdge);
1386
1387 private:
1388 void copy(const Graph &G, NodeArray<node> &mapNode,
1389 EdgeArray<edge> &mapEdge);
1390 void copy(const Graph &G);
1391
1392 edge createEdgeElement(node v, node w, adjEntry adjSrc, adjEntry adjTgt);
1393 node pureNewNode();
1394
1395 // moves adjacency entry to node w
1396 void moveAdj(adjEntry adj, node w);
1397
1398 //! Sets the sizes of registered node and edge arrays to the
1399 //! next power of two that is no less than the current id counts.
1400 //! Respects the minimum table size constants.
1401 void resetTableSizes();
1402
1403 //! Re-initializes registed arrays with respect to the current sizes.
1404 //! Calls #resetTableSizes() if \p doResetTableSizes is \c true (default).
1405 void reinitArrays(bool doResetTableSizes = true);
1406 void reinitStructures();
1407 void resetAdjEntryIndex(int newIndex, int oldIndex);
1408
1409 /**
1410 * Used to restore all hidden edges upon deleting the graph.
1411 */
1412 void restoreAllEdges();
1413 };
1414
1415 OGDF_EXPORT std::ostream & operator<<(std::ostream &os, const Graph::EdgeType &et);
1416
1417 //! Bucket function using the index of an edge's source node as bucket.
1418 class OGDF_EXPORT BucketSourceIndex : public BucketFunc<edge> {
1419 public:
1420 //! Returns source index of \p e.
getBucket(const edge & e)1421 int getBucket(const edge &e) override { return e->source()->index(); }
1422 };
1423
1424 //! Bucket function using the index of an edge's target node as bucket.
1425 class OGDF_EXPORT BucketTargetIndex : public BucketFunc<edge> {
1426 public:
1427 //! Returns target index of \p e.
getBucket(const edge & e)1428 int getBucket(const edge &e) override { return e->target()->index(); }
1429 };
1430
1431 namespace internal {
1432
1433 template<typename CONTAINER>
getAllNodes(const Graph & G,CONTAINER & nodes)1434 inline void getAllNodes(const Graph& G, CONTAINER& nodes) {
1435 nodes.clear();
1436 for (node v : G.nodes) {
1437 nodes.pushBack(v);
1438 }
1439 }
1440
1441 template<>
getAllNodes(const Graph & G,Array<node> & nodes)1442 inline void getAllNodes(const Graph& G, Array<node>& nodes) {
1443 nodes.init(G.numberOfNodes());
1444 int i = 0;
1445 for (node v : G.nodes) {
1446 nodes[i++] = v;
1447 }
1448 }
1449
1450 template<typename CONTAINER>
getAllEdges(const Graph & G,CONTAINER & edges)1451 inline void getAllEdges(const Graph& G, CONTAINER& edges) {
1452 edges.clear();
1453 for (edge v : G.edges) {
1454 edges.pushBack(v);
1455 }
1456 }
1457
1458 template<>
getAllEdges(const Graph & G,Array<edge> & edges)1459 inline void getAllEdges(const Graph& G, Array<edge>& edges) {
1460 edges.init(G.numberOfEdges());
1461 int i = 0;
1462 for (edge v : G.edges) {
1463 edges[i++] = v;
1464 }
1465 }
1466
1467 }
1468
1469 struct NodePair {
1470 node source = nullptr;
1471 node target = nullptr;
1472 NodePair() = default;
NodePairNodePair1473 NodePair(node src, node tgt) : source(src), target(tgt) {}
1474 };
1475
1476 inline std::ostream &operator<<(std::ostream &os, const NodePair& np) {
1477 os << "(" << np.source << "," << np.target << ")";
1478 return os;
1479 }
1480
1481 }
1482