Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
simple_graph_alg.h
Go to the documentation of this file.
1
32#pragma once
33
36#include <ogdf/basic/SList.h>
37#include <ogdf/basic/tuples.h>
38
39namespace ogdf {
40
43
50
52
59
61
68template<class NODELIST>
70 L.clear();
71
72 safeForEach(G.edges, [&](edge e) {
73 if (e->isSelfLoop()) {
74 L.pushBack(e->source());
75 G.delEdge(e);
76 }
77 });
78}
79
83
85
91
92
96
98
105
106
108
119
121
134template<bool ONLY_ONCE = false>
135int numParallelEdges(const Graph& G) {
136 if (G.numberOfEdges() <= 1) {
137 return 0;
138 }
139
140 SListPure<edge> edges;
141 parallelFreeSort(G, edges);
142
143 int num = 0;
144 SListConstIterator<edge> it = edges.begin();
145 edge ePrev = *it, e;
146 for (it = ++it; it.valid(); ++it, ePrev = e) {
147 e = *it;
148 if (ePrev->isParallelDirected(e)) {
149 ++num;
150 if (ONLY_ONCE) {
151 return num;
152 }
153 }
154 }
155
156 return num;
157}
158
160
172template<class EDGELIST>
174 parallelEdges.clear();
175 if (G.numberOfEdges() <= 1) {
176 return;
177 }
178
179 SListPure<edge> edges;
180 parallelFreeSort(G, edges);
181
182 SListConstIterator<edge> it = edges.begin();
183 edge ePrev = *it++, e;
184 bool bAppend = true;
185 while (it.valid()) {
186 e = *it++;
187 if (e->isParallelDirected(ePrev)) {
188 G.delEdge(e);
189 if (bAppend) {
190 parallelEdges.pushBack(ePrev);
191 bAppend = false;
192 }
193 } else {
194 ePrev = e;
195 bAppend = true;
196 }
197 }
198}
199
201
214
216
229
230
232
242
244
256template<bool ONLY_ONCE = false>
258 if (G.numberOfEdges() <= 1) {
259 return 0;
260 }
261
262 SListPure<edge> edges;
265
266 int num = 0;
267 SListConstIterator<edge> it = edges.begin();
268 edge ePrev = *it, e;
269 for (it = ++it; it.valid(); ++it, ePrev = e) {
270 e = *it;
271 if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) {
272 ++num;
273 if (ONLY_ONCE) {
274 return num;
275 }
276 }
277 }
278
279 return num;
280}
281
283
294template<class EDGELIST>
296 if (G.numberOfEdges() <= 1) {
297 return;
298 }
299
300 SListPure<edge> edges;
303
304 SListConstIterator<edge> it = edges.begin();
305 edge ePrev = *it++, e;
306 while (it.valid()) {
307 e = *it++;
308 if (minIndex[ePrev] == minIndex[e] && maxIndex[ePrev] == maxIndex[e]) {
309 parallelEdges[ePrev].pushBack(e);
310 } else {
311 ePrev = e;
312 }
313 }
314}
315
317
334template<class EDGELIST = SListPure<edge>>
337 if (parallelEdges != nullptr) {
338 parallelEdges->clear();
339 }
340 if (cardPositive != nullptr) {
341 cardPositive->fill(0);
342 }
343 if (cardNegative != nullptr) {
344 cardNegative->fill(0);
345 }
346
347 if (G.numberOfEdges() <= 1) {
348 return;
349 }
350
353
354 for (edge e : G.edges) {
355 for (edge parEdge : parEdges(e)) {
356 if (cardPositive != nullptr && e->source() == parEdge->source()) {
357 (*cardPositive)[e]++;
358 }
359 if (cardNegative != nullptr && e->source() == parEdge->target()) {
360 (*cardNegative)[e]++;
361 }
362 G.delEdge(parEdge);
363 if (parallelEdges != nullptr) {
364 parallelEdges->pushBack(e);
365 }
366 }
367 }
368}
369
370template<class EDGELIST>
371OGDF_DEPRECATED("The pointer-based makeParallelFreeUndirected() should be used instead.")
372void makeParallelFreeUndirected(Graph& G, EDGELIST& parallelEdges) {
374}
375
376template<class EDGELIST>
377OGDF_DEPRECATED("The pointer-based makeParallelFreeUndirected() should be used instead.")
382
386
388
394inline bool isSimple(const Graph& G) { return isLoopFree(G) && isParallelFree(G); }
395
397
402inline void makeSimple(Graph& G) {
403 makeLoopFree(G);
405}
406
408
415inline bool isSimpleUndirected(const Graph& G) {
416 return isLoopFree(G) && isParallelFreeUndirected(G);
417}
418
420
429
433
435
442
443
445
452
454
459inline void makeConnected(Graph& G) {
462}
463
466
479 List<node>* isolated = nullptr);
480
482
488inline int connectedComponents(const Graph& G) {
489 NodeArray<int> component(G);
490 return connectedComponents(G, component);
491}
492
493
494OGDF_DEPRECATED("connectedComponents() should be used instead.")
495
496
499inline int connectedIsolatedComponents(const Graph& G, List<node>& isolated,
500 NodeArray<int>& component) {
501 return connectedComponents(G, component, &isolated);
502}
503
511
514
529
531
538OGDF_EXPORT bool isBiconnected(const Graph& G, node& cutVertex);
539
541
546inline bool isBiconnected(const Graph& G) {
547 node cutVertex;
548 return isBiconnected(G, cutVertex);
549}
550
552
559
561
566inline void makeBiconnected(Graph& G) {
569}
570
578 int& nonEmptyComponents);
579
581
594inline int biconnectedComponents(const Graph& G, EdgeArray<int>& component) {
596 return biconnectedComponents(G, component, doNotNeedTheValue);
597}
598
604OGDF_EXPORT bool isTwoEdgeConnected(const Graph& graph, edge& bridge);
605
619inline bool isTwoEdgeConnected(const Graph& graph) {
620 edge bridge;
621 return isTwoEdgeConnected(graph, bridge);
622}
623
625
638OGDF_EXPORT bool isTriconnected(const Graph& G, node& s1, node& s2);
639
641
647inline bool isTriconnected(const Graph& G) {
648 node s1, s2;
649 return isTriconnected(G, s1, s2);
650}
651
653
670
672
681inline bool isTriconnectedPrimitive(const Graph& G) {
682 node s1, s2;
683 return isTriconnectedPrimitive(G, s1, s2);
684}
685
687
698
699
703
705
713
715
721inline bool isAcyclic(const Graph& G) {
723 return isAcyclic(G, backedges);
724}
725
727
735
737
743inline bool isAcyclicUndirected(const Graph& G) {
746}
747
749
757
758
760
768
769
771
778OGDF_EXPORT bool hasSingleSource(const Graph& G, node& source);
779
781
787inline bool hasSingleSource(const Graph& G) {
788 node source;
789 return hasSingleSource(G, source);
790}
791
793
801
803
809inline bool hasSingleSink(const Graph& G) {
810 node sink;
811 return hasSingleSink(G, sink);
812}
813
815
827OGDF_EXPORT bool isStGraph(const Graph& G, node& s, node& t, edge& st);
828
830
838inline bool isStGraph(const Graph& G) {
839 node s, t;
840 edge st;
841 return isStGraph(G, s, t, st);
842}
843
845
854
855
857
867
868
870
880
882
889inline void makeBimodal(Graph& G) {
890 List<edge> dummy;
891 makeBimodal(G, dummy);
892}
893
894
898
899OGDF_DEPRECATED("isAcyclicUndirected() should be used instead.")
900
901
904inline bool isFreeForest(const Graph& G) { return isAcyclicUndirected(G); }
905
907
913inline bool isTree(const Graph& G) {
914 return G.empty() || ((G.numberOfNodes() == G.numberOfEdges() + 1) && isConnected(G));
915}
916
918
927
929
935inline bool isArborescenceForest(const Graph& G) {
937 return isArborescenceForest(G, roots);
938}
939
940
941OGDF_DEPRECATED("isArborescenceForest() should be used instead.")
942
943
946inline bool isForest(const Graph& G, List<node>& roots) { return isArborescenceForest(G, roots); }
947
948
949OGDF_DEPRECATED("isArborescenceForest() should be used instead.")
950
951
954inline bool isForest(const Graph& G) { return isArborescenceForest(G); }
955
957
964OGDF_EXPORT bool isArborescence(const Graph& G, node& root);
965
967
973inline bool isArborescence(const Graph& G) {
974 node root;
975 return isArborescence(G, root);
976}
977
979
981
988
989
991
998OGDF_EXPORT bool isRegular(const Graph& G, int d);
999
1000
1002
1011
1013
1019inline bool isBipartite(const Graph& G) {
1020 NodeArray<bool> color(G);
1021 return isBipartite(G, color);
1022}
1023
1056OGDF_EXPORT void nodeDistribution(const Graph& G, Array<int>& degdist, std::function<int(node)> func);
1057
1066 nodeDistribution(G, degdist, [](node v) { return v->degree(); });
1067}
1068
1069}
Declaration and implementation of EdgeArray class.
Declaration and implementation of NodeArray class.
Declaration of singly linked lists and iterators.
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:56
The parameterized class Array implements dynamic arrays of type E.
Definition Array.h:214
Dynamic arrays indexed with edges.
Definition EdgeArray.h:125
Class for the representation of edges.
Definition Graph_d.h:300
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:521
Doubly linked lists (maintaining the length of the list).
Definition List.h:1435
Dynamic arrays indexed with nodes.
Definition NodeArray.h:125
Class for the representation of nodes.
Definition Graph_d.h:177
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition Graph_d.h:220
Encapsulates a pointer to an ogdf::SList element.
Definition SList.h:92
bool valid() const
Returns true iff the iterator points to an element.
Definition SList.h:122
Singly linked lists.
Definition SList.h:179
iterator begin()
Returns an iterator to the first element of the list.
Definition SList.h:332
Tuples of two elements (2-tuples).
Definition tuples.h:46
#define OGDF_EXPORT
Specifies that a function or class is exported by the OGDF DLL.
Definition config.h:101
bool isBiconnected(const Graph &G, node &cutVertex)
Returns true iff G is biconnected.
void makeBiconnected(Graph &G, List< edge > &added)
Makes G biconnected by adding edges.
void makeConnected(Graph &G, List< edge > &added)
Makes G connected by adding a minimum number of edges.
int biconnectedComponents(const Graph &G, EdgeArray< int > &component, int &nonEmptyComponents)
Computes the biconnected components of G.
bool isConnected(const Graph &G)
Returns true iff G is connected.
bool isTwoEdgeConnected(const Graph &graph, edge &bridge)
Returns true iff graph is 2-edge-connected.
bool isTriconnected(const Graph &G, node &s1, node &s2)
Returns true iff G is triconnected.
bool findCutVertices(const Graph &G, ArrayBuffer< node > &cutVertices, ArrayBuffer< Tuple2< node, node > > &addEdges, bool onlyOne=false)
Finds cut vertices and potential edges that could be added to turn the cut vertices into non-cut vert...
int connectedComponents(const Graph &G, NodeArray< int > &component, List< node > *isolated=nullptr)
Computes the connected components of G and optionally generates a list of isolated nodes.
void triangulate(Graph &G)
Triangulates a planarly embedded graph G by adding edges.
bool isTriconnectedPrimitive(const Graph &G, node &s1, node &s2)
Returns true iff G is triconnected (using a quadratic time algorithm!).
bool isAcyclic(const Graph &G, List< edge > &backedges)
Returns true iff the digraph G is acyclic.
int strongComponents(const Graph &G, NodeArray< int > &component)
Computes the strongly connected components of the digraph G.
void makeAcyclicByReverse(Graph &G)
Makes the digraph G acyclic by reversing edges.
void makeBimodal(Graph &G, List< edge > &newEdges)
Makes the digraph G bimodal.
bool hasSingleSource(const Graph &G, node &source)
Returns true iff the digraph G contains exactly one source node (or is empty).
bool isStGraph(const Graph &G, node &s, node &t, edge &st)
Returns true iff G is an st-digraph.
bool hasSingleSink(const Graph &G, node &sink)
Returns true iff the digraph G contains exactly one sink node (or is empty).
void makeAcyclic(Graph &G)
Makes the digraph G acyclic by removing edges.
void topologicalNumbering(const Graph &G, NodeArray< int > &num)
Computes a topological numbering of an acyclic digraph G.
bool isAcyclicUndirected(const Graph &G, List< edge > &backedges)
Returns true iff the undirected graph G is acyclic.
bool isParallelFreeUndirected(const Graph &G)
Returns true iff G contains no undirected parallel edges.
void makeLoopFree(Graph &G, NODELIST &L)
Removes all self-loops from G and returns all nodes with self-loops in L.
bool isParallelFree(const Graph &G)
Returns true iff G contains no parallel edges.
void makeSimple(Graph &G)
Removes all self-loops and all but one edge of each bundle of parallel edges.
void makeParallelFreeUndirected(Graph &G, EDGELIST *parallelEdges=nullptr, EdgeArray< int > *cardPositive=nullptr, EdgeArray< int > *cardNegative=nullptr)
Removes all but one edge of each bundle of undirected parallel edges.
bool isLoopFree(const Graph &G)
Returns true iff G contains no self-loop.
void parallelFreeSort(const Graph &G, SListPure< edge > &edges)
Sorts the edges of G such that parallel edges come after each other in the list.
void parallelFreeSortUndirected(const Graph &G, SListPure< edge > &edges, EdgeArray< int > &minIndex, EdgeArray< int > &maxIndex)
Sorts the edges of G such that undirected parallel edges come after each other in the list.
int numParallelEdgesUndirected(const Graph &G)
Returns the number of undirected parallel edges in G.
void makeParallelFree(Graph &G, EDGELIST &parallelEdges)
Removes all but one of each bundle of parallel edges.
void removeSelfLoops(Graph &graph, node v)
Removes all self-loops for a given node v in graph.
void getParallelFreeUndirected(const Graph &G, EdgeArray< EDGELIST > &parallelEdges)
Computes the bundles of undirected parallel edges in G.
bool isSimpleUndirected(const Graph &G)
Returns true iff G contains neither self-loops nor undirected parallel edges.
bool isSimple(const Graph &G)
Returns true iff G contains neither self-loops nor parallel edges.
bool hasNonSelfLoopEdges(const Graph &G)
Returns whether G has edges which are not self-loops.
int numParallelEdges(const Graph &G)
Returns the number of parallel edges in G.
void makeSimpleUndirected(Graph &G)
Removes all self-loops and all but one edge of each bundle of undirected parallel edges.
bool isArborescenceForest(const Graph &G, List< node > &roots)
Returns true iff G is a forest consisting only of arborescences.
bool isArborescence(const Graph &G, node &root)
Returns true iff G represents an arborescence.
bool isTree(const Graph &G)
Returns true iff G is a tree, i.e. contains no undirected cycle and is connected.
bool isBipartite(const Graph &G, NodeArray< bool > &color)
Checks whether a graph is bipartite.
void degreeDistribution(const Graph &G, Array< int > &degdist)
Fills degdist with the degree distribution of graph G.
void nodeDistribution(const Graph &G, Array< int > &degdist, std::function< int(node)> func)
Fills dist with the distribution given by a function func in graph G.
bool isRegular(const Graph &G)
Checks if a graph is regular.
#define OGDF_DEPRECATED(reason)
Mark a class / member / function as deprecated.
Definition config.h:120
static MultilevelBuilder * getDoubleFactoredZeroAdjustedMerger()
The namespace for all OGDF objects.
void safeForEach(CONTAINER &container, std::function< void(typename CONTAINER::value_type)> func)
Calls (possibly destructive) func for each element of container.
Declaration and implementation of class Tuple2, Tuple3 and Tuple4.