Graph::~Graph() { ListIterator<NodeArrayBase*> itVNext; for(ListIterator<NodeArrayBase*> itV = m_regNodeArrays.begin(); itV.valid(); itV = itVNext) { itVNext = itV.succ(); (*itV)->disconnect(); } ListIterator<EdgeArrayBase*> itENext; for(ListIterator<EdgeArrayBase*> itE = m_regEdgeArrays.begin(); itE.valid(); itE = itENext) { itENext = itE.succ(); (*itE)->disconnect(); } ListIterator<AdjEntryArrayBase*> itAdjNext; for(ListIterator<AdjEntryArrayBase*> itAdj = m_regAdjArrays.begin(); itAdj.valid(); itAdj = itAdjNext) { itAdjNext = itAdj.succ(); (*itAdj)->disconnect(); } for (node v = m_nodes.begin(); v; v = v->succ()) { v->m_adjEdges.~GraphList<AdjElement>(); } }
List<double> DavidsonHarel::returnEnergyFunctionWeights() { List<double> weights; ListIterator<double> it; for(it = m_weightsOfEnergyFunctions.begin(); it.valid(); it = it.succ()) weights.pushBack(*it); return weights; }
List<string> DavidsonHarel::returnEnergyFunctionNames() { List<string> names; ListIterator<EnergyFunction*> it; for(it = m_energyFunctions.begin(); it.valid(); it = it.succ()) names.pushBack((*it)->getName()); return names; }
//steps through all energy functions and adds the initial energy computed by each //function for the start layout void DavidsonHarel::computeInitialEnergy() { OGDF_ASSERT(!m_energyFunctions.empty()); ListIterator<EnergyFunction*> it; ListIterator<double> it2; it2 = m_weightsOfEnergyFunctions.begin(); for(it = m_energyFunctions.begin(); it.valid() && it2.valid(); it=it.succ(), it2 = it2.succ()) m_energy += (*it)->energy() * (*it2); }
void RadialTreeLayout::Grouping::computeAdd(double &D, double &W) { D = W = 0; ListIterator<Group> it; for(it = begin(); it.valid(); ++it) { Group &g = *it; D += g.m_sumD; if(g.m_leafGroup == true) continue; W += g.m_sumW; ListIterator<Group> itL; itL = it.pred(); if(itL.valid() == false) { g.m_leftAdd = 0.0; } else { ListIterator<Group> itR = itL.pred(); if(itR.valid() == false) g.m_leftAdd = (*itL).m_sumD; else g.m_leftAdd = (*itL).m_sumD * g.m_sumW / (*itR).m_sumW; } itL = it.succ(); if(itL.valid() == false) { g.m_leftAdd = 0.0; } else { ListIterator<Group> itR = itL.succ(); if(itR.valid() == false) g.m_leftAdd = (*itL).m_sumD; else g.m_leftAdd = (*itL).m_sumD * g.m_sumW / (*itR).m_sumW; } } }
void ENGLayer::simplifyAdjacencies(List<LHTreeNode::Adjacency> &adjs) { AdjacencyComparer cmp; if(!adjs.empty()) { adjs.quicksort(cmp); ListIterator<LHTreeNode::Adjacency> it = adjs.begin(); ListIterator<LHTreeNode::Adjacency> itNext = it.succ(); while(itNext.valid()) { if((*it).m_u == (*itNext).m_u && (*it).m_v == (*itNext).m_v) { (*it).m_weight += (*itNext).m_weight; adjs.del(itNext); itNext = it.succ(); } else { it = itNext; ++itNext; } } } }
void UpwardPlanRep::computeSinkSwitches() { OGDF_ASSERT(m_Gamma.externalFace() != nullptr); if (s_hat == nullptr) hasSingleSource(*this, s_hat); FaceSinkGraph fsg(m_Gamma, s_hat); List<adjEntry> dummyList; FaceArray< List<adjEntry> > sinkSwitches(m_Gamma, dummyList); fsg.sinkSwitches(sinkSwitches); m_sinkSwitchOf.init(*this, nullptr); for(face f : m_Gamma.faces) { List<adjEntry> switches = sinkSwitches[f]; ListIterator<adjEntry> it = switches.begin(); for (it = it.succ(); it.valid(); ++it) { m_sinkSwitchOf[(*it)->theNode()] = (*it); } } }
//Connect parts of partial active current CC. //Note that this only makes sense when the CC parts are //already correctly embedded. Crossings are already replaced //by nodes bool PlanRepInc::makeTreeConnected(adjEntry /* adjExternal */) { //we compute node numbers for the partial CCs in order to //identify the treeConnect Edges that can be deleted later m_component.init(*this, -1); //if there is only one CC, we don't need to connect if (isConnected(*this)) return false; //We have to insert edges connnecting nodes lying on //the "external" face of the active parts //First, we activate the CC's parts one by one and compute //the 'external' face from the layout information //If the PlanRepInc is not embedded corresponding to //this layout, we may introduce edges that are non-planar //in the drawing, leading to problems when we compute paths //in the dual graph List<node> isolatedNodes; const int numPartialCC = connectedIsolatedComponents(*this, isolatedNodes, m_component); //CombinatorialEmbedding can cope with unconnected graphs //but does not provide faces for isolated nodes CombinatorialEmbedding E(*this); TopologyModule tm; List<adjEntry> extAdjs; //we run through all faces searching for all outer faces for(face f : E.faces) { //TODO: check if we should select special adjEntry instead of first if (tm.faceSum(*this, *m_pGraphAttributes, f) < 0) extAdjs.pushBack(f->firstAdj()); #ifdef OGDF_DEBUG cout << "FaceSum in Face " << f->index() << " Groesse " << f->size() << " ist: " << tm.faceSum(*this, *m_pGraphAttributes, f) <<"\n" << flush; #endif }//forallfaces //now we have faces for all partial CCs that are not isolated nodes OGDF_ASSERT(extAdjs.size() + isolatedNodes.size() == numPartialCC) //OGDF_ASSERT(extAdjs.size() > 1) //eigentlich: = #partial CCs //OGDF_ASSERT(extAdjs.size() == numPartialCC) const int n1 = numPartialCC-1; m_eTreeArray.init(0, n1, 0, n1, nullptr); m_treeInit = true; //Three cases: only CCs, only isolated nodes, and both (where //only one CC + isolated nodes is possible //now we connect all partial CCs by inserting edges at the adjEntries //in extAdjs and adding all isolated nodes adjEntry lastAdj = nullptr; ListIterator<adjEntry> it = extAdjs.begin(); while(it.valid()) { //for the case: one external face, multiple isolated nodes lastAdj = (*it); adjEntry adj = (*it); ListIterator<adjEntry> it2 = it.succ(); if (it2.valid()) { adjEntry adj2 = (*it2); edge eTree = newEdge(adj, adj2); m_treeEdge[eTree] = true; lastAdj = eTree->adjTarget(); //save the connection edge by CC number index //this is used when deleting obsolete edges later //after edge reinsertion m_eTreeArray(componentNumber(adj->theNode()), componentNumber(adj2->theNode())) = m_eTreeArray(m_component[adj2->theNode()], m_component[adj->theNode()]) = eTree; }//if CCs left to connect ++it; }//while while (!isolatedNodes.empty()) { node uvw = isolatedNodes.popFrontRet(); if (lastAdj) { //same block as above edge eTree = newEdge(uvw, lastAdj); m_treeEdge[eTree] = true; //save the connection edge by CC number index //this is used when deleting obsolete edges later //after edge reinsertion m_eTreeArray(componentNumber(lastAdj->theNode()), componentNumber(uvw)) = m_eTreeArray(m_component[uvw], m_component[lastAdj->theNode()]) = eTree; lastAdj = eTree->adjSource(); } else //connect the first two isolated nodes / only iso nodes exist { //MUST BE #isonodes>1, else we returned already because CC connected OGDF_ASSERT(!isolatedNodes.empty()) node secv = isolatedNodes.popFrontRet(); //same block as above edge eTree = newEdge(uvw, secv); m_treeEdge[eTree] = true; //save the connection edge by CC number index //this is used when deleting obsolete edges later //after edge reinsertion m_eTreeArray(componentNumber(secv), componentNumber(uvw)) = m_eTreeArray(m_component[uvw], m_component[secv]) = eTree; lastAdj = eTree->adjSource(); } }//while isolated nodes OGDF_ASSERT(isConnected(*this)); //List<adjEntry> extAdjs; //getExtAdjs(extAdjs); return true; }//makeStarConnected