Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
BoyerMyrvoldPlanar.h
Go to the documentation of this file.
1
33#pragma once
34
35#include <ogdf/basic/Array.h>
36#include <ogdf/basic/Graph.h>
37#include <ogdf/basic/List.h>
38#include <ogdf/basic/SList.h>
39#include <ogdf/basic/basic.h>
40
41#include <iostream>
42#include <random>
43
44namespace ogdf {
45template<class E, class INDEX>
46class ArrayBuffer;
47
50 Undefined = 0,
51 Selfloop = 1,
52 Back = 2,
53 Dfs = 3,
54 DfsParallel = 4,
55 BackDeleted = 5
56};
57
58class FindKuratowskis;
59class KuratowskiStructure;
60
61namespace boyer_myrvold {
62class BoyerMyrvoldInit;
63}
64
67 friend class BoyerMyrvold;
69 friend class FindKuratowskis;
70 friend class ExtractKuratowskis;
71
72public:
74 const static int DirectionCCW;
75
77 const static int DirectionCW;
78
80 enum class EmbeddingGrade {
81 doNotEmbed = -3, // and not find any kuratowski subdivisions
82 doNotFind = -2, // but embed
83 doFindUnlimited = -1, // and embed
84 doFindZero = 0 // and embed
85 };
86
88 BoyerMyrvoldPlanar(Graph& g, bool bundles, int embeddingGrade, bool limitStructures,
89 SListPure<KuratowskiStructure>& output, double randomness, bool avoidE2Minors,
90 bool extractSubgraph, const EdgeArray<int>* edgeCosts = nullptr);
91
93 BoyerMyrvoldPlanar(Graph& g, bool bundles, EmbeddingGrade embeddingGrade, bool limitStructures,
94 SListPure<KuratowskiStructure>& output, double randomness, bool avoidE2Minors,
95 bool extractSubgraph, const EdgeArray<int>* edgeCosts = nullptr)
96 : BoyerMyrvoldPlanar(g, bundles, static_cast<int>(embeddingGrade), limitStructures, output,
97 randomness, avoidE2Minors, extractSubgraph, edgeCosts) { }
98
100 bool start();
101
103
109 void flipBicomp(int c, int marker, NodeArray<int>& visited, bool wholeGraph,
110 bool deleteFlipFlags);
111
112 // avoid automatic creation of assignment operator
115
119 void seed(const std::minstd_rand rand) { m_rand = rand; }
120
121protected:
124
126 inline bool pertinent(node w) const {
127 OGDF_ASSERT(w != nullptr);
128 return m_dfi[w] > 0 && (!m_backedgeFlags[w].empty() || !m_pertinentRoots[w].empty());
129 }
130
132 inline bool internallyActive(node w, int v) const {
133 OGDF_ASSERT(w != nullptr);
134 return m_dfi[w] > 0 && pertinent(w) && !externallyActive(w, v);
135 }
136
138 inline bool externallyActive(node w, int v) const {
139 OGDF_ASSERT(w != nullptr);
140 if (m_dfi[w] <= 0) {
141 return false;
142 }
143 if (m_leastAncestor[w] < v) {
144 return true;
145 }
146 return !m_separatedDFSChildList[w].empty()
147 && m_lowPoint[m_separatedDFSChildList[w].front()] < v;
148 }
149
151 inline bool inactive(node w, int v) {
152 OGDF_ASSERT(w != nullptr);
153 if (m_dfi[w] <= 0) {
154 return true;
155 }
156 if (!m_backedgeFlags[w].empty() || !m_pertinentRoots[w].empty() || m_leastAncestor[w] < v) {
157 return false;
158 }
159 return m_separatedDFSChildList[w].empty()
160 || m_lowPoint[m_separatedDFSChildList[w].front()] >= v;
161 }
162
164
171 inline int infoAboutNode(node w, int v) const {
172 OGDF_ASSERT(w != nullptr);
173 if (m_dfi[w] <= 0) {
174 return 0;
175 }
176 if (!m_pertinentRoots[w].empty() || !m_backedgeFlags[w].empty()) {
177 // pertinent
178 if (m_leastAncestor[w] < v) {
179 return 2;
180 }
181 if (m_separatedDFSChildList[w].empty()) {
182 return 1;
183 }
184 return m_lowPoint[m_separatedDFSChildList[w].front()] < v ? 2 : 1;
185 } else {
186 // not pertinent
187 if (m_leastAncestor[w] < v) {
188 return 3;
189 }
190 if (m_separatedDFSChildList[w].empty()) {
191 return 0;
192 }
193 return m_lowPoint[m_separatedDFSChildList[w].front()] < v ? 3 : 0;
194 }
195 }
196
198
203 inline node successorOnExternalFace(node w, int& direction) const {
204 OGDF_ASSERT(w != nullptr);
205 OGDF_ASSERT(w->degree() > 0);
208 adjEntry adj = m_link[direction][w];
209 OGDF_ASSERT(adj->theNode() != nullptr);
210
211 if (w->degree() > 1) {
212 direction = adj
214 }
215 OGDF_ASSERT(direction
217 return adj->theNode();
218 }
219
221 inline node successorWithoutShortCircuit(node w, int& direction) {
222 OGDF_ASSERT(w != nullptr);
223 OGDF_ASSERT(w->degree() > 0);
226 adjEntry adj = beforeShortCircuitEdge(w, direction);
227 OGDF_ASSERT(adj->theNode() != nullptr);
228
229 if (w->degree() > 1) {
230 direction = adj
232 }
233 OGDF_ASSERT(direction
235 return adj->theNode();
236 }
237
239
241 inline node constSuccessorOnExternalFace(node v, int direction) {
242 OGDF_ASSERT(v != nullptr);
243 OGDF_ASSERT(v->degree() > 0);
244 return m_link[direction][v]->theNode();
245 }
246
248
250 inline node constSuccessorWithoutShortCircuit(node v, int direction) const {
251 OGDF_ASSERT(v != nullptr);
252 OGDF_ASSERT(v->degree() > 0);
253 return beforeShortCircuitEdge(v, direction)->theNode();
254 }
255
257
260 inline adjEntry beforeShortCircuitEdge(node v, int direction) const {
261 OGDF_ASSERT(v != nullptr);
262 return (m_beforeSCE[direction][v] == nullptr) ? m_link[direction][v]
263 : m_beforeSCE[direction][v];
264 }
265
267
269 node activeSuccessor(node w, int& direction, int v, int& info) const;
270
272
274 inline node constActiveSuccessor(node w, int direction, int v, int& info) const {
275 return activeSuccessor(w, direction, v, info);
276 }
277
279
281 inline bool wNodesExist(node root, node stopx, node stopy) const {
282 OGDF_ASSERT(root != stopx);
283 OGDF_ASSERT(root != stopy);
284 OGDF_ASSERT(stopx != stopy);
286 bool between = false;
287 while (root != nullptr) {
288 root = successorOnExternalFace(root, dir);
289 if (between && pertinent(root)) {
290 return true;
291 }
292 if (root == stopx || root == stopy) {
293 if (between) {
294 return false;
295 }
296 between = true;
297 }
298 }
299 return false;
300 }
301
303 inline void printNodeInfo(node v) {
304 std::cout
305 << "\nprintNodeInfo(" << m_dfi[v] << "): "
308 << "\tCCWBefore="
310 << ",CWBefore="
312 << "\tadjList: ";
313 adjEntry adj;
314 for (adj = v->firstAdj(); adj; adj = adj->succ()) {
315 std::cout << adj->twinNode() << " ";
316 }
317 }
318
322
325 void embedBackedges(const node v, const int v_dir, const node w, const int w_dir);
326
328 void createShortCircuitEdge(const node v, const int v_dir, const node w, const int w_dir);
329
331
334 node walkup(const node v, const node w, const int marker, const edge back);
335
337
343 int walkdown(const int i, const node v, FindKuratowskis* findKuratowskis);
344
347
349
352
354
356 bool embed();
357
359
362
365 const bool m_bundles;
368 const double m_randomness;
369 const bool m_avoidE2Minors;
371 std::minstd_rand m_rand;
373
375 bool m_extractSubgraph = true;
376
379
382
384
387
390
393
395
398
400
405
408
410
413
416
419
422
424
427
429
432
436
439
442
449
456
458
463
465
469
472
475
477};
478
480 return lhs > static_cast<int>(rhs);
481}
482
484 return lhs == static_cast<int>(rhs);
485}
486
488 return lhs != static_cast<int>(rhs);
489}
490
492 return lhs <= static_cast<int>(rhs);
493}
494
495}
Declaration and implementation of Array class and Array algorithms.
Includes declaration of graph class.
Declaration of doubly linked lists and iterators.
Declaration of singly linked lists and iterators.
Basic declarations, included by all source files.
Class for adjacency list elements.
Definition Graph_d.h:143
adjEntry twin() const
Returns the corresponding adjacency element associated with the same edge.
Definition Graph_d.h:173
adjEntry succ() const
Returns the successor in the adjacency list.
Definition Graph_d.h:219
node twinNode() const
Returns the associated node of the corresponding adjacency entry (shorthand for twin()->theNode()).
Definition Graph_d.h:176
node theNode() const
Returns the node whose adjacency list contains this element.
Definition Graph_d.h:167
An array that keeps track of the number of inserted elements; also usable as an efficient stack.
Definition ArrayBuffer.h:64
The parameterized class Array implements dynamic arrays of type E.
Definition Array.h:219
Wrapper class used for preprocessing and valid invocation of the planarity test.
This class implements the extended BoyerMyrvold planarity embedding algorithm.
BoyerMyrvoldPlanar(Graph &g, bool bundles, EmbeddingGrade embeddingGrade, bool limitStructures, SListPure< KuratowskiStructure > &output, double randomness, bool avoidE2Minors, bool extractSubgraph, const EdgeArray< int > *edgeCosts=nullptr)
Constructor, for parameters see BoyerMyrvold.
NodeArray< SListPure< node > > m_pertinentRoots
List of virtual bicomp roots, that are pertinent to the current embedded node.
adjEntry beforeShortCircuitEdge(node v, int direction) const
Returns underlying former adjEntry, if a short circuit edge in direction of v exists.
Graph & m_g
Input graph, which can be altered.
static const int DirectionCW
Direction for clockwise traversal.
NodeArray< SListPure< adjEntry > > m_backedgeFlags
Holds information, if node is the source of a backedge.
NodeArray< ListIterator< node > > m_pNodeInParent
Pointer to node contained in the DFSChildList of his parent, if exists.
NodeArray< edge > m_visitedWithBackedge
Stores for each (real) non-root vertex v with which backedge it was visited during the walkup.
node successorOnExternalFace(node w, int &direction) const
Walks upon external face in the given direction starting at w.
bool externallyActive(node w, int v) const
Checks whether real node w is externally active while embedding node with DFI v.
int infoAboutNode(node w, int v) const
Checks all dynamic information about a node w while embedding node with DFI v.
BoyerMyrvoldPlanar(Graph &g, bool bundles, int embeddingGrade, bool limitStructures, SListPure< KuratowskiStructure > &output, double randomness, bool avoidE2Minors, bool extractSubgraph, const EdgeArray< int > *edgeCosts=nullptr)
Constructor, for parameters see BoyerMyrvold.
Array< node > m_nodeFromDFI
Returns appropriate node from given DFI.
bool pertinent(node w) const
Checks whether node w is pertinent. w has to be non-virtual.
NodeArray< int > m_numUnembeddedBackedgesInBicomp
Stores for each (virtual) bicomp root how many backedges to its bicomp still have to be embedded.
node constSuccessorWithoutShortCircuit(node v, int direction) const
Walks upon external face in direction avoiding short circuit edges.
NodeArray< int > m_dfi
The one and only DFI-NodeArray.
NodeArray< int > m_leastAncestor
The DFI of the least ancestor node over all backedges.
int walkdown(const int i, const node v, FindKuratowskis *findKuratowskis)
Walkdown: Embeds all backedges with DFI i as targetnode to node v.
node constSuccessorOnExternalFace(node v, int direction)
Returns the successornode on the external face in given direction.
bool inactive(node w, int v)
Checks whether real node w is inactive while embedding node with DFI v.
NodeArray< int > m_lowPoint
The lowpoint of each node.
node successorWithoutShortCircuit(node w, int &direction)
Walks upon external face in given direction avoiding short circuit edges.
void seed(const std::minstd_rand rand)
Seeds the random generator for performing a random DFS. If this method is never called the random gen...
NodeArray< bool > m_flipped
Iff true, the node is the root of a bicomp which has to be flipped.
NodeArray< int > m_visited
This Array keeps track of all vertices that are visited by current walkup.
SListPure< KuratowskiStructure > & m_output
Data structure for the Kuratowski subdivisions, which will be returned.
bool wNodesExist(node root, node stopx, node stopy) const
Checks, if one ore more wNodes exist between the two stopping vertices stopx and stopy.
node activeSuccessor(node w, int &direction, int v, int &info) const
Walks upon external face in the given direction starting at w until an active vertex is reached.
NodeArray< adjEntry > m_link[2]
Links to opposite adjacency entries on external face in clockwise resp. ccw order.
bool start()
Starts the embedding algorithm.
NodeArray< node > m_realVertex
Link to non-virtual vertex of a virtual Vertex.
const EdgeArray< int > * m_edgeCosts
NodeArray< adjEntry > m_adjParent
The adjEntry which goes from DFS-parent to current vertex.
void mergeBiconnectedComponent(ArrayBuffer< int > &stack)
Merges the last two biconnected components saved in stack. Embeds them iff m_embeddingGrade !...
static const int DirectionCCW
Direction for counterclockwise traversal.
EdgeArray< node > m_pointsToRoot
Identifies the rootnode of the child bicomp the given backedge points to.
BoyerMyrvoldPlanar & operator=(const BoyerMyrvoldPlanar &)
Assignment operator is undefined!
NodeArray< int > m_highestSubtreeDFI
The highest DFI in a subtree with node as root.
NodeArray< ListPure< node > > m_separatedDFSChildList
A list to all separated DFS-children of node.
EmbeddingGrade
Denotes the different embedding options.
void createShortCircuitEdge(const node v, const int v_dir, const node w, const int w_dir)
Creates a short circuit edge from node v with direction v_dir to node w with direction w_dir.
EdgeArray< BoyerMyrvoldEdgeType > m_edgeType
Contains the type of each edge.
NodeArray< adjEntry > m_beforeSCE[2]
Links for short circuit edges.
void mergeUnprocessedNodes()
Merges unprocessed virtual nodes such as the dfs-roots with their real counterpart.
int m_flippedNodes
The whole number of bicomps, which have to be flipped.
bool m_extractSubgraph
Flag for extracting a planar subgraph instead of testing for planarity.
void postProcessEmbedding()
Postprocessing of the graph, so that all virtual vertices are embedded and all bicomps are flipped.
bool internallyActive(node w, int v) const
Checks whether real node w is internally active while embedding node with DFI v.
void printNodeInfo(node v)
Prints informations about node v.
void embedBackedges(const node v, const int v_dir, const node w, const int w_dir)
Links (and embeds iff m_embeddingGrade != EmbeddingGrade::doNotEmbed) backedges from node v with dire...
node walkup(const node v, const node w, const int marker, const edge back)
Walkup: Builds the pertinent subgraph for the backedge back.
void flipBicomp(int c, int marker, NodeArray< int > &visited, bool wholeGraph, bool deleteFlipFlags)
Flips all nodes of the bicomp with unique, real, rootchild c as necessary.
node constActiveSuccessor(node w, int direction, int v, int &info) const
Walks upon external face in the given direction (without changing it) until an active vertex is reach...
bool embed()
Starts the embedding phase, which embeds m_g node by node in descending DFI-order.
Class for the representation of edges.
Definition Graph_d.h:364
Extracts multiple Kuratowski Subdivisions.
This class collects information about Kuratowski Subdivisions which is used for extraction later.
Data type for general directed graphs (adjacency list representation).
Definition Graph_d.h:866
Class for the representation of nodes.
Definition Graph_d.h:241
int degree() const
Returns the degree of the node (indegree + outdegree).
Definition Graph_d.h:284
adjEntry firstAdj() const
Returns the first entry in the adjaceny list.
Definition Graph_d.h:287
Singly linked lists.
Definition SList.h:191
This class is used in the Boyer-Myrvold planarity test for preprocessing purposes.
RegisteredArray for edges of a graph, specialized for EdgeArray<edge>.
Definition Graph_d.h:717
RegisteredArray for nodes, edges and adjEntries of a graph.
Definition Graph_d.h:659
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.
BoyerMyrvoldEdgeType
Type of edge.
@ DfsParallel
parallel DFS-edge
@ BackDeleted
deleted backedge
bool operator>(int lhs, BoyerMyrvoldPlanar::EmbeddingGrade rhs)
bool operator!=(const Tuple2< E1, E2 > &t1, const Tuple2< E1, E2 > &t2)
Inequality operator for 2-tuples.
Definition tuples.h:83
bool operator<=(int lhs, BoyerMyrvoldPlanar::EmbeddingGrade rhs)
bool operator==(const Tuple2< E1, E2 > &t1, const Tuple2< E1, E2 > &t2)
Equality operator for 2-tuples.
Definition tuples.h:77