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