6 * $Date: 2012-07-12 01:02:21 +0200 (Do, 12. Jul 2012) $
7 ***************************************************************/
10 * \brief Declaration of the class ExtractKuratowskis
12 * \author Jens Schmidt
16 * This file is part of the Open Graph Drawing Framework (OGDF).
20 * See README.txt in the root directory of the OGDF installation for details.
23 * This program is free software; you can redistribute it and/or
24 * modify it under the terms of the GNU General Public License
25 * Version 2 or 3 as published by the Free Software Foundation;
26 * see the file LICENSE.txt included in the packaging of this file
30 * This program is distributed in the hope that it will be useful,
31 * but WITHOUT ANY WARRANTY; without even the implied warranty of
32 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33 * GNU General Public License for more details.
36 * You should have received a copy of the GNU General Public
37 * License along with this program; if not, write to the Free
38 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
39 * Boston, MA 02110-1301, USA.
41 * \see http://www.gnu.org/copyleft/gpl.html
42 ***************************************************************/
49 #ifndef OGDF_EXTRACT_KURATOWSKIS_H
50 #define OGDF_EXTRACT_KURATOWSKIS_H
52 #include <ogdf/internal/planarity/BoyerMyrvoldPlanar.h>
53 #include <ogdf/internal/planarity/FindKuratowskis.h>
54 #include <ogdf/basic/Stack.h>
59 //! Extracts all possible paths with backtracking using given edges and special constraints
60 class OGDF_EXPORT DynamicBacktrack
{
65 const NodeArray
<int>& dfi
,
66 const EdgeArray
<int>& flags
)
72 //! Reinitializes backtracking with new constraints. All paths will be traversed again.
73 /** Startedges are either only \a startInclude or not \a startExclude, all startedges
74 * have to contain the flag \a startFlag, if \a startFlag != 0. The \a start- and \a endnode
75 * of extracted paths is given, too.
83 const edge startInclude
,
84 const edge startExlude
);
86 //! Returns next possible path from \a start- to \a endnode, if exists.
87 /** The path is returned to \a list. After that a process image is made,
88 * allowing to pause backtracking and extracting further paths later.
89 * \a Endnode returns the last traversed node.
91 bool addNextPath(SListPure
<edge
>& list
, node
& endnode
);
93 //! Returns next possible path under constraints from \a start- to \a endnode, if exists.
94 /** All paths avoid \a exclude-edges, except if on an edge with flag \a exceptOnEdge.
95 * The NodeArray \a nodeflags is used to mark visited nodes. Only that part of the path,
96 * which doesn't contain \a exclude-edges is finally added.
97 * The path is returned to \a list. After that a process image is made,
98 * allowing to pause backtracking and extracting further paths later.
99 * \a Endnode returns the last traversed node.
101 bool addNextPathExclude(SListPure
<edge
>& list
,
103 const NodeArray
<int>& nodeflags
,
107 // avoid automatic creation of assignment operator
108 //! Assignment is not defined!
109 DynamicBacktrack
&operator=(const DynamicBacktrack
&);
111 //! Marks an edge with three Flags: externalPath, pertinentPath and/or singlePath
112 enum enumKuratowskiFlag
{
113 externalPath
= 0x00001, // external paths, e.g. stopX->Ancestor
114 pertinentPath
= 0x00002, // pertinent paths, e.g. wNode->V
115 singlePath
= 0x00004, // marker for one single path
119 //! Flags, that partition the edges into pertinent and external subgraphs
120 const EdgeArray
<int>& m_flags
;
121 //! The one and only DFI-NodeArray
122 const NodeArray
<int>& m_dfi
;
124 //! Start node of backtracking
126 //! Identifies endnodes
128 //! Iff true, DFI of endnodes has to be < \a DFI[end], otherwise the only valid endnode is \a end
130 //! Every traversed edge has to be signed with this flag
133 //! Saves the parent edge for each node in path
134 NodeArray
<adjEntry
> m_parent
;
136 //! Backtracking stack. A NULL-element indicates a return from a child node
137 StackPure
<adjEntry
> stack
;
140 //! Wrapper-class for Kuratowski Subdivisions containing the minortype and edgelist
141 class OGDF_EXPORT KuratowskiWrapper
{
144 KuratowskiWrapper() { }
146 //! Returns true, iff subdivision is a K3,3-minor
147 inline bool isK33() const { return subdivisionType
!= E5
; }
148 //! Returns true, iff subdivision is a K5-minor
149 inline bool isK5() const { return subdivisionType
== E5
; }
151 //! Possible minortypes of a Kuratowski Subdivision
152 enum enumSubdivisionType
{
170 //! Minortype of the Kuratowski Subdivision
173 //! The node which was embedded while the Kuratowski Subdivision was found
176 //! Contains the edges of the Kuratowski Subdivision
177 SListPure
<edge
> edgeList
;
180 //! Extracts multiple Kuratowski Subdivisions
181 /** \pre Graph has to be simple.
183 class ExtractKuratowskis
{
186 ExtractKuratowskis(BoyerMyrvoldPlanar
& bm
);
188 ~ExtractKuratowskis() { }
190 //! Extracts all Kuratowski Subdivisions and adds them to \a output (without bundles)
192 const SListPure
<KuratowskiStructure
>& allKuratowskis
,
193 SList
<KuratowskiWrapper
>& output
);
195 //! Extracts all Kuratowski Subdivisions and adds them to \a output (with bundles)
197 const SListPure
<KuratowskiStructure
>& allKuratowskis
,
198 SList
<KuratowskiWrapper
>& output
);
200 //! Enumeration over Kuratowski Type none, K33, K5
201 enum enumKuratowskiType
{
202 none
= 0, //!< no kuratowski subdivision exists
203 K33
= 1, //!< a K3,3 subdivision exists
204 K5
= 2 //!< a K5 subdivision exists
207 //! Checks, if \a list forms a valid Kuratowski Subdivision and returns the type
209 * @return Returns the following value:
210 * - none = no Kuratowski
214 static int whichKuratowski(
216 const NodeArray
<int>& dfi
,
217 const SListPure
<edge
>& list
);
219 //! Checks, if edges in Array \a edgenumber form a valid Kuratowski Subdivision and returns the type
221 * \pre The numer of edges has to be 1 for used edges, otherwise 0.
222 * @return Returns the following value:
223 * - none = no Kuratowski
227 static int whichKuratowskiArray(
229 //const NodeArray<int>& m_dfi,
230 EdgeArray
<int>& edgenumber
);
232 //! Returns true, iff the Kuratowski is not already contained in output
233 static bool isANewKuratowski(
235 const SListPure
<edge
>& kuratowski
,
236 const SList
<KuratowskiWrapper
>& output
);
237 //! Returns true, iff the Kuratowski is not already contained in output
238 /** \pre Kuratowski Edges are all edges != 0 in the Array.
240 static bool isANewKuratowski(
242 const EdgeArray
<int>& test
,
243 const SList
<KuratowskiWrapper
>& output
);
245 // avoid automatic creation of assignment operator
246 //! Assignment operator is undefined!
247 ExtractKuratowskis
&operator=(const ExtractKuratowskis
&);
250 //! Link to class BoyerMyrvoldPlanar
251 BoyerMyrvoldPlanar
& BMP
;
256 //! Some parameters, see BoyerMyrvold for further instructions
257 int m_embeddingGrade
;
258 //! Some parameters, see BoyerMyrvold for further instructions
259 const bool m_avoidE2Minors
;
261 //! Value used as marker for visited nodes etc.
262 /** Used during Backtracking and the extraction of some specific minortypes
265 //! Array maintaining visited bits on each node
266 NodeArray
<int> m_wasHere
;
268 //! The one and only DFI-NodeArray
269 const NodeArray
<int>& m_dfi
;
271 //! Returns appropriate node from given DFI
272 const Array
<node
>& m_nodeFromDFI
;
274 //! The adjEntry which goes from DFS-parent to current vertex
275 const NodeArray
<adjEntry
>& m_adjParent
;
277 //! Adds external face edges to \a list
278 inline void addExternalFacePath(
279 SListPure
<edge
>& list
,
280 const SListPure
<adjEntry
>& externPath
) {
281 SListConstIterator
<adjEntry
> itExtern
;
282 for (itExtern
= externPath
.begin(); itExtern
.valid(); ++itExtern
) {
283 list
.pushBack((*itExtern
)->theEdge());
287 //! Returns \a adjEntry of the edge between node \a high and a special node
288 /** The special node is that node with the lowest DFI not less than the DFI of \a low.
290 inline adjEntry
adjToLowestNodeBelow(node high
, int low
);
292 //! Adds DFS-path from node \a bottom to node \a top to \a list
293 /** \pre Each virtual node has to be merged.
295 inline void addDFSPath(SListPure
<edge
>& list
, node bottom
, node top
);
296 //! Adds DFS-path from node \a top to node \a bottom to \a list
297 /** \pre Each virtual node has to be merged.
299 inline void addDFSPathReverse(SListPure
<edge
>& list
, node bottom
, node top
);
301 //! Separates \a list1 from edges already contained in \a list2
302 inline void truncateEdgelist(SListPure
<edge
>& list1
, const SListPure
<edge
>& list2
);
304 //! Extracts minortype A and adds it to list \a output
306 SList
<KuratowskiWrapper
>& output
,
307 const KuratowskiStructure
& k
,
309 const SListPure
<edge
>& pathX
,
311 const SListPure
<edge
>& pathY
,
313 const SListPure
<edge
>& pathW
);
314 //! Extracts minortype B and adds it to list \a output (no bundles)
316 SList
<KuratowskiWrapper
>& output
,
317 //NodeArray<int>& nodeflags,
318 //const int nodemarker,
319 const KuratowskiStructure
& k
,
321 const SListPure
<edge
>& pathX
,
323 const SListPure
<edge
>& pathY
,
325 const SListPure
<edge
>& pathW
);
326 //! Extracts minortype B and adds it to list \a output (with bundles)
327 void extractMinorBBundles(
328 SList
<KuratowskiWrapper
>& output
,
329 NodeArray
<int>& nodeflags
,
330 const int nodemarker
,
331 const KuratowskiStructure
& k
,
332 EdgeArray
<int>& flags
,
334 const SListPure
<edge
>& pathX
,
336 const SListPure
<edge
>& pathY
,
338 const SListPure
<edge
>& pathW
);
339 //! Extracts minortype C and adds it to list \a output
341 SList
<KuratowskiWrapper
>& output
,
342 const KuratowskiStructure
& k
,
344 const SListPure
<edge
>& pathX
,
346 const SListPure
<edge
>& pathY
,
348 const SListPure
<edge
>& pathW
);
349 //! Extracts minortype D and adds it to list \a output
351 SList
<KuratowskiWrapper
>& output
,
352 const KuratowskiStructure
& k
,
354 const SListPure
<edge
>& pathX
,
356 const SListPure
<edge
>& pathY
,
358 const SListPure
<edge
>& pathW
);
359 //! Extracts minortype E and adds it to list \a output (no bundles)
361 SList
<KuratowskiWrapper
>& output
,
365 bool firstWOnHighestXY
,
366 const KuratowskiStructure
& k
,
368 const SListPure
<edge
>& pathX
,
370 const SListPure
<edge
>& pathY
,
372 const SListPure
<edge
>& pathW
);
373 //! Extracts minortype E and adds it to list \a output (bundles)
374 void extractMinorEBundles(
375 SList
<KuratowskiWrapper
>& output
,
379 bool firstWOnHighestXY
,
380 NodeArray
<int>& nodeflags
,
381 const int nodemarker
,
382 const KuratowskiStructure
& k
,
383 EdgeArray
<int>& flags
,
385 const SListPure
<edge
>& pathX
,
387 const SListPure
<edge
>& pathY
,
389 const SListPure
<edge
>& pathW
);
390 //! Extracts minorsubtype E1 and adds it to list \a output
392 SList
<KuratowskiWrapper
>& output
,
397 const KuratowskiStructure
& k
,
399 const SListPure
<edge
>& pathX
,
401 const SListPure
<edge
>& pathY
,
403 const SListPure
<edge
>& pathW
,
404 const SListPure
<edge
>& pathZ
,
405 const node endnodeZ
);
406 //! Extracts minorsubtype E2 and adds it to list \a output
408 SList
<KuratowskiWrapper
>& output
,
413 const KuratowskiStructure
& k
,
415 const SListPure
<edge
>& pathX
,
417 const SListPure
<edge
>& pathY
,
419 //const SListPure<edge>& pathW,
420 const SListPure
<edge
>& pathZ
/*,
421 const node endnodeZ*/);
422 //! Extracts minorsubtype E3 and adds it to list \a output
424 SList
<KuratowskiWrapper
>& output
,
429 const KuratowskiStructure
& k
,
431 const SListPure
<edge
>& pathX
,
433 const SListPure
<edge
>& pathY
,
435 const SListPure
<edge
>& pathW
,
436 const SListPure
<edge
>& pathZ
,
437 const node endnodeZ
);
438 //! Extracts minorsubtype E4 and adds it to list \a output
440 SList
<KuratowskiWrapper
>& output
,
445 const KuratowskiStructure
& k
,
447 const SListPure
<edge
>& pathX
,
449 const SListPure
<edge
>& pathY
,
451 const SListPure
<edge
>& pathW
,
452 const SListPure
<edge
>& pathZ
,
453 const node endnodeZ
);
454 //! Extracts minorsubtype E5 and adds it to list \a output
456 SList
<KuratowskiWrapper
>& output
,
461 const KuratowskiStructure
& k
,
463 const SListPure
<edge
>& pathX
,
465 const SListPure
<edge
>& pathY
,
467 const SListPure
<edge
>& pathW
,
468 const SListPure
<edge
>& pathZ
,
469 const node endnodeZ
);