// Prepares the planarity test and the planar embedding // Parallel edges: do not need to be ignored, they can be handled // by the planarity test. // Selfloops: need to be ignored. bool PlanarModule::preparation(Graph &G,bool embed) { if (G.numberOfEdges() < 9 && !embed) return true; else if (G.numberOfEdges() < 3 && embed) return true; node v; edge e; SListPure<node> selfLoops; makeLoopFree(G,selfLoops); prepareParallelEdges(G); int isolated = 0; forall_nodes(v,G) if (v->degree() == 0) isolated++; if (((G.numberOfNodes()-isolated) > 2) && ((3*(G.numberOfNodes()-isolated) -6) < (G.numberOfEdges() - m_parallelCount))) return false; bool planar = true; NodeArray<node> tableNodes(G,0); EdgeArray<edge> tableEdges(G,0); NodeArray<bool> mark(G,0); EdgeArray<int> componentID(G); // Determine Biconnected Components int bcCount = biconnectedComponents(G,componentID); // Determine edges per biconnected component Array<SList<edge> > blockEdges(0,bcCount-1); forall_edges(e,G) { blockEdges[componentID[e]].pushFront(e); }
// // Prepare planarity test for one cluster // bool CconnectClusterPlanar::preparation( Graph &G, cluster &cl, node superSink) { int bcIdSuperSink = -1; // ID of biconnected component that contains superSink // Initialization with -1 necessary for assertion bool cPlanar = true; NodeArray<node> tableNodes(G, nullptr); EdgeArray<edge> tableEdges(G, nullptr); NodeArray<bool> mark(G, 0); EdgeArray<int> componentID(G); // Determine Biconnected Components int bcCount = biconnectedComponents(G, componentID); // Determine edges per biconnected component Array<SList<edge> > blockEdges(0, bcCount - 1); for (edge e : G.edges) { blockEdges[componentID[e]].pushFront(e); } // Determine nodes per biconnected component. Array<SList<node> > blockNodes(0, bcCount - 1); for (int i = 0; i < bcCount; i++) { for (edge e : blockEdges[i]) { if (!mark[e->source()]) { blockNodes[i].pushBack(e->source()); mark[e->source()] = true; } if (!mark[e->target()]) { blockNodes[i].pushBack(e->target()); mark[e->target()] = true; } } if (superSink && mark[superSink]) { OGDF_ASSERT(bcIdSuperSink == -1); bcIdSuperSink = i; } for (node v : blockNodes[i]) { if (mark[v]) mark[v] = false; else { OGDF_ASSERT(mark[v]); // v has been placed two times on the list. } } } // Perform planarity test for every biconnected component if (bcCount == 1) { // Compute st-numbering NodeArray<int> numbering(G,0); #ifdef OGDF_DEBUG int n = #endif (superSink) ? stNumber(G,numbering,nullptr,superSink) : stNumber(G,numbering); OGDF_ASSERT_IF(dlConsistencyChecks,testSTnumber(G,numbering,n)) EdgeArray<edge> backTableEdges(G,nullptr); for(edge e : G.edges) backTableEdges[e] = e; cPlanar = doTest(G,numbering,cl,superSink,backTableEdges); } else { for (int i = 0; i < bcCount; i++) { #ifdef OGDF_DEBUG if(int(ogdf::debugLevel)>=int(dlHeavyChecks)){ cout<<endl<<endl<<"-----------------------------------"; cout<<endl<<endl<<"Component "<<i<<endl;} #endif Graph C; for (node v : blockNodes[i]) { node w = C.newNode(); tableNodes[v] = w; #ifdef OGDF_DEBUG if (int(ogdf::debugLevel) >= int(dlHeavyChecks)){ cout << "Original: " << v << " New: " << w << endl; } #endif } NodeArray<node> backTableNodes(C,nullptr); for (edge e : blockEdges[i]) { edge f = C.newEdge(tableNodes[e->source()],tableNodes[e->target()]); tableEdges[e] = f; } EdgeArray<edge> backTableEdges(C,nullptr); for (edge e : blockEdges[i]) backTableEdges[tableEdges[e]] = e; // Compute st-numbering NodeArray<int> numbering(C,0); if (bcIdSuperSink == i) { #ifdef OGDF_DEBUG int n = #endif stNumber(C,numbering,nullptr,tableNodes[superSink]); OGDF_ASSERT_IF(dlConsistencyChecks,testSTnumber(C,numbering,n)) cPlanar = doTest(C,numbering,cl,tableNodes[superSink],backTableEdges); } else { #ifdef OGDF_DEBUG int n = #endif stNumber(C,numbering); OGDF_ASSERT_IF(dlConsistencyChecks,testSTnumber(C,numbering,n)) cPlanar = doTest(C,numbering,cl,nullptr,backTableEdges); } if (!cPlanar) break; } } return cPlanar; }