Open
Graph Drawing
Framework

 v.2012.05
 

BoyerMyrvoldPlanar.h
Go to the documentation of this file.
00001 /*
00002  * $Revision: 2299 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2012-05-07 15:57:08 +0200 (Mon, 07 May 2012) $ 
00007  ***************************************************************/
00008  
00044 #ifdef _MSC_VER
00045 #pragma once
00046 #endif
00047 
00048 #ifndef OGDF_BOYER_MYRVOLD_PLANAR_H
00049 #define OGDF_BOYER_MYRVOLD_PLANAR_H
00050 
00051 #include <ogdf/basic/Graph_d.h>
00052 #include <ogdf/basic/NodeArray.h>
00053 #include <ogdf/basic/Stack.h>
00054 #include <ogdf/basic/List.h>
00055 #include <ogdf/basic/SList.h>
00056 
00057 
00058 namespace ogdf {
00059 
00061 enum enumDirection {
00062     CCW=0,
00063     CW=1
00064 };
00065 
00067 
00074 enum enumEdgeType {
00075     EDGE_UNDEFINED=0,
00076     EDGE_SELFLOOP=1,
00077     EDGE_BACK=2,
00078     EDGE_DFS=3,
00079     EDGE_DFS_PARALLEL=4,
00080     EDGE_BACK_DELETED=5
00081 };
00082 
00083 class KuratowskiStructure;
00084 class FindKuratowskis;
00085 
00087 class BoyerMyrvoldPlanar
00088 {
00089     friend class BoyerMyrvold;
00090     friend class BoyerMyrvoldInit;
00091     friend class FindKuratowskis;
00092     friend class ExtractKuratowskis;
00093         
00094 public:
00096     BoyerMyrvoldPlanar(
00097         Graph& g,
00098         bool bundles,
00099         int m_embeddingGrade,
00100         bool limitStructures,
00101         SListPure<KuratowskiStructure>& output,
00102         bool randomDFSTree,
00103         bool avoidE2Minors);
00104 
00106     ~BoyerMyrvoldPlanar() { };
00107     
00109     bool start();
00110     
00112     enum enumEmbeddingGrade {
00113         doNotEmbed=-3, // and not find any kuratowski subdivisions
00114         doNotFind=-2, // but embed
00115         doFindUnlimited=-1, // and embed
00116         doFindZero=0 // and embed
00117     };
00118     
00120 
00126     void flipBicomp(
00127         int c,
00128         int marker,
00129         NodeArray<int>& visited,
00130         bool wholeGraph,
00131         bool deleteFlipFlags);
00132     
00133     // avoid automatic creation of assignment operator
00135     BoyerMyrvoldPlanar &operator=(const BoyerMyrvoldPlanar &);
00136 
00137 protected:
00138     /***** Methods for Walkup and Walkdown ******/
00139     
00141     inline bool pertinent(node w) {
00142         OGDF_ASSERT(w!=NULL);
00143         if (m_dfi[w] <= 0) return false;
00144         return (!m_backedgeFlags[w].empty() || !m_pertinentRoots[w].empty());
00145     }
00146     
00148     inline bool internallyActive(node w, int v) {
00149         OGDF_ASSERT(w!=NULL);
00150         if (m_dfi[w] <= 0) return false;
00151         return (pertinent(w) && !externallyActive(w,v));
00152     }
00153     
00155     inline bool externallyActive(node w, int v) {
00156         OGDF_ASSERT(w!=NULL);
00157         if (m_dfi[w] <= 0) return false;
00158         if (m_leastAncestor[w] < v) return true;
00159         if (m_separatedDFSChildList[w].empty()) return false;
00160         return (m_lowPoint[m_separatedDFSChildList[w].front()] < v);
00161     }
00162     
00164     inline bool inactive(node w, int v) {
00165         OGDF_ASSERT(w!=NULL);
00166         if (m_dfi[w] <= 0) return true;
00167         if (!m_backedgeFlags[w].empty() || !m_pertinentRoots[w].empty()
00168             || m_leastAncestor[w] < v) return false;
00169         if (m_separatedDFSChildList[w].empty()) return true;
00170         return (m_lowPoint[m_separatedDFSChildList[w].front()] >= v);
00171     }
00172     
00174 
00179     inline int infoAboutNode(node w, int v) {
00180         OGDF_ASSERT(w!=NULL);
00181         if (m_dfi[w] <= 0) return 0;
00182         if (!m_pertinentRoots[w].empty() || !m_backedgeFlags[w].empty()) {
00183             // pertinent
00184             if (m_leastAncestor[w] < v) return 2;
00185             if (m_separatedDFSChildList[w].empty()) return 1;
00186             return (m_lowPoint[m_separatedDFSChildList[w].front()] < v
00187                     ? 2 : 1);
00188         } else {
00189             // not pertinent
00190             if (m_leastAncestor[w] < v) return 3;
00191             if (m_separatedDFSChildList[w].empty()) return 0;
00192             return (m_lowPoint[m_separatedDFSChildList[w].front()] < v
00193                     ? 3 : 0);
00194         }
00195     }
00196     
00198 
00203     inline node successorOnExternalFace(node w, int& direction) {
00204         OGDF_ASSERT(w!=NULL);
00205         OGDF_ASSERT(w->degree()>0);
00206         OGDF_ASSERT(m_link[CW][w]!=NULL && m_link[CCW][w]!=NULL);
00207         adjEntry adj = m_link[direction][w];
00208         OGDF_ASSERT(adj->theNode()!=NULL);
00209         
00210         if (w->degree() > 1) direction =
00211                 adj==beforeShortCircuitEdge(adj->theNode(),CCW)->twin();
00212         OGDF_ASSERT(direction || adj==beforeShortCircuitEdge(adj->theNode(),CW)->twin());
00213         return adj->theNode();
00214     }
00215     
00217     inline node successorWithoutShortCircuit(node w, int& direction) {
00218         OGDF_ASSERT(w!=NULL);
00219         OGDF_ASSERT(w->degree()>0);
00220         OGDF_ASSERT(m_link[CW][w]!=NULL && m_link[CCW][w]!=NULL);
00221         adjEntry adj = beforeShortCircuitEdge(w,direction);
00222         OGDF_ASSERT(adj->theNode()!=NULL);
00223         
00224         if (w->degree() > 1) direction =
00225                 adj==beforeShortCircuitEdge(adj->theNode(),CCW)->twin();
00226         OGDF_ASSERT(direction || adj==beforeShortCircuitEdge(adj->theNode(),CW)->twin());
00227         return adj->theNode();
00228     }
00229     
00231 
00233     inline node constSuccessorOnExternalFace(node v, int direction) {
00234         OGDF_ASSERT(v!=NULL);
00235         OGDF_ASSERT(v->degree()>0);
00236         return m_link[direction][v]->theNode();
00237     }
00238     
00240 
00242     inline node constSuccessorWithoutShortCircuit(node v, int direction) {
00243         OGDF_ASSERT(v!=NULL);
00244         OGDF_ASSERT(v->degree()>0);
00245         return beforeShortCircuitEdge(v,direction)->theNode();
00246     }
00247     
00249 
00252     inline adjEntry beforeShortCircuitEdge(node v, int direction) {
00253         OGDF_ASSERT(v!=NULL);
00254         return (m_beforeSCE[direction][v]==NULL) ? m_link[direction][v] : m_beforeSCE[direction][v];
00255     }
00256     
00258 
00260     node activeSuccessor(node w, int& direction, int v, int& info);
00261     
00263 
00265     inline node constActiveSuccessor(node w, int direction, int v, int& info) {
00266         return activeSuccessor(w,direction,v,info);
00267     }
00268     
00270 
00272     inline bool wNodesExist(node root, node stopx, node stopy) {
00273         OGDF_ASSERT(root != stopx && root != stopy && stopx != stopy);
00274         int dir = CCW;
00275         bool between = false;
00276         while (root != NULL) {
00277             root = successorOnExternalFace(root,dir);
00278             if (between && pertinent(root)) {
00279                 return true;
00280             }
00281             if (root == stopx || root == stopy) {
00282                 if (between) {
00283                     return false;
00284                 }
00285                 between = true;
00286             }
00287         }
00288         return false;
00289     }
00290     
00292     inline void printNodeInfo(node v) {
00293         cout << "\nprintNodeInfo(" << m_dfi[v] << "): ";
00294         cout << "CCW=" << m_dfi[constSuccessorOnExternalFace(v,CCW)];
00295         cout << ",CW=" << m_dfi[constSuccessorOnExternalFace(v,CW)];
00296         cout << "\tCCWBefore=" << m_dfi[constSuccessorWithoutShortCircuit(v,CCW)];
00297         cout << ",CWBefore=" << m_dfi[constSuccessorWithoutShortCircuit(v,CW)];
00298         cout << "\tadjList: ";
00299         adjEntry adj;
00300         for (adj = v->firstAdj(); adj; adj = adj->succ()) {
00301             cout << adj->twinNode() << " ";
00302         }
00303     }
00304     
00306 
00308     void mergeBiconnectedComponent(StackPure<int>& stack, const int j);
00309     
00311 
00313     void mergeBiconnectedComponentOnlyPlanar(StackPure<int>& stack, const int j);
00314     
00316 
00318     void embedBackedges(const node v, const int v_dir,
00319                         const node w, const int w_dir, const int i);
00320     
00322 
00324     void embedBackedgesOnlyPlanar(const node v, const int v_dir,
00325                                 const node w, const int w_dir, const int i);
00326     
00328     void createShortCircuitEdge(const node v, const int v_dir,
00329                                 const node w, const int w_dir);
00330     
00332 
00335     node walkup(const node v, const node w, const int marker, const edge back);
00336     
00338 
00343     int walkdown(const int i, const node v, FindKuratowskis* findKuratowskis);
00344     
00346     void mergeUnprocessedNodes();
00347     
00349 
00351     void postProcessEmbedding();
00352     
00354 
00356     bool embed();
00357     
00358     
00359     /***** Members ******/
00361     Graph& m_g;
00362     
00364     const bool m_bundles;
00365     const int m_embeddingGrade;
00366     const bool m_limitStructures;
00367     const bool m_randomDFSTree;
00368     const bool m_avoidE2Minors;
00369     
00371     int m_flippedNodes;
00372     
00373     /***** Members from Boyer Myrvold-Init ******/
00375 
00377     NodeArray<node> m_realVertex;
00378     
00380     NodeArray<int> m_dfi;
00381     
00383     Array<node> m_nodeFromDFI;
00384     
00386 
00388     NodeArray<adjEntry> m_link[2];
00389     
00391 
00395     NodeArray<adjEntry> m_beforeSCE[2];
00396     
00398     NodeArray<adjEntry> m_adjParent;
00399     
00401 
00403     NodeArray<int> m_leastAncestor;
00404     
00406 
00413     EdgeArray<int> m_edgeType;
00414     
00416     NodeArray<int> m_lowPoint;
00417     
00419     NodeArray<int> m_highestSubtreeDFI;
00420     
00422 
00424     NodeArray<ListPure<node> > m_separatedDFSChildList;
00425     
00427 
00429     NodeArray<ListIterator<node> > m_pNodeInParent;
00430     
00431     /***** Members for Walkup and Walkdown ******/
00433     NodeArray<int> m_visited;
00434     
00436     EdgeArray<node> m_pointsToRoot;
00437     
00439 
00441     NodeArray<int> m_visitedWithBackedge;
00442     
00444 
00448     NodeArray<bool> m_flipped;
00449     
00451 
00454     NodeArray<SListPure<adjEntry> > m_backedgeFlags;
00455     
00457     NodeArray<SListPure<node> > m_pertinentRoots;
00458     
00460     SListPure<KuratowskiStructure>& m_output;
00461 };
00462 
00463 
00464 }
00465 
00466 #endif