void print_graph(Graph & G, NodeArray<int> & ind) { int n = G.numberOfNodes(); int m = G.numberOfEdges(); printf("%d %d", n, m); Array<edge> list(m); ind.init(G, 0); node u; int a = 0; forall_nodes(u, G) ind[u] = a++; int i = 0; edge e; forall_edges(e, G) list[i++] = e; EdgeCmp cmp; list.quicksort(cmp); for (i=0; i<m; i++) print_ord(ind[list[i]->source()], ind[list[i]->target()]); printf("\n"); }
/** * Copy the solution (Graph, Tour, Edges, and Headings) into those given. * @note Existing nodes and edges are cleared. */ void DubinsPathPlanner::copySolution(ogdf::Graph &G, ogdf::GraphAttributes &GA, ogdf::List<ogdf::node> &Tour, ogdf::List<ogdf::edge> &Edges, NodeArray<double> &Headings, double &cost) { DPP_ASSERT(m_haveSolution); // Copy the graph and attributes NodeArray<node> nodeCopyTable(m_G); EdgeArray<edge> edgeCopyTable(m_G); int n = copyGraph(m_G, m_GA, G, GA, nodeCopyTable, edgeCopyTable); // Copy the tour ogdf::ListIterator<ogdf::node> tourIter; for ( tourIter = m_Tour.begin(); tourIter != m_Tour.end(); tourIter++ ) { node u = *tourIter; node ucopy = nodeCopyTable(u); Tour.pushBack(ucopy); } // Copy the edge list ogdf::ListIterator<ogdf::edge> edgeIter; for ( edgeIter = m_Edges.begin(); edgeIter != m_Edges.end(); edgeIter++ ) { edge e = *edgeIter; edge ecopy = edgeCopyTable(e); Edges.pushBack(ecopy); } // Copy the headings Headings.init(G); node u; forall_nodes(u,m_G) { node ucopy = nodeCopyTable(u); Headings(ucopy) = m_Headings(u); }
void StressMinimization::minimizeStress( GraphAttributes& GA, NodeArray<NodeArray<double> >& shortestPathMatrix, NodeArray<NodeArray<double> >& weightMatrix) { const Graph& G = GA.constGraph(); int numberOfPerformedIterations = 0; double prevStress = numeric_limits<double>::max(); double curStress = numeric_limits<double>::max(); if (m_terminationCriterion == STRESS) { curStress = calcStress(GA, shortestPathMatrix, weightMatrix); } NodeArray<double> newX; NodeArray<double> newY; NodeArray<double> newZ; if (m_terminationCriterion == POSITION_DIFFERENCE) { newX.init(G); newY.init(G); if (GA.has(GraphAttributes::threeD)) newZ.init(G); } do { if (m_terminationCriterion == POSITION_DIFFERENCE) { if (GA.has(GraphAttributes::threeD)) copyLayout(GA, newX, newY, newZ); else copyLayout(GA, newX, newY); } nextIteration(GA, shortestPathMatrix, weightMatrix); if (m_terminationCriterion == STRESS) { prevStress = curStress; curStress = calcStress(GA, shortestPathMatrix, weightMatrix); } } while (!finished(GA, ++numberOfPerformedIterations, newX, newY, prevStress, curStress)); Logger::slout() << "Iteration count:\t" << numberOfPerformedIterations << "\tStress:\t" << calcStress(GA, shortestPathMatrix, weightMatrix) << endl; }
void Graph::copy(const Graph &G, NodeArray<node> &mapNode, EdgeArray<edge> &mapEdge) { if (G.m_nNodes == 0) return; mapNode.init(G,0); node vG; forall_nodes(vG,G) { node v = mapNode[vG] = pureNewNode(); v->m_indeg = vG->m_indeg; v->m_outdeg = vG->m_outdeg; }
void OptimalRanking::doCall( const Graph& G, NodeArray<int> &rank, EdgeArray<bool> &reversed, const EdgeArray<int> &length, const EdgeArray<int> &costOrig) { MinCostFlowReinelt<int> 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); for(node v : G.nodes) 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); for(edge e : GC.edges) 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) { edge 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); for(edge e : GC.edges) cost[e] = -length[GC.original(e)]; for(node v : GC.nodes) { int s = 0; edge e; 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); for(node v : GC.nodes) rank[GC.original(v)] = dual[v]; } }
void VerticalEdgeLengthCompacter::computeTransitiveHull(const Graph& g, NodeArray<NodeArray<bool> >& transitiveHull){ transitiveHull.init(g); node n; forall_nodes(n, g){ transitiveHull[n].init(g, false); }
T randomOptimalSteiner( int n, EdgeWeightedGraph<T> &graph, List<node> &terminals, NodeArray<bool> &isTerminal, EdgeWeightedGraphCopy<T> &tree ) { OGDF_ASSERT(n >= 0); T result = 0; graph.clear(); terminals.clear(); tree.clear(); tree.createEmpty(graph); isTerminal.init(graph, false); if(n > 0) { node source = graph.newNode(); tree.newNode(source); isTerminal[source] = true; terminals.pushFront(source); if(n > 1) { int numberOfAdditionalNodes = randomNumber(0, n-2); int numberOfNodes = n - numberOfAdditionalNodes; int numberOfEdges = randomNumber(numberOfNodes-1 + numberOfAdditionalNodes*2, (n*(n-1))/2); for(int i = 1; i < numberOfNodes; i++) { node v = graph.chooseNode(); node u = graph.newNode(); tree.newNode(u); edge e = graph.newEdge(v, u, 1); result++; tree.newEdge(e, 1); if(isTerminal[v] && v != source) { isTerminal[v] = false; terminals.del(terminals.search(v)); } isTerminal[u] = true; terminals.pushFront(u); } for(int i = numberOfNodes-1; i < numberOfEdges;) { node v = graph.chooseNode(); node u = graph.chooseNode(); while(u == v) { u = graph.chooseNode(); } if(numberOfAdditionalNodes > 0) { node w = graph.newNode(); graph.newEdge(v, w, n); graph.newEdge(w, u, n); numberOfAdditionalNodes--; i += 2; } else { if(graph.searchEdge(v, u) == NULL && graph.searchEdge(u, v) == NULL) { graph.newEdge(v, u, n); i++; } } } OGDF_ASSERT(graph.numberOfEdges() == numberOfEdges); OGDF_ASSERT(tree.numberOfNodes() == numberOfNodes); OGDF_ASSERT(tree.numberOfEdges() == numberOfNodes - 1); } } OGDF_ASSERT(graph.numberOfNodes() == n); OGDF_ASSERT(isSimpleUndirected(graph)); OGDF_ASSERT(isConnected(graph)); return result; }
void BasicPageRank::call( const Graph& graph, const EdgeArray<double>& edgeWeight, NodeArray<double>& pageRankResult) { const double initialPageRank = 1.0 / (double)graph.numberOfNodes(); const double maxPageRankDeltaBound = initialPageRank * m_threshold; // the two ping pong buffer NodeArray<double> pageRankPing(graph, 0.0); NodeArray<double> pageRankPong(graph, 0.0); NodeArray<double>* pCurrPageRank = &pageRankPing; NodeArray<double>* pNextPageRank = &pageRankPong; NodeArray<double> nodeNorm(graph); for (node v = graph.firstNode(); v; v = v->succ()) { double sum = 0.0; for (adjEntry adj = v->firstAdj(); adj; adj = adj->succ()) { edge e = adj->theEdge(); sum += edgeWeight[e]; } nodeNorm[v] = 1.0 / sum; } pCurrPageRank->init(graph, initialPageRank); // main iteration loop int numIterations = 0; bool converged = false; // check conditions while ( !converged && (numIterations < m_maxNumIterations) ) { // init the result of this iteration pNextPageRank->init(graph, (1.0 - m_dampingFactor) / (double)graph.numberOfNodes()); // calculate the transfer between each node for (edge e = graph.firstEdge(); e; e = e->succ()) { node v = e->source(); node w = e->target(); double vwTransfer = (edgeWeight[e] * nodeNorm[v] * (*pCurrPageRank)[v]); double wvTransfer = (edgeWeight[e] * nodeNorm[w] * (*pCurrPageRank)[w]); (*pNextPageRank)[w] += vwTransfer; (*pNextPageRank)[v] += wvTransfer; } // damping and calculating change double maxPageRankDelta = 0.0; for (node v = graph.firstNode(); v; v = v->succ()) { (*pNextPageRank)[v] *= m_dampingFactor; double pageRankDelta = fabs((*pNextPageRank)[v] - (*pCurrPageRank)[v]); maxPageRankDelta = std::max(maxPageRankDelta, pageRankDelta); } // swap ping and pong, pong ping, ping pong, lalalala std::swap(pNextPageRank, pCurrPageRank); numIterations++; // check if the change is small enough converged = (maxPageRankDelta < maxPageRankDeltaBound); } // normalization double maxPageRank = (*pCurrPageRank)[graph.firstNode()]; double minPageRank = (*pCurrPageRank)[graph.firstNode()]; for (node v = graph.firstNode(); v; v = v->succ()) { maxPageRank = std::max(maxPageRank, (*pCurrPageRank)[v]); minPageRank = std::min(minPageRank, (*pCurrPageRank)[v]); } // init result pageRankResult.init(graph); for (node v = graph.firstNode(); v; v = v->succ()) { double r = ((*pCurrPageRank)[v] - minPageRank) / (maxPageRank - minPageRank); pageRankResult[v] = r; } // result is now between 0 and 1 }