// Add additional edges between nodes and clusters to reflect adjacency hierarchy also // with respect to clusters forall_edges(e, G) { node u = e->source(); node v = e->target(); // e was reversed? if(m_copyEdge[e].front()->source() != m_copy[e->source()]) swap(u,v); if(CG.clusterOf(u) != CG.clusterOf(v)) { cluster c = lca(u, v); cluster cTo, cFrom; if(m_secondPathTo == v) { cTo = m_secondPath; cFrom = m_mark[c]; } else { cFrom = m_secondPath; cTo = m_mark[c]; } // Transfer adjacency relationship to a relationship between clusters // "clusters shall be above each other" edge eH = 0; if(cFrom != c && cTo != c) eH = addEdge(m_bottomNode[cFrom], m_topNode[cTo]); // if this is not possible, try to relax it to a relationship between node and cluster if(eH == 0) { addEdge(m_copy[u], m_topNode[cTo]); addEdge(m_bottomNode[cFrom], m_copy[v]); } } }
forall_edges (e, G) { if (e.source() != e.target()) { edge ec = g.new_edge (partner[e.source()], partner[e.target()]); w[ec] = edge_weight[e]; } }
// tests if two edges cross bool Planarity::intersect(const edge e1, const edge e2) const { node v1s = e1->source(); node v1t = e1->target(); node v2s = e2->source(); node v2t = e2->target(); bool cross = false; if(v1s != v2s && v1s != v2t && v1t != v2s && v1t != v2t) cross = lowLevelIntersect(currentPos(v1s),currentPos(v1t), currentPos(v2s),currentPos(v2t)); return cross; }
edge PlanRep::split(edge e) { bool cageBound = (m_expandedNode[e->source()] && m_expandedNode[e->target()]) && (m_expandedNode[e->source()] == m_expandedNode[e->target()]); node expNode = (cageBound ? m_expandedNode[e->source()] : nullptr); edge eNew = GraphCopy::split(e); m_eType[eNew] = m_eType[e]; m_edgeTypes[eNew] = m_edgeTypes[e]; m_expansionEdge[eNew] = m_expansionEdge[e]; m_expandedNode[eNew->source()] = expNode; return eNew; }
void print_edge(edge e, string delim) { int a = e->source()->index(), b = e->target()->index(), t; if (a > b) SWAP(a, b, t); printf("%s%d %d", delim.c_str(), a, b); }
string print_edge_string(edge e) { int a = e->source()->index(), b = e->target()->index(), t; if (a > b) SWAP(a, b, t); sprintf(buf, "%d %d", a, b); string res = buf; return res; }
bool MultilevelGraph::deleteEdge(NodeMerge * NM, edge theEdge) { int index = theEdge->index(); NM->m_deletedEdges.push_back(index); NM->m_doubleWeight[index] = m_weight[theEdge]; NM->m_source[index] = theEdge->source()->index(); NM->m_target[index] = theEdge->target()->index(); m_G->delEdge(theEdge); m_reverseEdgeIndex[index] = nullptr; return true; }
void VarEdgeInserterDynUMLCore::BCandSPQRtreesUML::insertEdgePath( edge eOrig, const SList<adjEntry>& crossedEdges) { SList<edge> ti; SList<node> tj; for (adjEntry adj : crossedEdges) { ti.pushBack(adj->theEdge()); tj.pushBack(adj->theEdge()->target()); } m_pr.insertEdgePath(eOrig, crossedEdges); Graph::EdgeType typeOfEOrig = m_pr.typeOrig(eOrig); int costOfEOrig = m_costOrig ? eOrig ? (*m_costOrig)[eOrig] : 0 : 1; node v = m_pr.copy(eOrig->source()); SListConstIterator<edge> it = ti.begin(); SListConstIterator<node> jt = tj.begin(); SListConstIterator<adjEntry> kt; for (kt = crossedEdges.begin(); it.valid(); ++it, ++jt, ++kt) { edge e = *it; node u = e->target(); adjEntry a; for (a = u->firstAdj(); a->theEdge()->target() != *jt; a = a->succ()) ; edge f = a->theEdge(); m_dynamicSPQRForest.updateInsertedNode(e, f); e = m_dynamicSPQRForest.rep(e); f = m_dynamicSPQRForest.rep(f); m_typeOf[f] = m_typeOf[e]; m_cost[f] = m_cost[e]; for (a = u->firstAdj(); a->theEdge()->source() != v; a = a->succ()); f = a->theEdge(); m_dynamicSPQRForest.updateInsertedEdge(f); f = m_dynamicSPQRForest.rep(f); m_typeOf[f] = typeOfEOrig; m_cost[f] = costOfEOrig; v = u; } node u = m_pr.copy(eOrig->target()); adjEntry a; for (a = v->firstAdj(); a->theEdge()->target() != u; a = a->succ()) ; edge f = a->theEdge(); m_dynamicSPQRForest.updateInsertedEdge(f); f = m_dynamicSPQRForest.rep(f); m_typeOf[f] = typeOfEOrig; m_cost[f] = costOfEOrig; }
static inline bool writeEdge( std::ostream &out, const int &depth, const GraphAttributes *GA, const edge &e) { GraphIO::indent(out, depth) << e->source() << (GA && !GA->directed() ? " -- " : " -> ") << e->target(); if(GA) { out << " "; writeAttributes(out, *GA, e); } out << "\n"; return true; }
void MultilevelGraph::copyEdgeTo(edge e, MultilevelGraph &MLG, std::map<node, node> &tempNodeAssociations, bool associate, int index) { node source = e->source(); node target = e->target(); edge e_new; if (index == -1) { e_new = MLG.m_G->newEdge(tempNodeAssociations[source], tempNodeAssociations[target]); } else { e_new = MLG.m_G->newEdge(tempNodeAssociations[source], tempNodeAssociations[target], index); } if(associate) { MLG.m_edgeAssociations[e_new] = e->index(); } MLG.m_weight[e_new] = m_weight[e]; }
bool MultilevelGraph::changeEdge(NodeMerge * NM, edge theEdge, double newWeight, node newSource, node newTarget) { int index = theEdge->index(); std::vector<int>::iterator pos = find(NM->m_changedEdges.begin(), NM->m_changedEdges.end(), index); if (pos == NM->m_changedEdges.end()) { NM->m_changedEdges.push_back(index); NM->m_doubleWeight[index] = m_weight[theEdge]; NM->m_source[index] = theEdge->source()->index(); NM->m_target[index] = theEdge->target()->index(); } m_G->delEdge(theEdge); edge newEdge = m_G->newEdge(newSource, newTarget, index); m_reverseEdgeIndex[index] = newEdge; m_weight[newEdge] = newWeight; return true; }
static inline void writeEdge( std::ostream &out, int depth, const GraphAttributes *GA, edge e) { if(GA) { GraphIO::indent(out, depth) << "<edge id=\"" << e->index() << "\""; if(GA->attributes() & GraphAttributes::edgeLabel) { out << " label=\"" << GA->label(e) << "\""; } out << ">\n"; writeAttributes(out, depth + 1, *GA, e); GraphIO::indent(out, depth) << "</edge>\n"; } else { GraphIO::indent(out, depth) << "<edge " << "id=\"" << e->index() << "\" " << "source=\"" << e->source() << "\" " << "target=\"" << e->target() << "\" " << "/>\n"; } }
node DynamicSPQRTree::updateInsertedNode(edge eG, edge fG) { edge eH = m_gEdge_hEdge[eG]; node vT = spqrproper(eH); if (m_tNode_type[vT] == SComp) { DynamicSPQRForest::updateInsertedNode(eG, fG); if (m_sk[vT]) { edge fH = m_gEdge_hEdge[fG]; edge fM = m_skelEdge[fH] = m_sk[vT]->getGraph().split(m_skelEdge[eH]); m_sk[vT]->m_origNode[fM->source()] = fH->source(); m_sk[vT]->m_origEdge[fM] = fH; } } else { DynamicSPQRForest::updateInsertedNode(eG, fG); if (m_sk[vT]) { edge gH = m_hEdge_twinEdge[m_tNode_hEdges[spqrproper(eH)].front()]; edge gM = m_skelEdge[gH] = m_skelEdge[eH]; m_sk[vT]->m_origEdge[gM] = gH; } } return fG->source(); }
void VarEdgeInserterDynCore::insert(edge eOrig, SList<adjEntry>& eip) { eip.clear(); node s = m_pr.copy(eOrig->source()); node t = m_pr.copy(eOrig->target()); // find path from s to t in BC-tree // call of blockInsert() is done when we have found the path // if no path is found, s and t are in different connected components // and thus an empty edge insertion path is correct! DynamicSPQRForest& dSPQRF = m_pBC->dynamicSPQRForest(); SList<node>& path = dSPQRF.findPath(s, t); if (!path.empty()) { SListIterator<node> it = path.begin(); node repS = dSPQRF.repVertex(s, *it); for (SListIterator<node> jt = it; it.valid(); ++it) { node repT = (++jt).valid() ? dSPQRF.cutVertex(*jt, *it) : dSPQRF.repVertex(t, *it); // less than 3 nodes requires no crossings (cannot build SPQR-tree // for a graph with less than 3 nodes!) if (dSPQRF.numberOfNodes(*it) > 3) { List<adjEntry> L; blockInsert(repS, repT, L); // call biconnected case // transform crossed edges to edges in G for (adjEntry kt : L) { edge e = kt->theEdge(); eip.pushBack(e->adjSource() == kt ? dSPQRF.original(e)->adjSource() : dSPQRF.original(e)->adjTarget()); } } if (jt.valid()) repS = dSPQRF.cutVertex(*it, *jt); } } delete &path; }
void SvgPrinter::drawEdge(pugi::xml_node xmlNode, edge e) { // draw arrows if G is directed or if arrow types are defined for the edge bool drawSourceArrow = false; bool drawTargetArrow = false; if (m_attr.has(GraphAttributes::edgeArrow)) { switch (m_attr.arrowType(e)) { case EdgeArrow::Undefined: drawTargetArrow = m_attr.directed(); break; case EdgeArrow::Last: drawTargetArrow = true; break; case EdgeArrow::Both: drawTargetArrow = true; OGDF_CASE_FALLTHROUGH; case EdgeArrow::First: drawSourceArrow = true; break; default: // don't draw any arrows break; } } xmlNode = xmlNode.append_child("g"); bool drawLabel = m_attr.has(GraphAttributes::edgeLabel) && !m_attr.label(e).empty(); pugi::xml_node label; if(drawLabel) { label = xmlNode.append_child("text"); label.append_attribute("text-anchor") = "middle"; label.append_attribute("dominant-baseline") = "middle"; label.append_attribute("font-family") = m_settings.fontFamily().c_str(); label.append_attribute("font-size") = m_settings.fontSize(); label.append_attribute("fill") = m_settings.fontColor().c_str(); label.text() = m_attr.label(e).c_str(); } DPolyline path = m_attr.bends(e); node s = e->source(); node t = e->target(); path.pushFront(DPoint(m_attr.x(s), m_attr.y(s))); path.pushBack(DPoint(m_attr.x(t), m_attr.y(t))); bool drawSegment = false; bool finished = false; List<DPoint> points; for(ListConstIterator<DPoint> it = path.begin(); it.succ().valid() && !finished; it++) { DPoint p1 = *it; DPoint p2 = *(it.succ()); // leaving segment at source node ? if(isCoveredBy(p1, e, s) && !isCoveredBy(p2, e, s)) { if(!drawSegment && drawSourceArrow) { drawArrowHead(xmlNode, p2, p1, s, e); } drawSegment = true; } // entering segment at target node ? if(!isCoveredBy(p1, e, t) && isCoveredBy(p2, e, t)) { finished = true; if(drawTargetArrow) { drawArrowHead(xmlNode, p1, p2, t, e); } } if(drawSegment && drawLabel) { label.append_attribute("x") = (p1.m_x + p2.m_x) / 2; label.append_attribute("y") = (p1.m_y + p2.m_y) / 2; drawLabel = false; } if(drawSegment) { points.pushBack(p1); } if(finished) { points.pushBack(p2); } } if(points.size() < 2) { GraphIO::logger.lout() << "Could not draw edge since nodes are overlapping: " << e << std::endl; } else { drawCurve(xmlNode, e, points); } }
forall_edges(e, G) { pushBackEdge(nodeIndex[e->source()], nodeIndex[e->target()], (float)edgeLength[e]); };
edge DynamicSPQRForest::updateInsertedEdgeSPQR (node vB, edge eG) { node sG = eG->source(); node tG = eG->target(); node sH = repVertex(sG,vB); node tH = repVertex(tG,vB); edge eH = m_H.newEdge(sH,tH); m_gEdge_hEdge[eG] = eH; m_hEdge_gEdge[eH] = eG; adjEntry aH; forall_adj (aH,sH) { edge fH = aH->theEdge(); if (fH==eH) continue; if (fH->opposite(sH)!=tH) continue; node vT = spqrproper(fH); if (m_tNode_type[vT]==PComp) { m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH); m_hEdge_tNode[eH] = vT; return eG; } edge gH = m_hEdge_twinEdge[fH]; if (!gH) { m_bNode_numP[vB]++; node nT = m_T.newNode(); m_tNode_type[nT] = PComp; m_tNode_owner[nT] = nT; edge v1 = m_H.newEdge(sH,tH); edge v2 = m_H.newEdge(sH,tH); m_hEdge_position[v1] = m_tNode_hEdges[vT].insertAfter(v1,m_hEdge_position[fH]); m_tNode_hEdges[vT].del(m_hEdge_position[fH]); m_hEdge_position[v2] = m_tNode_hEdges[nT].pushBack(v2); m_hEdge_position[fH] = m_tNode_hEdges[nT].pushBack(fH); m_hEdge_position[eH] = m_tNode_hEdges[nT].pushBack(eH); m_hEdge_tNode[v1] = vT; m_hEdge_twinEdge[v1] = m_tNode_hRefEdge[nT] = v2; m_hEdge_tNode[v2] = m_hEdge_tNode[eH] = m_hEdge_tNode[fH] = nT; m_hEdge_twinEdge[v2] = v1; return eG; } node wT = spqrproper(gH); if (m_tNode_type[wT]==PComp) { m_hEdge_position[eH] = m_tNode_hEdges[vT].pushBack(eH); m_hEdge_tNode[eH] = vT; } else { m_bNode_numP[vB]++; node nT = m_T.newNode(); m_tNode_type[nT] = PComp; m_tNode_owner[nT] = nT; edge v1 = m_tNode_hRefEdge[vT]; if (!v1) v1 = m_tNode_hRefEdge[wT]; else if (spqrproper(m_hEdge_twinEdge[v1])!=wT) v1 = m_tNode_hRefEdge[wT]; edge v4 = m_hEdge_twinEdge[v1]; edge v2 = m_H.newEdge(v1->source(),v1->target()); edge v3 = m_H.newEdge(v4->source(),v4->target()); m_hEdge_twinEdge[v1] = v2; m_hEdge_twinEdge[v2] = v1; m_hEdge_twinEdge[v3] = v4; m_hEdge_twinEdge[v4] = v3; m_hEdge_position[v2] = m_tNode_hEdges[nT].pushBack(v2); m_hEdge_position[eH] = m_tNode_hEdges[nT].pushBack(eH); m_hEdge_position[v3] = m_tNode_hEdges[nT].pushBack(v3); m_hEdge_tNode[v2] = m_hEdge_tNode[eH] = m_hEdge_tNode[v3] = nT; m_tNode_hRefEdge[nT] = v3; } return eG; }
edge DynamicSPQRTree::updateInsertedEdge(edge eG) { SList<node> marked; node sH = m_gNode_hNode[eG->source()]; node tH = m_gNode_hNode[eG->target()]; for (adjEntry aH : sH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (fH->opposite(sH) == tH) { if (m_tNode_type[vT] == PComp) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge eH = m_gEdge_hEdge[eG]; edge fM = m_skelEdge[fH]; node sM = fM->source(); node tM = fM->target(); if (eH->source() == m_sk[vT]->m_origNode[tM]) { node uM = sM; sM = tM; tM = uM; } m_skelEdge[eH] = m_sk[vT]->getGraph().newEdge(sM, tM); m_sk[vT]->m_origEdge[m_skelEdge[eH]] = eH; } return eG; } else if (!m_hEdge_twinEdge[fH]) { DynamicSPQRForest::updateInsertedEdge(eG); if (m_sk[vT]) { edge gH = m_hEdge_twinEdge[m_tNode_hEdges[m_hEdge_tNode[fH]].front()]; m_skelEdge[gH] = m_skelEdge[fH]; m_sk[vT]->m_origEdge[m_skelEdge[gH]] = gH; } return eG; } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } else { m_tNode_isMarked[vT] = true; marked.pushBack(vT); } } int count = 0; node found[2]; for (adjEntry aH : tH->adjEdges) { edge fH = aH->theEdge(); node vT = spqrproper(fH); if (!m_tNode_isMarked[vT]) continue; found[count++] = vT; m_tNode_isMarked[vT] = false; } while (!marked.empty()) m_tNode_isMarked[marked.popFrontRet()] = false; if (count == 0) { node rT; SList<node>& pT = findPathSPQR(sH, tH, rT); for (node vT : pT) { if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } delete &pT; } else if (count == 1) { node vT = found[0]; if (m_sk[vT]) { delete m_sk[vT]; m_sk[vT] = nullptr; } } return DynamicSPQRForest::updateInsertedEdge(eG); }
forall_edges(e, g){ transitiveHull[e->source()][e->target()] = true; }
void FixEdgeInserterCore::findWeightedShortestPath(const CombinatorialEmbedding &E, edge eOrig, SList<adjEntry> &crossed) { node s = m_pr.copy(eOrig->source()); node t = m_pr.copy(eOrig->target()); OGDF_ASSERT(s != t); int eSubgraph = (m_pSubgraph != nullptr) ? (*m_pSubgraph)[eOrig] : 0; EdgeArray<int> costDual(m_dual, 0); int maxCost = 0; for(edge eDual : m_dual.edges) { int c = getCost(m_primalAdj[eDual]->theEdge(), eSubgraph); costDual[eDual] = c; if (c > maxCost) maxCost = c; } ++maxCost; Array<SListPure<edge> > nodesAtDist(maxCost); NodeArray<edge> spPred(m_dual,nullptr); int oldIdCount = m_dual.maxEdgeIndex(); // augment dual by edges from s to all adjacent faces of s ... for(adjEntry adj : s->adjEdges) { // starting edges of bfs-search are all edges leaving s edge eDual = m_dual.newEdge(m_vS, m_nodeOf[E.rightFace(adj)]); m_primalAdj[eDual] = adj; nodesAtDist[0].pushBack(eDual); } // ... and from all adjacent faces of t to t for(adjEntry adj : t->adjEdges) { edge eDual = m_dual.newEdge(m_nodeOf[E.rightFace(adj)], m_vT); m_primalAdj[eDual] = adj; } // 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. // constructed list of used edges (translated to crossed // adjacency entries in PG) from t back to s (including first // and last!) do { edge eDual = spPred[v]; crossed.pushFront(m_primalAdj[eDual]); v = eDual->source(); } while(v != m_vS); break; } // append next candidate edges to queue (all edges leaving v) appendCandidates(nodesAtDist, costDual, maxCost, v, currentDist); } } // remove augmented edges again adjEntry adj; while ((adj = m_vS->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); while ((adj = m_vT->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); m_dual.resetEdgeIdCount(oldIdCount); }
forall_edges(e, G) { edge eH = addEdge(m_copy[e->source()], m_copy[e->target()], true); m_copyEdge[e].pushBack(eH); m_origEdge[eH] = e; }
void FixEdgeInserterCore::findShortestPath(const CombinatorialEmbedding &E, edge eOrig, SList<adjEntry> &crossed) { node s = m_pr.copy(eOrig->source()); node t = m_pr.copy(eOrig->target()); OGDF_ASSERT(s != t); NodeArray<edge> spPred(m_dual,nullptr); QueuePure<edge> queue; int oldIdCount = m_dual.maxEdgeIndex(); // augment dual by edges from s to all adjacent faces of s ... for(adjEntry adj : s->adjEdges) { // starting edges of bfs-search are all edges leaving s edge eDual = m_dual.newEdge(m_vS, m_nodeOf[E.rightFace(adj)]); m_primalAdj[eDual] = adj; queue.append(eDual); } // ... and from all adjacent faces of t to t for(adjEntry adj : t->adjEdges) { edge eDual = m_dual.newEdge(m_nodeOf[E.rightFace(adj)], m_vT); m_primalAdj[eDual] = adj; } // actual search (using bfs on directed dual) for( ; ;) { // next candidate edge edge eCand = queue.pop(); 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. // constructed list of used edges (translated to crossed // adjacency entries in PG) from t back to s (including first // and last!) do { edge eDual = spPred[v]; crossed.pushFront(m_primalAdj[eDual]); v = eDual->source(); } while(v != m_vS); break; } // append next candidate edges to queue (all edges leaving v) appendCandidates(queue, v); } } // remove augmented edges again adjEntry adj; while ((adj = m_vS->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); while ((adj = m_vT->firstAdj()) != nullptr) m_dual.delEdge(adj->theEdge()); m_dual.resetEdgeIdCount(oldIdCount); }
forall_edges(e, G) { printf("n%d -- n%d [color=%s];\n", e->source()->index(), e->target()->index(), strcol[ecolor[e]].c_str()); }
forall_edges(e, G) { edge e_new = m_G->newEdge(tempAssociations[e->source()], tempAssociations[e->target()]); m_edgeAssociations[e_new] = e->index(); }
forall_edges(e, m_originalGraph) { node source = copiedNodes[e->source()], target = copiedNodes[e->target()]; newEdge(source, target, e); }