1 /** \file
2  * \brief Declaration of the class FindKuratowskis
3  *
4  * \author Jens Schmidt
5  *
6  * \par License:
7  * This file is part of the Open Graph Drawing Framework (OGDF).
8  *
9  * \par
10  * Copyright (C)<br>
11  * See README.md in the OGDF root directory for details.
12  *
13  * \par
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * Version 2 or 3 as published by the Free Software Foundation;
17  * see the file LICENSE.txt included in the packaging of this file
18  * for details.
19  *
20  * \par
21  * This program is distributed in the hope that it will be useful,
22  * but WITHOUT ANY WARRANTY; without even the implied warranty of
23  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  * GNU General Public License for more details.
25  *
26  * \par
27  * You should have received a copy of the GNU General Public
28  * License along with this program; if not, see
29  * http://www.gnu.org/copyleft/gpl.html
30  */
31 
32 #pragma once
33 
34 #include <ogdf/planarity/boyer_myrvold/BoyerMyrvoldPlanar.h>
35 
36 
37 namespace ogdf {
38 
39 
40 /**
41  * %List of externally active nodes strictly between x and y for minortypes \a B and \a E
42  *
43  * In case of extracting without bundles, all external paths and lists of their start-
44  * and endnodes are added.
45  */
46 struct ExternE {
47 	node theNode;
48 	SListPure<int> startnodes;
49 	SListPure<node> endnodes;
50 	SListPure<SListPure<edge> > externalPaths;
51 };
52 
53 //! Saves information about a pertinent node w between two stopping vertices.
54 /** In particular links to appropriate highest-XY-Path and z-nodes are maintained
55  */
56 struct WInfo {
57 	node w;
58 
59 	//!  All possible base minortypes on w
60 	enum class MinorType {
61 		A=0x0001, // minor A
62 		B=0x0002, // minor B
63 		C=0x0004, // minor C
64 		D=0x0008, // minor D
65 		E=0x0010  // minor E
66 	};
67 	int minorType;
68 
69 	ArrayBuffer<adjEntry>* highestXYPath;
70 	ArrayBuffer<adjEntry>* zPath;
71 
72 	bool pxAboveStopX;
73 	bool pyAboveStopY;
74 
75 	SListPure<SListPure<edge> > pertinentPaths;
76 
77 	SListIterator<ExternE> externEStart;
78 	SListIterator<ExternE> externEEnd;
79 	node firstExternEAfterW;
80 };
81 
82 inline int operator & (int lhs, WInfo::MinorType rhs) {
83 	return lhs & static_cast<int>(rhs);
84 }
85 
86 inline int operator |= (int& lhs, WInfo::MinorType rhs) {
87 	lhs |= static_cast<int>(rhs);
88 	return lhs;
89 }
90 
91 //! A Kuratowski Structure is a special graph structure containing severals subdivisions
92 class OGDF_EXPORT KuratowskiStructure {
93 	friend class FindKuratowskis;
94 	friend class ExtractKuratowskis;
95 public:
96 	//! Constructor
KuratowskiStructure()97 	KuratowskiStructure() { }
98 	//! Destructor
~KuratowskiStructure()99 	~KuratowskiStructure() { }
100 
101 	//! Copy constructor
KuratowskiStructure(const KuratowskiStructure & orig)102 	KuratowskiStructure(const KuratowskiStructure& orig) {
103 		copy(orig);
104 	}
105 
106 	//! Assignment
107 	KuratowskiStructure& operator=(const KuratowskiStructure& orig) {
108 		copy(orig);
109 		return *this;
110 	}
111 
112 	//! Reset all data members
113 	void clear();
114 
115 	//! The current node to embed
116 	node V;
117 	//! DFI of the current node to embed
118 	int V_DFI;
119 
120 	//! The root of the bicomp containing \p stopX and \p stopY
121 	node R;
122 	//! Real node of virtual node #R.
123 	/** This is redundant, but virtual node will be deleted later on
124 	 */
125 	node RReal;
126 	//! First stopping node
127 	node stopX;
128 	//! Second stopping node
129 	node stopY;
130 
131 protected:
132 	//! Holds information about all pertinent nodes \a w of the bicomp containing \a V
133 	/** Those were not embedded because of the two stopping nodes. In addition,
134 	 * links to the highest-XY-path and the z-nodes of w and the minortype is saved.
135 	 */
136 	SListPure<WInfo> wNodes;
137 
138 	//! The whole highestFacePath of the bicomp containing \a V
139 	/** The construct the highestFacePath, delete all edges of \a V except the two
140 	 * edges on the external face. The highestFacePath is the path starting at the
141 	 * first external edge along the unique face back to \a V.
142 	 */
143 	ArrayBuffer<adjEntry> highestFacePath;
144 
145 	//! The appropriate paths of the highestFacePath for each wNode
146 	SListPure<ArrayBuffer<adjEntry>> highestXYPaths;
147 
148 	//! External face path of bicomp containing \a V in direction CCW
149 	SListPure<adjEntry> externalFacePath;
150 
151 	//! A list of all edges in all externally active paths (bundles only)
152 	SListPure<edge> externalSubgraph;
153 
154 	//! A list of all edges in pertinent paths (bundles only)
155 	SListPure<edge> pertinentSubgraph;
156 
157 	//! A path from the \a zNode in minortype \a D to node \a V for each highest XY-Path
158 	/** zNodes are cut-vertices not contained in the external face path
159 	 */
160 	SListPure<ArrayBuffer<adjEntry>> zPaths;
161 
162 	//! List of externally active nodes strictly between x and y for minortypes \a B and \a E
163 	SListPure<ExternE> externE;
164 
165 	//! List of all virtual startnodes of paths starting at #stopX (only without bundles)
166 	SListPure<int> stopXStartnodes;
167 	//! List of all virtual startnodes of paths starting at #stopY (only without bundles)
168 	SListPure<int> stopYStartnodes;
169 	//! List of all endnodes of paths starting at #stopX (only without bundles)
170 	SListPure<node> stopXEndnodes;
171 	//! List of all endnodes of paths starting at #stopY (only without bundles)
172 	SListPure<node> stopYEndnodes;
173 
174 	//! Copies class
175 	void copy(const KuratowskiStructure& orig);
176 	//! Used in copy constructor
177 	void copyPointer(const KuratowskiStructure& orig, SListPure<WInfo>& list);
178 };
179 
180 //! This class collects information about Kuratowski Subdivisions which is used for extraction later.
181 /** \pre Graph has to be simple.
182  */
183 class FindKuratowskis {
184 public:
185 	//! Constructor
186 	explicit FindKuratowskis(BoyerMyrvoldPlanar* bm);
187 	//! Destructor
~FindKuratowskis()188 	~FindKuratowskis() { }
189 
190 	//! Adds Kuratowski Structure on current node with root \p root and stopping nodes \p stopx and \p stopy
191 	void addKuratowskiStructure(
192 					const node currentNode,
193 					const node root,
194 					const node stopx,
195 					const node stopy);
196 
197 	//! Get-method for the list of all KuratowskiStructures
getAllKuratowskis()198 	inline SListPure<KuratowskiStructure>& getAllKuratowskis() {
199 		return allKuratowskis;
200 	}
201 
202 	//! Constant get-method for the list of all KuratowskiStructures
getAllKuratowskis()203 	inline const SListPure<KuratowskiStructure>& getAllKuratowskis() const {
204 		return allKuratowskis;
205 	}
206 
207 	FindKuratowskis &operator=(const FindKuratowskis &) = delete;
208 
209 protected:
210 	//! Link to class BoyerMyrvoldPlanar
211 	BoyerMyrvoldPlanar* pBM;
212 
213 	//! Input graph
214 	Graph& m_g;
215 
216 	//! The embedding grade
217 	const int& m_embeddingGrade;
218 
219 	//! If true, bundles are extracted, otherwise single paths?
220 	const bool m_bundles;
221 
222 	//! Links appropriate WInfo to node
223 	NodeArray<WInfo*> m_getWInfo;
224 
225 	//! List of all Kuratowski Structures
226 	SListPure<KuratowskiStructure> allKuratowskis;
227 
228 	//! Current Kuratowski Structure
229 	KuratowskiStructure k;
230 
231 	//! Value used as marker for visited nodes etc.
232 	/** Used during computation of the external face path and the highest x-y-path
233 	 */
234 	int m_nodeMarker;
235 	//! Array maintaining visited bits on each node
236 	NodeArray<int> m_wasHere;
237 
238 	//! Link to non-virtual vertex of a virtual Vertex.
239 	/** A virtual vertex has negative DFI of the DFS-Child of related non-virtual Vertex
240 	 */
241 	const NodeArray<node>& m_realVertex;
242 
243 	//! The one and only DFI-NodeArray
244 	const NodeArray<int>& m_dfi;
245 
246 	//! Returns appropriate node from given DFI
247 	const Array<node>& m_nodeFromDFI;
248 
249 	//! Links to opposite adjacency entries on external face in clockwise resp. ccw order
250 	/** m_link[0]=CCW, m_link[1]=CW
251 	 */
252 	const NodeArray<adjEntry>(& m_link)[2];
253 
254 	//! The adjEntry which goes from DFS-parent to current vertex
255 	const NodeArray<adjEntry>& m_adjParent;
256 
257 	//! The DFI of the least ancestor node over all backedges
258 	/** If no backedge exists, the least ancestor is the DFI of that node itself
259 	 */
260 	const NodeArray<int>& m_leastAncestor;
261 
262 	//! Contains the type of each edge
263 	EdgeArray<BoyerMyrvoldEdgeType>& m_edgeType;
264 
265 	//! The lowpoint of each node
266 	NodeArray<int>& m_lowPoint;
267 
268 	//! The highest DFI in a subtree with node as root
269 	const NodeArray<int>& m_highestSubtreeDFI;
270 
271 	//! A list to all separated DFS-children of node
272 	/** The list is sorted by lowpoint values (in linear time)
273 	*/
274 	const NodeArray<ListPure<node> >& m_separatedDFSChildList;
275 
276 	//! Identifies the rootnode of the child bicomp the given backedge points to
277 	const EdgeArray<node>& m_pointsToRoot;
278 
279 	/**
280 	 * Stores for each (virtual) bicomp root how many backedges to its bicomp
281 	 * still have to be embedded. The value is set during the walkup, and it is
282 	 * used and decreased while embedding backedges during the walkdown.
283 	 */
284 	NodeArray<int>& m_numUnembeddedBackedgesInBicomp;
285 
286 	//! Holds information, if node is the source of a backedge.
287 	/** This information refers to the adjEntries on the targetnode
288 	 * and is used during the walkdown
289 	 */
290 	NodeArray<SListPure<adjEntry> >& m_backedgeFlags;
291 
292 	//! List of virtual bicomp roots, that are pertinent to the current embedded node
293 	NodeArray<SListPure<node> >& m_pertinentRoots;
294 
295 	//! Finds root node of the bicomp containing the stopping node \p stopX
296 	node findRoot(node stopX) const;
297 
298 	//! Extracts the highestFace Path of the bicomp containing both stopping nodes
299 	void extractHighestFacePath(ArrayBuffer<adjEntry>& highestFacePath, int marker);
300 
301 	//! Extracts externalFacePath in direction CCW and splits highestFacePath in highestXYPaths
302 	void extractExternalFacePath(
303 				SListPure<adjEntry>& externalFacePath,
304 				const ArrayBuffer<adjEntry>& highestFacePath,
305 				int marker,
306 				int highMarker);
307 
308 	//! Assign pertinent nodes to the different minortypes and extracts inner externalPaths
309 	void splitInMinorTypes(
310 			const SListPure<adjEntry>& externalFacePath,
311 			int marker);
312 
313 	//! Extracts external subgraph from node \p stop to ancestors of node with DFI \p root (without bundles)
314 	void extractExternalSubgraph(
315 			const node stop,
316 			int root,
317 			SListPure<int>& externalStartnodes,
318 			SListPure<node>& externalEndnodes);
319 	//! Extracts external subgraph from node \p stop to ancestors of node with DFI \p root (with bundles)
320 	void extractExternalSubgraphBundles(
321 			const node stop,
322 			int root,
323 			SListPure<edge>& externalSubgraph,
324 			int nodeMarker);
325 
326 	//! Extracts pertinent subgraph from all wNodes to \a V (without bundles)
327 #if 1
328 	void extractPertinentSubgraph(SListPure<WInfo>& W_All);
329 #else
330 	void extractPertinentSubgraph(SListPure<WInfo>& W_All, const node V);
331 #endif
332 
333 	//! Extracts pertinent subgraph from all wNodes to \a V (with bundles)
334 	void extractPertinentSubgraphBundles(
335 			const SListPure<WInfo>& W_All,
336 			const node V,
337 			SListPure<edge>& pertinentSubgraph,
338 			int nodeMarker);
339 };
340 
341 }
342