void VarEdgeInserterDynCore::ExpandedGraph::findShortestPath(List<adjEntry> &L, Graph::EdgeType eType) { NodeArray<edge> spPred(m_dual, nullptr); // predecessor in shortest path tree List<edge> queue; // candidate edges // start with all edges leaving from m_vS edge e; forall_adj_edges(e, m_vS) queue.pushBack(e); for (;;) { edge eCand = queue.popFrontRet(); // next candidate from front of queue node v = eCand->target(); // hit an unvisited node ? if (spPred[v] == nullptr) { spPred[v] = eCand; // if it is m_vT, we have found the shortest path if (v == m_vT) { // build path from shortest path tree while (v != m_vS) { adjEntry adjExp = m_primalEdge[spPred[v]]; if (adjExp != nullptr) // == nil for first and last edge L.pushFront(m_expToG[adjExp]); v = spPred[v]->source(); } return; } // append next candidates to end of queue appendCandidates(queue, v, eType); } } }
//************************************************************* // checks whether node is a proper dummy node // proper dummy means that node is marked as dummy and // incident edges have at least one common input graph bool SimDraw::isProperDummy(node v) const { if(!isDummy(v)) return false; int sgb = m_GA.subGraphBits(v->firstAdj()->theEdge()); edge e; forall_adj_edges(e, v) sgb &= m_GA.subGraphBits(e); return (sgb != 0); } // end isProperDummy
void VarEdgeInserterDynCore::ExpandedGraph::findWeightedShortestPath(List<adjEntry> &L, Graph::EdgeType eType) { int maxCost = 0; for (edge eDual : m_dual.edges) { int c = costDual(eDual); if (c > maxCost) maxCost = c; } ++maxCost; Array<SListPure<edge> > nodesAtDist(maxCost); NodeArray<edge> spPred(m_dual, nullptr); // predecessor in shortest path tree // start with all edges leaving from m_vS edge e; forall_adj_edges(e, m_vS) nodesAtDist[0].pushBack(e); // actual search (using extended bfs on directed dual) int currentDist = 0; for (;;) { // next candidate edge while (nodesAtDist[currentDist % maxCost].empty()) ++currentDist; edge eCand = nodesAtDist[currentDist % maxCost].popFrontRet(); node v = eCand->target(); // leads to an unvisited node ? if (spPred[v] == nullptr) { // yes, then we set v's predecessor in search tree spPred[v] = eCand; // have we reached t ... if (v == m_vT) { // ... then search is done. // construct list of used edges (translated to crossed // adjacency entries in G) while (v != m_vS) { adjEntry adjExp = m_primalEdge[spPred[v]]; if (adjExp != nullptr) // == nil for first and last edge L.pushFront(m_expToG[adjExp]); v = spPred[v]->source(); } return; } // append next candidates to end of queue appendCandidates(nodesAtDist, maxCost, v, eType, currentDist); } } }
void PlanRep::expand(bool lowDegreeExpand) { for(node v : nodes) { // Replace vertices with high degree by cages and // replace degree 4 vertices with two generalizations // adjacent in the embedding list by a cage. if ((v->degree() > 4) && (typeOf(v) != Graph::dummy) && !lowDegreeExpand) { edge e; //Set the type of the node v. It remains in the graph // as one of the nodes of the expanded face. typeOf(v) = Graph::highDegreeExpander; // Scan the list of edges of v to find the adjacent edges of v // according to the planar embedding. All except one edge // will get a new adjacent node SList<edge> adjEdges; {forall_adj_edges(e,v) adjEdges.pushBack(e); } //The first edge remains at v. remove it from the list. e = adjEdges.popFrontRet(); // Create the list of high degree expanders // We need degree(v)-1 of them to construct a face. // and set expanded Node to v setExpandedNode(v, v); SListPure<node> expander; for (int i = 0; i < v->degree()-1; i++) { node u = newNode(); typeOf(u) = Graph::highDegreeExpander; setExpandedNode(u, v); expander.pushBack(u); } // We move the target node of each ingoing generalization of v to a new // node stored in expander. // Note that, for each such edge e, the target node of the original // edge is then different from the original of the target node of e // (the latter is 0 because u is a new (dummy) node) SListConstIterator<node> itn; NodeArray<adjEntry> ar(*this); itn = expander.begin(); for (edge ei : adjEdges) { // Did we allocate enough dummy nodes? OGDF_ASSERT(itn.valid()); if (ei->source() == v) moveSource(ei,*itn); else moveTarget(ei,*itn); ar[*itn] = (*itn)->firstAdj(); ++itn; } ar[v] = v->firstAdj(); // Now introduce the circular list of new edges // forming the border of the merge face. Keep the embedding. adjEntry adjPrev = v->firstAdj(); // cout <<endl << "INTRODUCING CIRCULAR EDGES" << endl; for (node n : expander) { // cout << adjPrev << " " << (*itn)->firstAdj() << endl; e = Graph::newEdge(adjPrev,n->firstAdj()); setExpansionEdge(e, 2);//can be removed if edgetypes work properly setExpansion(e); setAssociation(e); typeOf(e) = association; //??? if (!expandAdj(v)) expandAdj(v) = e->adjSource(); adjPrev = n->firstAdj(); } e = newEdge(adjPrev,v->lastAdj()); typeOf(e) = association; //??? setExpansionEdge(e, 2);//can be removed if edgetypes work properly setAssociation(e); }//highdegree // Replace all vertices with degree > 2 by cages. else if (v->degree() >= 2 && typeOf(v) != Graph::dummy && lowDegreeExpand) { edge e; //Set the type of the node v. It remains in the graph // as one of the nodes of the expanded face. typeOf(v) = Graph::lowDegreeExpander; //high?? // Scan the list of edges of v to find the adjacent edges of v // according to the planar embedding. All except one edge // will get a new adjacent node SList<edge> adjEdges; {forall_adj_edges(e,v) adjEdges.pushBack(e); } //The first edge remains at v. remove it from the list. // Check if it is a generalization. e = adjEdges.popFrontRet(); // Create the list of high degree expanders // We need degree(v)-1 of them to construct a face. // and set expanded Node to v setExpandedNode(v, v); SListPure<node> expander; for (int i = 0; i < v->degree()-1; i++) { node u = newNode(); typeOf(u) = Graph::highDegreeExpander; setExpandedNode(u, v); expander.pushBack(u); } // We move the target node of each ingoing generalization of v to a new // node stored in expander. // Note that, for each such edge e, the target node of the original // edge is then different from the original of the target node of e // (the latter is 0 because u is a new (dummy) node) NodeArray<adjEntry> ar(*this); SListConstIterator<node> itn = expander.begin(); for (edge ei : adjEdges) { // Did we allocate enough dummy nodes? OGDF_ASSERT(itn.valid()); if (ei->source() == v) moveSource(ei,*itn); else moveTarget(ei,*itn); ar[*itn] = (*itn)->firstAdj(); ++itn; } ar[v] = v->firstAdj(); // Now introduce the circular list of new edges // forming the border of the merge face. Keep the embedding. adjEntry adjPrev = v->firstAdj(); for (node n : expander) { e = newEdge(adjPrev,n->firstAdj()); if (!expandAdj(v)) expandAdj(v) = e->adjSource(); typeOf(e) = association; //??? setExpansionEdge(e, 2); //new types setAssociation(e); //should be dummy type? setExpansion(e); adjPrev = n->firstAdj(); } e = newEdge(adjPrev,v->lastAdj()); typeOf(e) = association; //??? setExpansionEdge(e, 2); } } }//expand