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); }
void CombinatorialEmbedding::moveBridge(adjEntry adjBridge, adjEntry adjBefore) { OGDF_ASSERT(m_rightFace[adjBridge] == m_rightFace[adjBridge->twin()]); OGDF_ASSERT(m_rightFace[adjBridge] != m_rightFace[adjBefore]); face fOld = m_rightFace[adjBridge]; face fNew = m_rightFace[adjBefore]; adjEntry adjCand = adjBridge->faceCycleSucc(); int sz = 0; adjEntry adj; for(adj = adjBridge->twin(); adj != adjCand; adj = adj->faceCycleSucc()) { if (fOld->entries.m_adjFirst == adj) fOld->entries.m_adjFirst = adjCand; m_rightFace[adj] = fNew; ++sz; } fOld->m_size -= sz; fNew->m_size += sz; edge e = adjBridge->theEdge(); if(e->source() == adjBridge->twinNode()) m_pGraph->moveSource(e, adjBefore, after); else m_pGraph->moveTarget(e, adjBefore, after); OGDF_ASSERT_IF(dlConsistencyChecks, consistencyCheck()); }
string print_arc_string(adjEntry a) { sprintf(buf, "%d->%d", a->theNode()->index(), a->twinNode()->index()); string res = buf; return res; }
// 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); } }
// computes the leftist canonical order. Requires that G is simple, triconnected and embedded. // adj_v1n is the adjEntry at v_1 looking towards v_n, the outerface is choosen such that v_2 is the cyclic pred // of v_n. the result is saved in result, a list of list of nodes, first set is v_1, v_2, last one is v_n. bool LeftistOrdering::call(const Graph& G, adjEntry adj_v1n, List<List<node> >& result) { // init the is marked array for all adj entries m_marked.init(G, false); // v1 -> v_n edge adjEntry adj_v12 = adj_v1n->cyclicPred(); // the node v_n node v_n = adj_v1n->twinNode(); // init all the node related arrays m_cutFaces.init(G, 0); m_cutEdges.init(G, 0); m_cutFaces[v_n] = 1; // mark v_1 -> v_n m_marked[adj_v12] = true; m_marked[adj_v12->twin()] = true; // initial candidate for the belt Candidate v12_candidate; v12_candidate.chain.pushBack(adj_v12->twin()); // edge 2->1 v12_candidate.chain.pushBack(adj_v12); // edge 1->2 v12_candidate.chain.pushBack(adj_v12->twin()); // edge 2->1 v12_candidate.stopper = nullptr; // init the belt m_belt.pushBack(v12_candidate); // init the candidate variable // we us an iterator here to keep things simple m_currCandidateIt = m_belt.begin(); // while the belt contains some candidates while (!m_belt.empty()) { // the next partition List<node> P_k; // get the next leftmost feasible candidate if (!leftmostFeasibleCandidate(P_k)) return false; // update the belt updateBelt(); // save the result. result.pushBack(P_k); } // thats it we are done return true; }
int EdgeComparerSimple::compare(const adjEntry &e1, const adjEntry &e2) const { // set true if the algorithm should consider the bend-points bool useBends = true; double xP1, xP2, yP1, yP2; DPolyline poly = m_AG->bends(e1->theEdge()); ListIterator<DPoint> it; DPoint pE1, pE2; if ((useBends) && (poly.size() > 2)){ it = poly.begin(); while (it.valid()){ it++; } if (e1->theEdge()->source() == basis){ it = poly.begin(); it++; } else{ it = poly.rbegin(); it--; } pE1 = *it; } else{ pE1.m_x = m_AG->x((e1->twinNode())); pE1.m_y = m_AG->y((e1->twinNode())); } poly = m_AG->bends(e2->theEdge()); if ((useBends) && (poly.size() > 2)){ it = poly.begin(); while (it.valid()){ it++; } if (e2->theEdge()->source() == basis){ it = poly.begin(); it++; } else{ it = poly.rbegin(); it--; } pE2 = *it; } else{ pE2.m_x = m_AG->x((e2->twinNode())); pE2.m_y = m_AG->y((e2->twinNode())); } xP1 = -(m_AG->x(basis)) + (pE1.m_x); yP1 = -(m_AG->y(basis)) + (pE1.m_y); xP2 = -(m_AG->x(basis)) + (pE2.m_x); yP2 = -(m_AG->y(basis)) + (pE2.m_y); if ((yP1 >= 0) && (yP2 < 0)) return 1; if ((yP1 < 0) && (yP2 >= 0)) return -1; if ((yP1 >= 0) && (yP2 >= 0)){ if ((xP1 >= 0) && (xP2 < 0)) return -1; if ((xP1 < 0) && (xP2 >= 0)) return 1; xP1 = xP1 / (sqrt(xP1*xP1 + yP1*yP1)); xP2 = xP2 / (sqrt(xP2*xP2 + yP2*yP2)); if (xP1 > xP2) return -1; else return 1; } if ((yP1 < 0) && (yP2 < 0)){ if ((xP1 >= 0) && (xP2 < 0)) return 1; if ((xP1 < 0) && (xP2 >= 0)) return -1; xP1 = xP1 / (sqrt(xP1*xP1 + yP1*yP1)); xP2 = xP2 / (sqrt(xP2*xP2 + yP2*yP2)); if (xP1 > xP2) return 1; else return -1; } return 0; }
void print_arc(adjEntry a) { printf(" %d->%d", a->theNode()->index(), a->twinNode()->index()); }