// creates a virtual vertex of vertex father and embeds it as // root in the biconnected child component containing of one edge void BoyerMyrvoldInit::createVirtualVertex(const adjEntry father) { // check that adjEntry is valid OGDF_ASSERT(father != nullptr); // create new virtual Vertex and copy properties from non-virtual node const node virt = m_g.newNode(); m_realVertex[virt] = father->theNode(); m_dfi[virt] = -m_dfi[father->twinNode()]; m_nodeFromDFI[m_dfi[virt]] = virt; // set links for traversal of bicomps m_link[CW][virt] = father->twin(); m_link[CCW][virt] = father->twin(); // move edge to new virtual Vertex edge e = father->theEdge(); if (e->source() == father->theNode()) { // e is outgoing edge m_g.moveSource(e,virt); } else { // e is ingoing edge m_g.moveTarget(e,virt); } }
bool FeasibleUpwardPlanarSubgraph::constructMergeGraph( GraphCopy &M, adjEntry adj_orig, const List<edge> &orig_edges) { CombinatorialEmbedding Beta(M); //set ext. face of Beta adjEntry ext_adj = M.copy(adj_orig->theEdge())->adjSource(); Beta.setExternalFace(Beta.rightFace(ext_adj)); FaceSinkGraph fsg(Beta, M.copy(adj_orig->theNode())); SList<node> aug_nodes; SList<edge> aug_edges; SList<face> fList; fsg.possibleExternalFaces(fList); // use this method to call the methode checkForest() node v_ext = fsg.faceNodeOf(Beta.externalFace()); OGDF_ASSERT(v_ext != 0); fsg.stAugmentation(v_ext, M, aug_nodes, aug_edges); //add the deleted edges for(edge eOrig: orig_edges) { node a = M.copy(eOrig->source()); node b = M.copy(eOrig->target()); M.newEdge(a, b); } return (isAcyclic(M)); }
BitonicOrdering::BitonicOrdering(Graph& G, adjEntry adj_st_edge) : m_graph(G) , m_currLabel(0) , m_orderIndex(G,-1) , m_indexToNode(G.numberOfNodes()) , m_tree(G, adj_st_edge->theEdge(), true) { // set all tree nodes to non flipped m_flipped.init(m_tree.tree(), false); // s in the graph node s_G = adj_st_edge->theNode(); node t_G = adj_st_edge->twinNode(); // we label s here manually: set the label m_orderIndex[s_G] = m_currLabel++; // and update the other map m_indexToNode[m_orderIndex[s_G]] = s_G; // label everything else except t handleCase(m_tree.rootNode()); // we label s here manually: set the label m_orderIndex[t_G] = m_currLabel++; // and update the other map m_indexToNode[m_orderIndex[t_G]] = t_G; // finally embedd G m_tree.embed(m_graph); }
string print_arc_string(adjEntry a) { sprintf(buf, "%d->%d", a->theNode()->index(), a->twinNode()->index()); string res = buf; return res; }
void PlanarSPQRTree::setPosInEmbedding( NodeArray<SListPure<adjEntry> > &adjEdges, NodeArray<node> ¤tCopy, NodeArray<adjEntry> &lastAdj, SListPure<node> ¤t, const Skeleton &S, adjEntry adj) { node vT = S.treeNode(); adjEdges[vT].pushBack(adj); node vCopy = adj->theNode(); node vOrig = S.original(vCopy); if(currentCopy[vT] == nullptr) { currentCopy[vT] = vCopy; current.pushBack(vT); for (adjEntry adjVirt : vCopy->adjEdges) { edge eCopy = S.twinEdge(adjVirt->theEdge()); if (eCopy == nullptr) continue; if (adjVirt == adj) { lastAdj[vT] = adj; continue; } const Skeleton &STwin = skeleton(S.twinTreeNode(adjVirt->theEdge())); adjEntry adjCopy = (STwin.original(eCopy->source()) == vOrig) ? eCopy->adjSource() : eCopy->adjTarget(); setPosInEmbedding(adjEdges,currentCopy,lastAdj,current, STwin, adjCopy); } } else if (lastAdj[vT] != nullptr && lastAdj[vT] != adj) { adjEntry adjVirt = lastAdj[vT]; edge eCopy = S.twinEdge(adjVirt->theEdge()); const Skeleton &STwin = skeleton(S.twinTreeNode(adjVirt->theEdge())); adjEntry adjCopy = (STwin.original(eCopy->source()) == vOrig) ? eCopy->adjSource() : eCopy->adjTarget(); setPosInEmbedding(adjEdges,currentCopy,lastAdj,current, STwin, adjCopy); lastAdj[vT] = nullptr; } }
bool FUPSSimple::constructMergeGraph(GraphCopy &M, adjEntry adj_orig, const List<edge> &orig_edges) { CombinatorialEmbedding Beta(M); //set ext. face of Beta adjEntry ext_adj = M.copy(adj_orig->theEdge())->adjSource(); Beta.setExternalFace(Beta.rightFace(ext_adj)); //*************************** debug ******************************** /* cout << endl << "FUPS : " << endl; for(face ff : Beta.faces) { cout << "face " << ff->index() << ": "; adjEntry adjNext = ff->firstAdj(); do { cout << adjNext->theEdge() << "; "; adjNext = adjNext->faceCycleSucc(); } while(adjNext != ff->firstAdj()); cout << endl; } if (Beta.externalFace() != 0) cout << "ext. face of the graph is: " << Beta.externalFace()->index() << endl; else cout << "no ext. face set." << endl; */ FaceSinkGraph fsg(Beta, M.copy(adj_orig->theNode())); SList<node> aug_nodes; SList<edge> aug_edges; SList<face> fList; fsg.possibleExternalFaces(fList); // use this method to call the methode checkForest() node v_ext = fsg.faceNodeOf(Beta.externalFace()); OGDF_ASSERT(v_ext != 0); fsg.stAugmentation(v_ext, M, aug_nodes, aug_edges); /* //------------------------------------debug GraphAttributes AG(M, GraphAttributes::nodeGraphics| GraphAttributes::edgeGraphics| GraphAttributes::nodeColor| GraphAttributes::edgeColor| GraphAttributes::nodeLabel| GraphAttributes::edgeLabel ); // label the nodes with their index for(node v : AG.constGraph().nodes) { AG.label(v) = to_string(v->index()); } AG.writeGML("c:/temp/MergeFUPS.gml"); */ OGDF_ASSERT(isStGraph(M)); //add the deleted edges for(edge eOrig : orig_edges) { node a = M.copy(eOrig->source()); node b = M.copy(eOrig->target()); M.newEdge(a, b); } return (isAcyclic(M)); }
void FPPLayout::computeOrder( const GraphCopy &G, NodeArray<int> &num, NodeArray<adjEntry> &e_wp, NodeArray<adjEntry> &e_wq, adjEntry e_12, adjEntry e_2n, adjEntry e_n1) { NodeArray<int> num_diag(G, 0); // number of chords // link[v] = Iterator in possible, that points to v (if diag[v] = 0 and outer[v] = TRUE) NodeArray<ListIterator<node> > link(G, 0); // outer[v] = TRUE <=> v is a node of the actual outer face NodeArray<bool> outer(G, false); // List of all nodes v with outer[v] = TRUE and diag[v] = 0 List<node> possible; // nodes of the outer triangle (v_1,v_2,v_n) node v_1 = e_12->theNode(); node v_2 = e_2n->theNode(); node v_n = e_n1->theNode(); node v_k, wp, wq, u; adjEntry e, e2; int k; // initialization: beginn with outer face (v_1,v_2,v_n) // v_n is the only possible node num[v_1] = 1; num[v_2] = 2; outer[v_1] = true; outer[v_2] = true; outer[v_n] = true; link[v_n] = possible.pushBack(v_n); e_wq[v_1] = e_n1->twin(); e_wp[v_2] = e_2n; e_wq[v_n] = e_2n->twin(); e_wp[v_n] = e_n1; // select next v_k and delete it for (k = G.numberOfNodes(); k >= 3; k--) { v_k = possible.popFrontRet(); // select arbitrary node from possible as v_k num[v_k] = k; // predecessor wp and successor wq from vk in C_k (actual outer face) wq = (e_wq [v_k])->twinNode(); wp = (e_wp [v_k])->twinNode(); // v_k not in C_k-1 anymore outer[v_k] = false; // shortfall of a chord? if (e_wq[wp]->cyclicSucc()->twinNode() == wq) { // wp, wq is the only successor of vk in G_k // wp, wq loose a chord if (--num_diag[wp] == 0) { link[wp] = possible.pushBack(wp); } if (--num_diag[wq] == 0) { link[wq] = possible.pushBack(wq); } } // update or initialize e_wq, e_wp e_wq[wp] = e_wq[wp]->cyclicSucc(); e_wp[wq] = e_wp[wq]->cyclicPred(); e = e_wq[wp]; for (u = e->twinNode(); u != wq; u = e->twinNode()) { outer[u] = true; e_wp[u] = e->twin(); e = e_wq[u] = e_wp[u]->cyclicSucc()->cyclicSucc(); // search for new chords for (e2 = e_wp[u]->cyclicPred(); e2 != e_wq[u]; e2 = e2->cyclicPred()) { node w = e2->twinNode(); if (outer[w] == true) { ++num_diag[u]; if (w != v_1 && w != v_2) if (++num_diag[w] == 1) possible.del(link[w]); } } if (num_diag[u] == 0) { link[u] = possible.pushBack(u); } } } }
void print_arc(adjEntry a) { printf(" %d->%d", a->theNode()->index(), a->twinNode()->index()); }