void MultiEdgeApproxInserter::Block::initSPQR(int m) { if(m_spqr == 0) { m_spqr = new StaticPlanarSPQRTree(*this,true); m_pathSPQR.init(m); const Graph &tree = m_spqr->tree(); m_tc.init(tree); m_info.init(tree); // compute allocation nodes m_allocNodes.init(*this); node n; forall_nodes(n,tree) { const Skeleton &S = m_spqr->skeleton(n); const Graph &M = S.getGraph(); EdgeArray<int> &tcS = m_tc[n]; tcS.init(M,-1); node x; forall_nodes(x,M) m_allocNodes[S.original(x)].pushBack(n); edge e; forall_edges(e,M) { edge eOrig = S.realEdge(e); if(eOrig != 0) tcS[e] = 1; } }
void FruchtermanReingold :: calculate_exact_repulsive_forces(const Graph &G, NodeArray <NodeAttributes> &A, NodeArray<DPoint>& F_rep) { //naive algorithm by Fruchterman & Reingold mathExtension M; numexcept N; node v,u; DPoint f_rep_u_on_v; DPoint vector_v_minus_u; DPoint pos_u,pos_v; DPoint nullpoint (0,0); double norm_v_minus_u; long node_number = G.numberOfNodes(); Array<node> array_of_the_nodes (node_number+1); long counter = 1; long i,j; double scalar; forall_nodes(v,G) F_rep[v]= nullpoint; forall_nodes(v,G) { array_of_the_nodes[counter]=v; counter++; }
// // destructor: deletes skeleton graphs // StaticSPQRTree::~StaticSPQRTree() { node vT; forall_nodes(vT,m_tree) delete m_sk[vT]; delete m_cpV; }
void ComponentSplitterLayout::call(GraphAttributes &GA) { // Only do preparations and call if layout is valid if (m_secondaryLayout.valid()) { //first we split the graph into its components const Graph& G = GA.constGraph(); NodeArray<int> componentNumber(G); m_numberOfComponents = connectedComponents(G, componentNumber); if (m_numberOfComponents == 0) { return; } //std::vector< std::vector<node> > componentArray; //componentArray.resize(numComponents); //Array<GraphAttributes *> components(numComponents); // // intialize the array of lists of nodes contained in a CC nodesInCC.init(m_numberOfComponents); node v; forall_nodes(v,G) nodesInCC[componentNumber[v]].pushBack(v); // Create copies of the connected components and corresponding // GraphAttributes GraphCopy GC; GC.createEmpty(G); EdgeArray<edge> auxCopy(G); for (int i = 0; i < m_numberOfComponents; i++) { GC.initByNodes(nodesInCC[i],auxCopy); GraphAttributes cGA(GC); //copy information into copy GA forall_nodes(v, GC) { cGA.width(v) = GA.width(GC.original(v)); cGA.height(v) = GA.height(GC.original(v)); cGA.x(v) = GA.x(GC.original(v)); cGA.y(v) = GA.y(GC.original(v)); } m_secondaryLayout.get().call(cGA); //copy layout information back into GA forall_nodes(v, GC) { node w = GC.original(v); if (w != 0) GA.x(w) = cGA.x(v); GA.y(w) = cGA.y(v); } }
void EnergyFunction::printStatus() const{ cout << "\nEnergy function name: " << m_name; cout << "\nCurrent energy: " << m_energy; node v; cout << "\nPosition of nodes in current solution:"; NodeArray<int> num(m_G); int count = 1; forall_nodes(v,m_G) num[v] = count ++; forall_nodes(v,m_G) { cout << "\nNode: " << num[v] << " Position: " << currentPos(v); }
bool Delaunay3D::Invoke() { typedef leda::d3_rat_point point3_t; _simplices.clear(); if(!NB::FirstSelectedMesh()) { NB::LogPrintf("no geometry selected.\n"); return false; } NB::SetOperatorName("Delaunay 3D"); NB::Mesh cloud = NB::FirstSelectedMesh(); COM_assert(cloud); leda::nb::RatPolyMesh& cloudGraph = NB::GetGraph(cloud); leda::list<point3_t> L; leda::node v; forall_nodes(v, cloudGraph) L.push_back(cloudGraph.position_of(v)); leda::list<leda::fork::simplex_t> S; std::cout << "Delaunay3D: calling D3_DELAUNAY ... " << std::flush; // NOTE: include d3_delaunay.cpp when building LEDA leda::fork::D3_DELAUNAY(L, S); std::cout << "DONE" << std::endl; _mesh = NB::CreateMesh(); NB::SetMeshRenderMode(_mesh, NB::RM_ALL); NB::SetMeshPosition(_mesh, NB::GetMeshPosition(cloud)); leda::nb::RatPolyMesh& graph = NB::GetGraph(_mesh); std::cout << "Delaunay3D: creating simplex geometries ... " << std::flush; leda::list_item it; forall_items(it, S) { Simplex simplex; simplex.center = leda::rat_vector::zero(3); leda::rat_vector pos[4]; for(int i = 0; i < 4; ++i) { pos[i] = S[it].verts[i].to_vector(); simplex.center += pos[i]; simplex.verts[i] = graph.new_node(); graph.set_position(simplex.verts[i], pos[i]); } simplex.center /= 4; for(int i = 0; i < 4; ++i) simplex.localPos[i] = pos[i] - simplex.center; AddFace(graph, simplex.verts[0], simplex.verts[1], simplex.verts[2], simplex.verts[3]); _simplices.push_back(simplex); }
// extract and add external subgraph from stopnode to ancestors of the node with dfi root // to edgelist, nodeMarker is used as a visited flag. returns the endnode with lowest dfi. void FindKuratowskis::extractExternalSubgraphBundles( const node stop, int root, SListPure<edge>& externalSubgraph, int nodeMarker) { node v,temp; adjEntry adj; #ifdef OGDF_DEBUG forall_nodes(v,m_g) OGDF_ASSERT(m_wasHere[v]!=nodeMarker); #endif StackPure<node> stack; // stack for dfs-traversal ListConstIterator<node> it; stack.push(stop); while (!stack.empty()) { v = stack.pop(); if (m_wasHere[v]==nodeMarker) continue; // mark visited nodes m_wasHere[v]=nodeMarker; // search for unvisited nodes and add them to stack forall_adj(adj,v) { temp = adj->twinNode(); if (m_edgeType[adj->theEdge()]==EDGE_BACK_DELETED) continue; // go along backedges to ancestor (ignore virtual nodes) if (m_dfi[temp] < root && m_dfi[temp] > 0) { OGDF_ASSERT(m_edgeType[adj->theEdge()]==EDGE_BACK); externalSubgraph.pushBack(adj->theEdge()); } else if (v != stop && m_dfi[temp]>=m_dfi[v]) { // set flag and push unvisited nodes OGDF_ASSERT(m_edgeType[adj->theEdge()]==EDGE_BACK || m_edgeType[adj->theEdge()]==EDGE_DFS || m_edgeType[adj->theEdge()]==EDGE_BACK_DELETED); externalSubgraph.pushBack(adj->theEdge()); if (m_wasHere[temp] != nodeMarker) stack.push(temp); } } // descent to external active child bicomps for (it = m_separatedDFSChildList[v].begin(); it.valid(); ++it) { temp = *it; if (m_lowPoint[temp] >= root) break; stack.push(m_nodeFromDFI[-m_dfi[temp]]); } }
//************************************************************* // call for PlanarizationLayoutUML void SimDrawCaller::callPlanarizationLayout() { m_SD->addAttribute(GraphAttributes::nodeGraphics); m_SD->addAttribute(GraphAttributes::edgeGraphics); // nodes get default size node v; forall_nodes(v, *m_G) m_GA->height(v) = m_GA->width(v) = 5.0; // actual call on PlanarizationLayout PlanarizationLayout PL; PL.callSimDraw(*m_GA); } // end callPlanarizationLayout
//************************************************************* // call for SugiyamaLayout void SimDrawCaller::callSugiyamaLayout() { m_SD->addAttribute(GraphAttributes::nodeGraphics); m_SD->addAttribute(GraphAttributes::edgeGraphics); // nodes get default size node v; forall_nodes(v, *m_G) m_GA->height(v) = m_GA->width(v) = 5.0; // actual call of SugiyamaLayout updateESG(); SugiyamaLayout SL; SL.setSubgraphs(m_esg); // needed to call SimDraw mode SL.call(*m_GA); } // end callSugiyamaLayout
void GraphCopySimple::initGC(const GraphCopySimple &GC, NodeArray<node> &vCopy, EdgeArray<edge> &eCopy) { m_pGraph = GC.m_pGraph; m_vOrig.init(*this,0); m_eOrig.init(*this,0); m_vCopy.init(*m_pGraph,0); m_eCopy.init(*m_pGraph,0); node v; forall_nodes(v,GC) m_vCopy[m_vOrig[vCopy[v]] = GC.m_vOrig[v]] = vCopy[v]; edge e; forall_edges(e,GC) { edge eOrig = GC.m_eOrig[e]; m_eOrig[eCopy[e]] = eOrig; if (eOrig) m_eCopy[eOrig] = eCopy[e]; }
SpringEmbedderFRExact::ArrayGraph::ArrayGraph(GraphAttributes &ga) : m_ga(&ga), m_mapNode(ga.constGraph()) { const Graph &G = ga.constGraph(); m_numNodes = m_numEdges = 0; m_orig = 0; m_src = m_tgt = 0; m_x = m_y = 0; m_nodeWeight = 0; m_useNodeWeight = false; // compute connected components of G NodeArray<int> component(G); m_numCC = connectedComponents(G,component); m_nodesInCC.init(m_numCC); node v; forall_nodes(v,G) m_nodesInCC[component[v]].pushBack(v); }
void SpringEmbedderFR::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); if(G.empty()) return; // all edges straight-line AG.clearAllBends(); GraphCopy GC; GC.createEmpty(G); // compute connected component of G NodeArray<int> component(G); int numCC = connectedComponents(G,component); // intialize the array of lists of nodes contained in a CC Array<List<node> > nodesInCC(numCC); node v; forall_nodes(v,G) nodesInCC[component[v]].pushBack(v); EdgeArray<edge> auxCopy(G); Array<DPoint> boundingBox(numCC); int i; for(i = 0; i < numCC; ++i) { GC.initByNodes(nodesInCC[i],auxCopy); GraphCopyAttributes AGC(GC,AG); node vCopy; forall_nodes(vCopy, GC) { node vOrig = GC.original(vCopy); AGC.x(vCopy) = AG.x(vOrig); AGC.y(vCopy) = AG.y(vOrig); } // original if (initialize(GC, AGC) == true) { for(int i = 1; i <= m_iterations; i++) mainStep(GC, AGC); } cleanup(); // end original node vFirst = GC.firstNode(); double minX = AGC.x(vFirst), maxX = AGC.x(vFirst), minY = AGC.y(vFirst), maxY = AGC.y(vFirst); forall_nodes(vCopy,GC) { node v = GC.original(vCopy); AG.x(v) = AGC.x(vCopy); AG.y(v) = AGC.y(vCopy); if(AG.x(v)-AG.width (v)/2 < minX) minX = AG.x(v)-AG.width(v) /2; if(AG.x(v)+AG.width (v)/2 > maxX) maxX = AG.x(v)+AG.width(v) /2; if(AG.y(v)-AG.height(v)/2 < minY) minY = AG.y(v)-AG.height(v)/2; if(AG.y(v)+AG.height(v)/2 > maxY) maxY = AG.y(v)+AG.height(v)/2; }
void OptimalRanking::doCall( const Graph& G, NodeArray<int> &rank, EdgeArray<bool> &reversed, const EdgeArray<int> &length, const EdgeArray<int> &costOrig) { MinCostFlowReinelt mcf; // construct min-cost flow problem GraphCopy GC; GC.createEmpty(G); // compute connected component of G NodeArray<int> component(G); int numCC = connectedComponents(G,component); // intialize the array of lists of nodes contained in a CC Array<List<node> > nodesInCC(numCC); node v; forall_nodes(v,G) nodesInCC[component[v]].pushBack(v); EdgeArray<edge> auxCopy(G); rank.init(G); for(int i = 0; i < numCC; ++i) { GC.initByNodes(nodesInCC[i], auxCopy); makeLoopFree(GC); edge e; forall_edges(e,GC) if(reversed[GC.original(e)]) GC.reverseEdge(e); // special cases: if(GC.numberOfNodes() == 1) { rank[GC.original(GC.firstNode())] = 0; continue; } else if(GC.numberOfEdges() == 1) { e = GC.original(GC.firstEdge()); rank[e->source()] = 0; rank[e->target()] = length[e]; continue; } EdgeArray<int> lowerBound(GC,0); EdgeArray<int> upperBound(GC,mcf.infinity()); EdgeArray<int> cost(GC); NodeArray<int> supply(GC); forall_edges(e,GC) cost[e] = -length[GC.original(e)]; node v; forall_nodes(v,GC) { int s = 0; forall_adj_edges(e,v) { if(v == e->source()) s += costOrig[GC.original(e)]; else s -= costOrig[GC.original(e)]; } supply[v] = s; } OGDF_ASSERT(isAcyclic(GC) == true); // find min-cost flow EdgeArray<int> flow(GC); NodeArray<int> dual(GC); #ifdef OGDF_DEBUG bool feasible = #endif mcf.call(GC, lowerBound, upperBound, cost, supply, flow, dual); OGDF_ASSERT(feasible); forall_nodes(v,GC) rank[GC.original(v)] = dual[v]; }
void randomTriconnectedGraph(Graph &G, int n, double p1, double p2) { if(n < 4) n = 4; // start with K_4 completeGraph(G,4); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; // Will be used below as array of neighbors of v Array<edge> neighbors(n); // used to mark neighbors // 0 = not marked // 1 = marked left // 2 = marked right // 3 = marked both Array<int> mark(0,n-1,0); for(; i < n; ++i) { // pick a random node v = nodes[randomNumber(0,i-1)]; // create a new node w such that v is split into v and w node w = nodes[i] = G.newNode(); // build array of all neighbors int d = v->degree(); int j = 0; adjEntry adj; forall_adj(adj,v) neighbors[j++] = adj->theEdge(); // mark two distinct neighbors for left for(j = 2; j > 0; ) { int r = randomNumber(0,d-1); if((mark[r] & 1) == 0) { mark[r] |= 1; --j; } } // mark two distinct neighbors for right for(j = 2; j > 0; ) { int r = randomNumber(0,d-1); if((mark[r] & 2) == 0) { mark[r] |= 2; --j; } } for(j = 0; j < d; ++j) { int m = mark[j]; mark[j] = 0; // decide to with which node each neighbor is connected // (possible: v, w, or both) double x = randomDouble(0.0,1.0); switch(m) { case 0: if(x < p1) m = 1; else if(x < p1+p2) m = 2; else m = 3; break; case 1: case 2: if(x >= p1+p2) m = 3; break; } // move edge or create new one if necessary edge e = neighbors[j]; switch(m) { case 2: if(v == e->source()) G.moveSource(e,w); else G.moveTarget(e,w); break; case 3: G.newEdge(w,e->opposite(v)); break; } } G.newEdge(v,w); } }
void planarTriconnectedGraph(Graph &G, int n, double p1, double p2) { if (n < 4) n = 4; // start with K_4 completeGraph(G,4); planarEmbedPlanarGraph(G); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; for(; i < n; ++i) { // pick a random node v = nodes[randomNumber(0,i-1)]; int m = v->degree(); int a1 = randomNumber(0,m-1); int a2 = randomNumber(0,m-2); int j; adjEntry adj1, adj2; for(adj1 = v->firstAdj(), j = 0; j < a1; adj1 = adj1->succ(), ++j) ; for(adj2 = adj1->cyclicSucc(), j = 0; j < a2; adj2 = adj2->cyclicSucc(), ++j) ; adjEntry adj_b1 = adj2->cyclicPred(); adjEntry adj_b2 = adj1->cyclicPred(); nodes[i] = G.splitNode(adj1, adj2); if(adj1 == adj_b1) G.newEdge(adj_b1, adj2->twin()); else if(adj2 == adj_b2) G.newEdge(adj2, adj_b1->twin(), ogdf::before); else { double r = randomDouble(0.0,1.0); if(r <= p1) { int s = randomNumber(0,1); if(s == 0) G.newEdge(adj_b1, adj2->twin()); else G.newEdge(adj2, adj_b1->twin(), ogdf::before); } } double r = randomDouble(0.0,1.0); if(r <= p2) { int s = randomNumber(0,1); if(s == 0) G.newEdge(adj1, adj_b2->twin(), ogdf::before); else G.newEdge(adj_b2, adj1->twin()); } } }
void planarTriconnectedGraph(Graph &G, int n, int m) { if (n < 4) n = 4; if(n % 2) ++n; // need an even number // start with K_4 completeGraph(G,4); planarEmbedPlanarGraph(G); // nodes[0],...,nodes[i-1] is array of all nodes Array<node> nodes(n); node v; int i = 0; forall_nodes(v,G) nodes[i++] = v; // create planar triconnected 3-graph for(; i < n; ) { // pick a random node v = nodes[randomNumber(0,i-1)]; adjEntry adj2 = v->firstAdj(); int r = randomNumber(0,2); switch(r) { case 2: adj2 = adj2->succ(); // fall through to next case case 1: adj2 = adj2->succ(); } adjEntry adj1 = adj2->cyclicSucc(); nodes[i++] = G.splitNode(adj1,adj2); r = randomNumber(0,1); if(r == 0) { adjEntry adj = adj1->twin(); G.newEdge(adj2,adj); nodes[i++] = G.splitNode(adj,adj->cyclicSucc()->cyclicSucc()); } else { adjEntry adj = adj1->cyclicSucc()->twin(); G.newEdge(adj2,adj,ogdf::before); nodes[i++] = G.splitNode(adj->cyclicPred(),adj->cyclicSucc()); } } nodes.init(); Array<edge> edges(m); CombinatorialEmbedding E(G); Array<face> faces(2*n); i = 0; face f; forall_faces(f,E) { if(f->size() >= 4) faces[i++] = f; } while(G.numberOfEdges() < m && i > 0) { int r = randomNumber(0,i-1); f = faces[r]; faces[r] = faces[--i]; int p = randomNumber(0,f->size()-1); int j = 0; adjEntry adj, adj2; for(adj = f->firstAdj(); j < p; adj = adj->faceCycleSucc(), ++j) ; p = randomNumber(2, f->size()-2); for(j = 0, adj2 = adj; j < p; adj2 = adj2->faceCycleSucc(), ++j) ; edge e = E.splitFace(adj,adj2); f = E.rightFace(e->adjSource()); if(f->size() >= 4) faces[i++] = f; f = E.rightFace(e->adjTarget()); if(f->size() >= 4) faces[i++] = f; } }
void GEMLayout::call(GraphAttributes &AG) { const Graph &G = AG.constGraph(); if(G.empty()) return; OGDF_ASSERT(m_numberOfRounds >= 0); OGDF_ASSERT(DIsGreaterEqual(m_minimalTemperature,0)); OGDF_ASSERT(DIsGreaterEqual(m_initialTemperature,m_minimalTemperature)); OGDF_ASSERT(DIsGreaterEqual(m_gravitationalConstant,0)); OGDF_ASSERT(DIsGreaterEqual(m_desiredLength,0)); OGDF_ASSERT(DIsGreaterEqual(m_maximalDisturbance,0)); OGDF_ASSERT(DIsGreaterEqual(m_rotationAngle,0)); OGDF_ASSERT(DIsLessEqual(m_rotationAngle,pi / 2)); OGDF_ASSERT(DIsGreaterEqual(m_oscillationAngle,0)); OGDF_ASSERT(DIsLessEqual(m_oscillationAngle,pi / 2)); OGDF_ASSERT(DIsGreaterEqual(m_rotationSensitivity,0)); OGDF_ASSERT(DIsLessEqual(m_rotationSensitivity,1)); OGDF_ASSERT(DIsGreaterEqual(m_oscillationSensitivity,0)); OGDF_ASSERT(DIsLessEqual(m_oscillationSensitivity,1)); OGDF_ASSERT(m_attractionFormula == 1 || m_attractionFormula == 2); // all edges straight-line AG.clearAllBends(); GraphCopy GC; GC.createEmpty(G); // compute connected component of G NodeArray<int> component(G); int numCC = connectedComponents(G,component); // intialize the array of lists of nodes contained in a CC Array<List<node> > nodesInCC(numCC); node v; forall_nodes(v,G) nodesInCC[component[v]].pushBack(v); EdgeArray<edge> auxCopy(G); Array<DPoint> boundingBox(numCC); int i; for(i = 0; i < numCC; ++i) { GC.initByNodes(nodesInCC[i],auxCopy); GraphCopyAttributes AGC(GC,AG); node vCopy; forall_nodes(vCopy, GC) { node vOrig = GC.original(vCopy); AGC.x(vCopy) = AG.x(vOrig); AGC.y(vCopy) = AG.y(vOrig); } SList<node> permutation; node v; // initialize node data m_impulseX.init(GC,0); m_impulseY.init(GC,0); m_skewGauge.init(GC,0); m_localTemperature.init(GC,m_initialTemperature); // initialize other data m_globalTemperature = m_initialTemperature; m_barycenterX = 0; m_barycenterY = 0; forall_nodes(v,GC) { m_barycenterX += weight(v) * AGC.x(v); m_barycenterY += weight(v) * AGC.y(v); }