/* * Embeds all edges in path P' from t1 to t2 and all back-edges with * representant in P' (emb_list). * emb_back_edges_out_w is false only in case of 2 terminal * nodes, for one of the two terminals (see calculate_partial_embedding). * Returns an ordered list of all representants to be embedded later * (see add_old_cnode_to_embedding). * Precondition: * - if u is a node in P' and e is a back-edge with representant u then e is in list * b_edges_repres[u]. */ list<node> PlanarityTestImpl::embedUpwardT(bool embBackEdgesOutW, node t1, node t2, Graph *sG, node w, map<node , list<edge> > &bEdgesRepres, list<node>& traversedNodes, tlp::BmdList<edge>& embList) { list<node> toEmbedLater; node u = t1, predU = NULL_NODE; while (predU != t2) { if (isCNode(u)) { node f = predU, oldCNode = activeCNodeOf(false, u); addOldCNodeToEmbedding(embBackEdgesOutW, sG, w, oldCNode, f, bEdgesRepres, traversedNodes, toEmbedLater, embList); u = parent.get(oldCNode.id); if (u == t2) return toEmbedLater; } else { if (predU != NULL_NODE) { embList.push(edgeReversal( T0EdgeIn.get(predU.id))); if (u != w) embList.push(T0EdgeIn.get(predU.id)); else embList.append(T0EdgeIn.get(predU.id)); } } if (hasBackEdge.get(u.id) && u != t2) embedBackEdges(embBackEdgesOutW, sG, u, traversedNodes, bEdgesRepres[u], embList); predU = u; u = parent.get(u.id); } return toEmbedLater; }
//================================================================= void PlanarityTestImpl::calcNewRBCFromTerminalNode(node newCNode, node n, node n1, node n2, tlp::BmdList<node>& nodeList) { node t = n1; node predT = NULL_NODE; node parentT = NULL_NODE; while (t != n2) { parentT = parent.get(t.id); // cout << "Tulip t = " << t.id << " : "; if (isCNode(t)) { // cout << "Is CNode" << endl; t = activeCNodeOf(false, t); addOldCNodeRBCToNewRBC(t, newCNode, n, predT, NULL_NODE, nodeList); parentT = parent.get(t.id); parent.set(t.id, newCNode); if (labelB.get(t.id) > labelB.get(newCNode.id)) { labelB.set(newCNode.id, labelB.get(t.id)); if (embed) // needed to calculate obstruction edges; nodeLabelB.set(newCNode.id, nodeLabelB.get(t.id)); } } else { // cout << "Not Is CNode :" << t << endl; parent.set(t.id, newCNode); updateLabelB(t); if (labelB.get(t.id) > dfsPosNum.get(n.id)) { BmdLink<node>* item = nodeList.append(t); ptrItem.set(t.id, item) ;//nodeList.append(t)); } if (labelB.get(t.id) > labelB.get(newCNode.id)) { labelB.set(newCNode.id, labelB.get(t.id)); if (embed) // needed to calculate obstruction edges; nodeLabelB.set(newCNode.id, nodeLabelB.get(t.id)); } } if (!isCNode(t)) predT = t; // predT is never a c-node; t = parentT; } }
//================================================================= void PlanarityTestImpl::addOldCNodeRBCToNewRBC(node oldCNode, node, node n, node n1, node n2, tlp::BmdList<node> &nodeList) { // compress RBC[oldCNode]: // removes all nodes v in RBC[oldCNode] s.t. label_b[v] < dfspos_num[n] // or v = parent[oldCNode]. BmdLink<node> *firstItem = RBC[oldCNode].firstItem(); BmdLink<node> *predItem = RBC[oldCNode].cyclicPred(firstItem, nullptr); BmdLink<node> *succItem = RBC[oldCNode].cyclicSucc(firstItem, nullptr); node predNode = predItem->getData(); node succNode = succItem->getData(); node ul; node ur; // goes to the left; while (labelB.get(predNode.id) == dfsPosNum.get(n.id) && predNode != n1 && predNode != n2) { if (!ul.isValid()) ul = predNode; BmdLink<node> *tmp = predItem; predItem = RBC[oldCNode].cyclicPred(predItem, firstItem); predNode = predItem->getData(); RBC[oldCNode].delItem(tmp); } // goes to right; while (labelB.get(succNode.id) == dfsPosNum.get(n.id) && succNode != n1 && succNode != n2) { if (!ur.isValid()) ur = succNode; BmdLink<node> *tmp = succItem; succItem = RBC[oldCNode].cyclicSucc(succItem, firstItem); succNode = succItem->getData(); RBC[oldCNode].delItem(tmp); } RBC[oldCNode].delItem(RBC[oldCNode].firstItem()); // endpoint to correctly concatentates with RBC[new_cnode]; node first = n1; if (!n1.isValid()) { if (ul.isValid()) first = predNode; else first = succNode; } // note that oldCNode may have flipped; if (RBC[oldCNode].lastItem()->getData() == first) RBC[oldCNode].reverse(); // reoves n1 and n2 from RBC[oldCNode]; if (n1.isValid()) { RBC[oldCNode].delItem(RBC[oldCNode].firstItem()); } if (n2.isValid()) { RBC[oldCNode].delItem(RBC[oldCNode].lastItem()); } nodeList.conc(RBC[oldCNode]); }
/* * Embeds all edges in a path from w, starting in a back-edge in listBackEdges * and ending in repr. * Inserts all embedded edges in list embList. * Appends all nodes marked as VISITED in list traversed_nodes. * emb_back_edges_out_w is false only in case of 2 terminal * nodes, for one of the two terminals (see calculate_partial_embedding). */ void PlanarityTestImpl::embedBackEdges(bool embBackEdgesOutW, Graph *sG, node repr, list<node>& traversedNodes, list<edge>& listBackEdges, tlp::BmdList<edge>& embList) { if (listBackEdges.empty()) return; edge e; BmdList<edge> el1, l1, wl1; //node w = target(listBackEdges.contents(listBackEdges.first())); node w = sG->target(listBackEdges.front()); vector<edge> backEdge; int n = sortBackEdgesByDfs(sG, w, repr, listBackEdges, backEdge); for(int i = 1; i <= n; i++) { e = backEdge[i]; if (e != NULL_EDGE) { if (embBackEdgesOutW) wl1.append(edgeReversal( e)); else listBackEdgesOutW.push(edgeReversal( e)); } } for(int i = n; i >= 1; i--) { e = backEdge[i]; if (e != NULL_EDGE) { l1.push(e); node predU = sG->source(e); node u = parent.get(predU.id); while (state.get(predU.id) == NOT_VISITED) { state.set(predU.id, VISITED); traversedNodes.push_back(predU); if (isCNode(u)) { u = activeCNodeOf(false, u); embedList[u].conc(l1); embedList[u].swap(l1); u = parent.get(u.id); } else { l1.push(T0EdgeIn.get(predU.id)); l1.push(edgeReversal( T0EdgeIn.get(predU.id))); } predU = u; u = parent.get(u.id); } el1.conc(l1); } } el1.conc(embList); el1.swap(embList); embList.conc(wl1); }