bool CconnectClusterPlanar::preProcess(ClusterGraph &C,Graph &G) { if (!isCConnected(C)) { m_errorCode = nonCConnected; return false; } if (!isPlanar(C)) { m_errorCode = nonPlanar; return false; } cluster c; SListPure<node> selfLoops; makeLoopFree(G,selfLoops); c = C.rootCluster(); bool cPlanar = planarityTest(C,c,G); return cPlanar; }
bool CconnectClusterPlanar::preProcess(ClusterGraph &C,Graph &G) { if (!isCConnected(C)) { ogdf::sprintf(errorCode,124,"Graph is not C-connected \n"); m_errorCode = nonCConnected; return false; } PlanarModule Pm; if (!Pm.planarityTest(C)) { ogdf::sprintf(errorCode,124,"Graph is not planar\n"); m_errorCode = nonPlanar; return false; } cluster c; SListPure<node> selfLoops; makeLoopFree(G,selfLoops); c = C.rootCluster(); bool cPlanar = planarityTest(C,c,G); return cPlanar; }
// Recursive call for testing c-planarity of the clustered graph // that is induced by cluster act bool CconnectClusterPlanar::planarityTest(ClusterGraph &C, cluster &act, Graph &G) { // Test children first ListConstIterator<cluster> it; for (it = act->cBegin(); it.valid();) { ListConstIterator<cluster> succ = it.succ(); cluster next = (*it); if (!planarityTest(C,next,G)) return false; it = succ; } // Get induced subgraph of cluster act and test it for planarity List<node> subGraphNodes; ListIterator<node> its; for (its = act->nBegin(); its.valid(); its++) subGraphNodes.pushBack(*its); Graph subGraph; NodeArray<node> table; inducedSubGraph(G,subGraphNodes.begin(),subGraph,table); // Introduce super sink and add edges corresponding // to outgoing edges of the cluster node superSink = subGraph.newNode(); EdgeArray<node> outgoingTable(subGraph,0); for (its = act->nBegin(); its.valid(); its++) { node w = (*its); adjEntry adj = w->firstAdj(); forall_adj(adj,w) { edge e = adj->theEdge(); edge cor = 0; if (table[e->source()] == 0) // edge is connected to a node outside the cluster { cor = subGraph.newEdge(table[e->target()],superSink); outgoingTable[cor] = e->source(); } else if (table[e->target()] == 0) // dito { cor = subGraph.newEdge(table[e->source()],superSink); outgoingTable[cor] = e->target(); } // else edge connects two nodes of the cluster } }
// Recursive call for testing c-planarity of the clustered graph // that is induced by cluster act bool CconnectClusterPlanar::planarityTest( ClusterGraph &C, cluster &act, Graph &G) { // Test children first ListConstIterator<cluster> it; for (it = act->cBegin(); it.valid();) { ListConstIterator<cluster> succ = it.succ(); cluster next = (*it); if (!planarityTest(C,next,G)) return false; it = succ; } // Get induced subgraph of cluster act and test it for planarity List<node> subGraphNodes; for (node s : act->nodes) subGraphNodes.pushBack(s); Graph subGraph; NodeArray<node> table; inducedSubGraph(G,subGraphNodes.begin(),subGraph,table); // Introduce super sink and add edges corresponding // to outgoing edges of the cluster node superSink = subGraph.newNode(); EdgeArray<node> outgoingTable(subGraph,nullptr); for (node w : act->nodes) { //adjEntry adj = w->firstAdj(); for(adjEntry adj : w->adjEntries) { edge e = adj->theEdge(); edge cor = nullptr; if (table[e->source()] == nullptr) // edge is connected to a node outside the cluster { cor = subGraph.newEdge(table[e->target()],superSink); outgoingTable[cor] = e->source(); } else if (table[e->target()] == nullptr) // dito { cor = subGraph.newEdge(table[e->source()],superSink); outgoingTable[cor] = e->target(); } // else edge connects two nodes of the cluster } } if (superSink->degree() == 0) // root cluster is not connected to outside clusters { subGraph.delNode(superSink); superSink = nullptr; } bool cPlanar = preparation(subGraph,act,superSink); if (cPlanar && act != C.rootCluster()) { // Remove induced subgraph and the cluster act. // Replace it by a wheel graph while (!subGraphNodes.empty()) { node w = subGraphNodes.popFrontRet(); // C.unassignNode(w); G.delNode(w); } cluster parent = act->parent(); if (superSink && m_clusterPQTree[act]) constructWheelGraph(C,G,parent,m_clusterPQTree[act],outgoingTable); C.delCluster(act); if (m_clusterPQTree[act] != nullptr) // if query necessary for clusters with just one child { m_clusterPQTree[act]->emptyAllPertinentNodes(); delete m_clusterPQTree[act]; } } else if (!cPlanar) { m_errorCode = nonCPlanar; }//if not cplanar return cPlanar; }