00001
00002
00003
00004
00005
00006
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,
00114 doNotFind=-2,
00115 doFindUnlimited=-1,
00116 doFindZero=0
00117 };
00118
00120
00126 void flipBicomp(
00127 int c,
00128 int marker,
00129 NodeArray<int>& visited,
00130 bool wholeGraph,
00131 bool deleteFlipFlags);
00132
00133
00135 BoyerMyrvoldPlanar &operator=(const BoyerMyrvoldPlanar &);
00136
00137 protected:
00138
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
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
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
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
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
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