void randomHierarchy( Graph &G, int numberOfNodes, int numberOfEdges, bool planar, bool singleSource, bool longEdges) { G.clear(); Array<node> nnr (3*numberOfNodes); Array<int> vrt (3*numberOfNodes); Array<int> fst (numberOfNodes+1); /** Place nodes **/ for(int i = 0; i < numberOfNodes; i++) G.newNode(); minstd_rand rng(randomSeed()); uniform_real_distribution<> dist_0_1(0.0,1.0); int numberOfLayers = 0, totNumber = 0, realCount = 0; fst[0] = 0; for(node v : G.nodes) { if(longEdges && numberOfLayers) vrt[totNumber++] = 1; nnr[totNumber] = v; vrt[totNumber++] = 0; realCount++; double r = dist_0_1(rng); if((totNumber == 1 && singleSource) || realCount == numberOfNodes || r*r*numberOfNodes < 1) { if(longEdges && numberOfLayers) vrt[totNumber++] = 1; fst[++numberOfLayers] = totNumber; } } /** Determine allowed neighbours **/ Array<int> leftN (totNumber); Array<int> rightN(totNumber); for(int l = 1; l < numberOfLayers; l++) { if(planar) { int n1 = fst[l-1]; int n2 = fst[l]; leftN[n2] = n1; while(n1 < fst[l] && n2 < fst[l+1]) { double r = dist_0_1(rng); if(n1 != fst[l]-1 && (n2 == fst[l+1]-1 || r < (double)(fst[l]-fst[l-1])/(double)(fst[l+1]-fst[l-1]))) n1++; else { rightN[n2] = n1; if(++n2 < fst[l+1]) leftN[n2] = n1; } } } else for(int n2 = fst[l]; n2 < fst[l+1]; n2++) { leftN [n2] = fst[l-1]; rightN[n2] = fst[l]-1; } } /** Insert edges **/ List<bEdge> startEdges; Array<SList<bEdge>> edgeIn (totNumber); Array<SList<bEdge>> edgeOut(totNumber); if (numberOfLayers) { double x1 = numberOfEdges; double x2 = 0; for (int n2 = fst[1]; n2 < totNumber; n2++) { if (!vrt[n2]) x2 += rightN[n2] - leftN[n2] + 1; } int idc = 0; for (int n2 = fst[1]; n2 < totNumber; n2++) { if (!vrt[n2]) { bool connected = !singleSource; for (int n1 = leftN[n2]; n1 <= rightN[n2] || !connected; n1++) { double r = dist_0_1(rng); if (r < x1 / x2 || n1 > rightN[n2]) { int next = (n1 <= rightN[n2] ? n1 : uniform_int_distribution<>(leftN[n2], rightN[n2])(rng)); int act = n2; bEdge nextEdge = OGDF_NEW BEdge(next, act, idc++); while (vrt[next]) { act = next; next = uniform_int_distribution<>(leftN[act], rightN[act])(rng); edgeOut[act].pushBack(nextEdge); nextEdge = OGDF_NEW BEdge(next, act, idc++); edgeIn[act].pushBack(nextEdge); } startEdges.pushBack(nextEdge); connected = true; x1 -= 1; } if (n1 <= rightN[n2]) x2 -= 1; } } } } if(planar) for(int act = 0; act < totNumber; act++) { CmpTail cmpTail; edgeIn[act].quicksort(cmpTail); CmpHead cmpHead; edgeOut[act].quicksort(cmpHead); } for(int act = 0; act < totNumber; act++) { for(bEdge nextEdge : edgeIn[act]) { nextEdge->next = edgeOut[act].popFrontRet(); } } for(bEdge actEdge : startEdges) { bEdge nextEdge = actEdge; while(vrt[nextEdge->head]) nextEdge = nextEdge->next; G.newEdge(nnr[actEdge->tail], nnr[nextEdge->head]); } /** Clean up **/ for(bEdge nextEdge : startEdges) { bEdge toDelete = nextEdge; while(vrt[nextEdge->head]) { nextEdge = nextEdge->next; delete toDelete; toDelete = nextEdge; } delete toDelete; } }
// Personalized pagerank starting from vertex start (at index 0) void pers_pagerank() { Graph *graph = sub->subgraph; unsigned iter = 0; double err = 1.0; // We are done when maxiteration is reached // or the error is small enough. while (iter++ < maxiter && err > tolerance) { // copy last iteration to last array // and clear pagerank array #pragma omp parallel for for (unsigned i = 0; i < nvert; i++) { last[i] = pagerank[i]; pagerank[i] = 0.0; } // sum up the nodes without outgoing edges ("dangling nodes"). // their pagerank sum will be uniformly distributed among all nodes. double zsum = 0.0; #pragma omp parallel for reduction(+:zsum) for (unsigned i = 0; i < sub->zerodeg.size(); i++) zsum += last[ sub->zerodeg[i] ]; double nolinks = (1.0-alpha) * zsum / nvert; pagerank[0] += alpha; // add teleport probability to the start vertex #pragma omp parallel for for (unsigned id = 0; id < nvert; id++) { double update = (1.0-alpha) * last[id]; for (Graph::iterator e = graph->iterate_outgoing_edges(id); !e.end(); e++) { #pragma omp atomic pagerank[(*e).v2] += (update * sub->score(id, (*e).v2)); } #pragma omp atomic pagerank[id] += nolinks; // pagerank from "dangling nodes" } // sum the pagerank double sum = 0.0; #pragma omp parallel for reduction(+:sum) for (unsigned i = 0; i < nvert; i++) sum += pagerank[i]; // normalize to valid probabilities, from 0 to 1. sum = 1.0 / sum; #pragma omp parallel for for (unsigned i = 0; i < nvert; i++) pagerank[i] *= sum; // sum up the error err = 0.0; #pragma omp parallel for reduction(+:err) for (unsigned i = 0; i < nvert; i++) err += fabs(pagerank[i] - last[i]); //cout << "Iteration " << iter << endl; //cout << "Error: " << err << endl; } //cout << "PageRank iterations: " << iter << endl; }
void do_degrees() { for (Graph::iterator ii = graph.begin(), ei = graph.end(); ii != ei; ++ii) { std::cout << std::distance(graph.neighbor_begin(*ii), graph.neighbor_end(*ii)) << "\n"; } }
//========================================================== void PlanarityTestTest::planarMetaGraphsEmbedding() { tlp::warning() << "===========MetaGraphsEmbedding=======================" << endl; graph = tlp_loadGraph(GRAPHPATH + "planar/grid1010.tlp"); Graph *g = graph->addCloneSubGraph(); vector<node> toGroup; toGroup.reserve(10); const std::vector<node> &nodes = graph->nodes(); for (unsigned int i = 0; i < 10; ++i) toGroup.push_back(nodes[i]); g->createMetaNode(toGroup); toGroup.clear(); for (unsigned int i = 10; i < 20; ++i) toGroup.push_back(nodes[i]); node meta2 = g->createMetaNode(toGroup); toGroup.clear(); toGroup.push_back(meta2); for (unsigned int i = 20; i < 30; ++i) toGroup.push_back(nodes[i]); g->createMetaNode(toGroup, false); toGroup.clear(); PlanarConMap *graphMap = computePlanarConMap(g); // graphMap->makePlanar(); CPPUNIT_ASSERT(PlanarityTest::isPlanar(g)); // eulerIdentity(g), graphMap->nbFaces()); CPPUNIT_ASSERT(PlanarityTest::isPlanar(graphMap)); // eulerIdentity(g), graphMap->nbFaces()); delete graphMap; graph->delSubGraph(g); delete graph; tlp::warning() << "==================================" << endl; /* graph = tlp::loadGraph(GRAPHPATH + "planar/unconnected.tlp"); graph->setAttribute("name", string("unconnected")); graphMap = new PlanarConMap(graph); tlp::warning() << "Graph name : " << graph->getAttribute<string>("name") << endl; graphMap->makePlanar();*/ /* * The number of faces must be adapted because the Planarity Test split the * external face into several faces (one by connected componnent). */ /* CPPUNIT_ASSERT_EQUAL(eulerIdentity(graph), graphMap->nbFaces() - (ConnectedTest::numberOfConnectedComponnents(graph) - 1)); delete graphMap; delete graph; tlp::warning() << "==================================" << endl; tlp::warning() << "unbiconnected" << endl; graph = tlp::loadGraph(GRAPHPATH + "planar/unbiconnected.tlp"); graphMap = new PlanarConMap(graph); graphMap->makePlanar(); CPPUNIT_ASSERT_EQUAL(eulerIdentity(graph), graphMap->nbFaces()); delete graphMap; delete graph; tlp::warning() << "==================================" << endl;*/ }
int main(int argc, char *argv[]) { //first argument, lowercase, if any std::string fl = argc>1 ? lowercase(argv[1]) : ""; if (argc<=2) { if (fl=="" || fl=="--help" || fl=="-h" || fl=="/?" || fl=="/help") { std::cerr << "usage:\t" << argv[0] << " graph [''|solution|'='|'%'|color]" << std::endl; std::cerr << "where:\t" << "graph and solution are filenames" << std::endl; std::cerr << "\tcolor is an id in the default color palette" << std::endl; return 1; } else { try { Graph graph = Graph::load(argv[1]); signal(SIGUSR1, Metaheuristic::dump_handler); std::vector<int> v(graph.succ.size(), 0); Solution sol(v, graph); sol.initSolution(); //TODO adjust parameters here! float alpha = 0.9f; float temperature = 10.0f; float epsilon = 1.0f; int niter = 10; //std::cerr << "HIT before create recuit" << std::endl; Recuit meta(sol, alpha, niter, temperature, epsilon); //std::cerr << "HIT before starting recuit" << std::endl; //LocalSearch meta(graph); sol = meta.getSolution(); sol.dump(); if(sol.isAdmissible()) std::cerr << "GOOD" << std::endl; return 0; } catch (GraphException& e) { std::cerr << "error: " << e.what() << std::endl; return 2; } } } else { try { Graph g = Graph::load(argv[1]); #ifdef USE_SDL Solution *s = NULL; int pattern = get_positive(argv[2]); if (pattern == -1) { std::string a2 = argv[2]; if (a2 == "=") pattern = -1; else if (a2 == "%") pattern = -2; else s = new Solution(Solution::load(a2, g)); } if (!s) s = new Solution(Solution::load(g, pattern)); ui_main(g, s); delete s; #else g.dump(); #endif //USE_SDL return 0; } catch (SolutionException& e) { std::cerr << "error: " << e.what() << std::endl; return 3; } catch (GraphException& e) { std::cerr << "error: " << e.what() << std::endl; return 2; } } }
void vertex_event(const char* name, Vertex v, const Graph& g) { std::cerr << "#" << process_id(g.process_group()) << ": " << name << "(" << get_vertex_name(v, g) << ": " << local(v) << "@" << owner(v) << ")\n"; }
void NodeController::tryGraphs() { Graph<int> testerGraph; testerGraph.addVertex(7); testerGraph.addVertex(18); testerGraph.addVertex(9); testerGraph.addVertex(17); testerGraph.addVertex(6); testerGraph.addVertex(3); testerGraph.addVertex(52); testerGraph.addVertex(68); testerGraph.addVertex(23); testerGraph.addVertex(35); //Add at least 7 vertices. //Connct the vertices testerGraph.addEdge(0,1); testerGraph.addEdge(1,2); testerGraph.addEdge(2,3); testerGraph.addEdge(6,7); testerGraph.addEdge(7,8); testerGraph.addEdge(8,9); testerGraph.breadthFirstTraversal(testerGraph, 0); }
static unsigned foo(const GNode& n) { return std::distance(graph.edge_begin(n, Galois::NONE), graph.edge_end(n, Galois::NONE)); }
static void makeGraph(const char* input) { std::vector<GNode> nodes; //Create local computation graph. typedef Galois::Graph::LC_CSR_Graph<Node, EdgeDataType> InGraph; typedef InGraph::GraphNode InGNode; InGraph in_graph; //Read graph from file. in_graph.structureFromFile(input); std::cout << "Read " << in_graph.size() << " nodes\n"; //A node and a int is an element. typedef std::pair<InGNode, EdgeDataType> Element; //A vector of element is 'Elements' typedef std::vector<Element> Elements; //A vector of 'Elements' is a 'Map' typedef std::vector<Elements> Map; //'in_edges' is a vector of vector of pairs of nodes and int. Map edges(in_graph.size()); // int numEdges = 0; for (InGraph::iterator src = in_graph.begin(), esrc = in_graph.end(); src != esrc; ++src) { for (InGraph::edge_iterator dst = in_graph.edge_begin(*src, Galois::NONE), edst = in_graph.edge_end(*src, Galois::NONE); dst != edst; ++dst) { if (*src == *dst) { #if BORUVKA_DEBUG std::cout<<"ERR:: Self loop at "<<*src<<std::endl; #endif continue; } EdgeDataType w = in_graph.getEdgeData(dst); Element e(*src, w); edges[in_graph.getEdgeDst(dst)].push_back(e); numEdges++; } } #if BORUVKA_DEBUG std::cout<<"Number of edges "<<numEdges<<std::endl; #endif nodes.resize(in_graph.size()); for (Map::iterator i = edges.begin(), ei = edges.end(); i != ei; ++i) { Node n(nodeID); GNode node = graph.createNode(n); graph.addNode(node); nodes[nodeID] = node; nodeID++; } int id = 0; numEdges = 0; EdgeDataType edge_sum = 0; int numDups = 0; for (Map::iterator i = edges.begin(), ei = edges.end(); i != ei; ++i) { GNode src = nodes[id]; for (Elements::iterator j = i->begin(), ej = i->end(); j != ej; ++j) { Graph::edge_iterator it = graph.findEdge(src, nodes[j->first], Galois::NONE); if (it != graph.edge_end(src, Galois::NONE)) { numDups++; EdgeDataType w = (graph.getEdgeData(it)); if (j->second < w) { graph.getEdgeData(it) = j->second; edge_sum += (j->second-w); } } else { graph.getEdgeData(graph.addEdge(src, nodes[j->first], Galois::NONE)) = j->second; edge_sum += j->second; } numEdges++; assert(edge_sum < std::numeric_limits<EdgeDataType>::max()); } id++; } #if BORUVKA_DEBUG std::cout << "Final num edges " << numEdges << " Dups " << numDups << " sum :" << edge_sum << std::endl; #endif }
void operator()(GNode& src, ContextTy& lwl) { if (graph.containsNode(src) == false) return; graph.getData(src, Galois::ALL); GNode * minNeighbor = 0; #if BORUVKA_DEBUG std::cout<<"Processing "<<graph.getData(src).toString()<<std::endl; #endif EdgeDataType minEdgeWeight = std::numeric_limits<EdgeDataType>::max(); //Acquire locks on neighborhood. for (Graph::edge_iterator dst = graph.edge_begin(src, Galois::ALL), edst = graph.edge_end(src, Galois::ALL); dst != edst; ++dst) { graph.getData(graph.getEdgeDst(dst)); } //Find minimum neighbor for (Graph::edge_iterator e_it = graph.edge_begin(src, Galois::NONE), edst = graph.edge_end(src, Galois::NONE); e_it != edst; ++e_it) { EdgeDataType w = graph.getEdgeData(e_it, Galois::NONE); assert(w>=0); if (w < minEdgeWeight) { minNeighbor = &((*e_it).first()); minEdgeWeight = w; } } //If there are no outgoing neighbors. if (minEdgeWeight == std::numeric_limits<EdgeDataType>::max()) { graph.removeNode(src, Galois::NONE); return; } #if BORUVKA_DEBUG std::cout << " Min edge from "<<graph.getData(src) << " to "<<graph.getData(*minNeighbor)<<" " <<minEdgeWeight << " "<<std::endl; #endif //Acquire locks on neighborhood of min neighbor. for (Graph::edge_iterator e_it = graph.edge_begin(*minNeighbor, Galois::ALL), edst = graph.edge_end(*minNeighbor, Galois::ALL); e_it != edst; ++e_it) { graph.getData(graph.getEdgeDst(e_it)); } assert(minEdgeWeight>=0); //update MST weight. *MSTWeight.getLocal() += minEdgeWeight; typedef std::pair<GNode, EdgeDataType> EdgeData; typedef std::set<EdgeData, std::less<EdgeData>, Galois::PerIterAllocTy::rebind<EdgeData>::other> edsetTy; edsetTy toAdd(std::less<EdgeData>(), Galois::PerIterAllocTy::rebind<EdgeData>::other(lwl.getPerIterAlloc())); for (Graph::edge_iterator mdst = graph.edge_begin(*minNeighbor, Galois::NONE), medst = graph.edge_end(*minNeighbor, Galois::NONE); mdst != medst; ++mdst) { GNode dstNode = graph.getEdgeDst(mdst); int edgeWeight = graph.getEdgeData(mdst,Galois::NONE); if (dstNode != src) { //Do not add the edge being contracted Graph::edge_iterator dup_edge = graph.findEdge(src, dstNode, Galois::NONE); if (dup_edge != graph.edge_end(src, Galois::NONE)) { EdgeDataType dup_wt = graph.getEdgeData(dup_edge,Galois::NONE); graph.getEdgeData(dup_edge,Galois::NONE) = std::min<EdgeDataType>(edgeWeight, dup_wt); assert(std::min<EdgeDataType>(edgeWeight, dup_wt)>=0); } else { toAdd.insert(EdgeData(dstNode, edgeWeight)); assert(edgeWeight>=0); } } } graph.removeNode(*minNeighbor, Galois::NONE); for (edsetTy::iterator it = toAdd.begin(), endIt = toAdd.end(); it != endIt; it++) { graph.getEdgeData(graph.addEdge(src, it->first, Galois::NONE)) = it->second; } lwl.push(src); #if COMPILE_STATISICS if(stat_collector.tick().counter%BORUVKA_SAMPLE_FREQUENCY==0) stat_collector.snap(); #endif }
unsigned operator()(const GNode& n) { return std::distance(graph.edge_begin(n, Galois::NONE), graph.edge_end(n, Galois::NONE)); }
template<size_t span> struct debruijn_mphf_bench { void operator () (Parameter params) { typedef NodeFast<span> NodeFastT; typedef GraphTemplate<NodeFastT,EdgeFast<span>,GraphDataVariantFast<span>> GraphFast; size_t kmerSize = params.k; Graph graph; GraphFast graphFast; if (params.seq == "") { graph = Graph::create (params.args.c_str()); graphFast = GraphFast::create (params.args.c_str()); } else { graph = Graph::create (new BankStrings (params.seq.c_str(), 0), params.args.c_str()); graphFast = GraphFast::create (new BankStrings (params.seq.c_str(), 0), params.args.c_str()); } cout << "graph built, benchmarking.." << endl; int miniSize = 8; int NB_REPETITIONS = 2000000; double unit = 1000000000; cout.setf(ios_base::fixed); cout.precision(3); Graph::Iterator<Node> nodes = graph.iterator(); typename GraphFast::template Iterator<NodeFastT> nodesFast = graphFast.iterator(); nodes.first (); /** We get the first node. */ Node node = nodes.item(); typedef typename Kmer<span>::Type Type; typedef typename Kmer<span>::ModelCanonical ModelCanonical; typedef typename Kmer<span>::ModelDirect ModelDirect; typedef typename Kmer<span>::template ModelMinimizer <ModelCanonical> ModelMini; typedef typename ModelMini::Kmer KmerType; ModelMini modelMini (kmerSize, miniSize); ModelCanonical modelCanonical (kmerSize); // for some reason.. if *compiled*, this code confuses makes later MPHF queries 3x slower. really? yes. try to replace "if (confuse_mphf)" by "if (confuse_mphf && 0)" and re-run, you will see. { bool confuse_mphf = false; if (confuse_mphf) { //Type b; b.setVal(0); //modelCanonical.emphf_hasher(modelCanonical.adaptor(b)); //typedef std::pair<u_int8_t const*, u_int8_t const*> byte_range_t; //int c = 0; //byte_range_t brange( reinterpret_cast <u_int8_t const*> (&c), reinterpret_cast <u_int8_t const*> (&c) + 2 ); //byte_range_t brange( (u_int8_t const*) 1,(u_int8_t const*)33); //auto hashes = modelCanonical.empfh_hasher(brange); } for (int i = 0; i < 0; i++) { auto start_tt=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelCanonical.EMPHFhash(nodes.item().kmer.get<Type>()); auto end_tt=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computing EMPHFhash of kmers on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_tt, end_tt) / unit) << " seconds" << endl; } // it's slow. i don't understand why. see above for the "confuse mphf" part //return; //FIXME } /** We get the value of the first node (just an example, it's not used later). */ Type kmer = node.kmer.get<Type>(); auto start_t=chrono::system_clock::now(); auto end_t=chrono::system_clock::now(); cout << "----\non all nodes of the graph\n-----\n"; /* disable node state (because we don't want to pay the price for overhea of checking whether a node is deleted or not in contain() */ std::cout<< "PAY ATTENTION: this neighbor() benchmark, in the Bloom flavor, is without performing a MPHF query for each found node" << std::endl; graph.disableNodeState(); graphFast.disableNodeState(); /* compute baseline times (= overheads we're not interested in) */ start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) {} end_t=chrono::system_clock::now(); auto baseline_graph_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph nodes enumeration (" << nodes.size() << " nodes) : " << baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) {} end_t=chrono::system_clock::now(); auto baseline_graphfast_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph NodeFast enumeration (" << nodes.size() << " nodes) : " << baseline_graphfast_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelMini.getMinimizerValueDummy(nodes.item().kmer.get<Type>()); end_t=chrono::system_clock::now(); auto baseline_minim_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph nodes enumeration and minimizer computation setup (" << nodes.size() << " nodes) : " << baseline_minim_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) nodes.item().getKmer<Type>(); end_t=chrono::system_clock::now(); auto baseline_hash_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph nodes enumeration and hash computation setup (" << nodes.size() << " nodes) : " << baseline_hash_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) nodesFast.item().kmer; end_t=chrono::system_clock::now(); auto baseline_hashfast_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph NodeFast enumeration and hash computation setup (" << nodes.size() << " nodes) : " << baseline_hashfast_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.nodeMPHFIndexDummy(nodes.item()); end_t=chrono::system_clock::now(); auto baseline_mphf_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph nodes enumeration and mphf query setup (" << nodes.size() << " nodes) : " << baseline_mphf_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.nodeMPHFIndexDummy(nodesFast.item()); end_t=chrono::system_clock::now(); auto baseline_mphffast_time = diff_wtime(start_t, end_t) / unit; cout << "baseline overhead for graph NodeFast enumeration and mphf query setup (" << nodes.size() << " nodes) : " << baseline_mphffast_time << " seconds" << endl; /* do actual benchmark */ start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelMini.getMinimizerValue(nodes.item().kmer.get<Type>(), true); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computations of minimizers (fast method) of length " << miniSize << " on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_minim_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.nodeMPHFIndex(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computations of MPHF index on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_mphf_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.nodeMPHFIndex(nodesFast.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computations of MPHF index on all NodeFast (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_mphffast_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelCanonical.getHash(nodes.item().kmer.get<Type>()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computing hash1 of kmers on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_hash_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelCanonical.getHash2(nodes.item().kmer.get<Type>()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computing hash2 of kmers on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_hash_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) modelCanonical.getHash2(nodesFast.item().kmer); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computing hash2 of kmers on all NodeFast (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_hashfast_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) modelCanonical.EMPHFhash(nodes.item().kmer.get<Type>()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " computing EMPHFhash of kmers on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_hash_time << " seconds" << endl; // it's slow. i don't understand why. see above for the "confuse mphf" part start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.neighborsDummy(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " dummy neighbors() query on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.neighbors(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " neighbors() query on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.neighbors(nodesFast.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " neighbors() query on all NodeFast (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_graphfast_time << " seconds" << endl; /* isBranching */ start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.isBranching(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " isBranching() query on all nodes (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.isBranching(nodesFast.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " isBranching() query on all NodeFast (" << kmerSize << "-mers) : " << (diff_wtime(start_t, end_t) / unit) - baseline_graphfast_time << " seconds" << endl; /* now, compute adjacency! */ graph.precomputeAdjacency(); graphFast.precomputeAdjacency(); cout << "adjacency precomputed" << endl; start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.neighbors(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " neighbors() query on all nodes (" << kmerSize << "-mers) using adjacency : " << (diff_wtime(start_t, end_t) / unit) - baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.neighbors(nodesFast.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " fast neighbors() query on all NodeFast (" << kmerSize << "-mers) using adjacency : " << (diff_wtime(start_t, end_t) / unit) - baseline_graphfast_time << " seconds" << endl; /* isBranching */ start_t=chrono::system_clock::now(); for (nodes.first(); !nodes.isDone(); nodes.next()) graph.isBranching(nodes.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " isBranching() query on all nodes (" << kmerSize << "-mers) using adjacency : " << (diff_wtime(start_t, end_t) / unit) - baseline_graph_time << " seconds" << endl; start_t=chrono::system_clock::now(); for (nodesFast.first(); !nodesFast.isDone(); nodesFast.next()) graphFast.isBranching(nodesFast.item()); end_t=chrono::system_clock::now(); cout << "time to do " << nodes.size() << " fast isBranching() query on all NodeFast (" << kmerSize << "-mers) using adjacency : " << (diff_wtime(start_t, end_t) / unit) - baseline_graphfast_time << " seconds" << endl; /** We remove the graph. */ //graph.remove (); //graphFast.remove (); // no actually, I want to keep the .h5 file }
void MultiLayer::printAllLayers(QPainter *painter) { if (!painter) return; QPrinter *printer = (QPrinter *)painter->device(); QRect paperRect = ((QPrinter *)painter->device())->paperRect(); QRect canvasRect = canvas->rect(); QRect pageRect = printer->pageRect(); QRect cr = canvasRect; // cropmarks rectangle if (d_scale_on_print) { int margin = (int)((1 / 2.54) * printer->logicalDpiY()); // 1 cm margins double scaleFactorX = (double)(paperRect.width() - 2 * margin) / (double)canvasRect.width(); double scaleFactorY = (double)(paperRect.height() - 2 * margin) / (double)canvasRect.height(); if (d_print_cropmarks) { cr.moveTo(QPoint(margin + int(cr.x() * scaleFactorX), margin + int(cr.y() * scaleFactorY))); cr.setWidth(int(cr.width() * scaleFactorX)); cr.setHeight(int(cr.height() * scaleFactorX)); } for (int i = 0; i < (int)graphsList.count(); i++) { Graph *gr = (Graph *)graphsList.at(i); Plot *myPlot = gr->plotWidget(); QPoint pos = gr->pos(); pos = QPoint(margin + int(pos.x() * scaleFactorX), margin + int(pos.y() * scaleFactorY)); int width = int(myPlot->frameGeometry().width() * scaleFactorX); int height = int(myPlot->frameGeometry().height() * scaleFactorY); gr->print(painter, QRect(pos, QSize(width, height))); } } else { int x_margin = (pageRect.width() - canvasRect.width()) / 2; int y_margin = (pageRect.height() - canvasRect.height()) / 2; if (d_print_cropmarks) cr.moveTo(x_margin, y_margin); for (int i = 0; i < (int)graphsList.count(); i++) { Graph *gr = (Graph *)graphsList.at(i); Plot *myPlot = (Plot *)gr->plotWidget(); QPoint pos = gr->pos(); pos = QPoint(x_margin + pos.x(), y_margin + pos.y()); gr->print(painter, QRect(pos, myPlot->size())); } } if (d_print_cropmarks) { cr.addCoords(-1, -1, 2, 2); painter->save(); painter->setPen(QPen(QColor(Qt::black), 0.5, Qt::DashLine)); painter->drawLine(paperRect.left(), cr.top(), paperRect.right(), cr.top()); painter->drawLine(paperRect.left(), cr.bottom(), paperRect.right(), cr.bottom()); painter->drawLine(cr.left(), paperRect.top(), cr.left(), paperRect.bottom()); painter->drawLine(cr.right(), paperRect.top(), cr.right(), paperRect.bottom()); painter->restore(); } }
QSize MultiLayer::arrangeLayers(bool userSize) { const QRect rect = canvas->geometry(); gsl_vector *xTopR = gsl_vector_calloc( graphs); // ratio between top axis + title and canvas height gsl_vector *xBottomR = gsl_vector_calloc(graphs); // ratio between bottom axis and canvas height gsl_vector *yLeftR = gsl_vector_calloc(graphs); gsl_vector *yRightR = gsl_vector_calloc(graphs); gsl_vector *maxXTopHeight = gsl_vector_calloc(rows); // maximum top axis + title height in a row gsl_vector *maxXBottomHeight = gsl_vector_calloc(rows); // maximum bottom axis height in a row gsl_vector *maxYLeftWidth = gsl_vector_calloc(cols); // maximum left axis width in a column gsl_vector *maxYRightWidth = gsl_vector_calloc(cols); // maximum right axis width in a column gsl_vector *Y = gsl_vector_calloc(rows); gsl_vector *X = gsl_vector_calloc(cols); int i; for (i = 0; i < graphs; i++) { // calculate scales/canvas dimensions reports for each layer and // stores them in the above vectors Graph *gr = (Graph *)graphsList.at(i); QwtPlot *plot = gr->plotWidget(); QwtPlotLayout *plotLayout = plot->plotLayout(); QRect cRect = plotLayout->canvasRect(); double ch = (double)cRect.height(); double cw = (double)cRect.width(); QRect tRect = plotLayout->titleRect(); QwtScaleWidget *scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::xTop); int topHeight = 0; if (!tRect.isNull()) topHeight += tRect.height() + plotLayout->spacing(); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::xTop); topHeight += sRect.height(); } gsl_vector_set(xTopR, i, double(topHeight) / ch); scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::xBottom); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::xBottom); gsl_vector_set(xBottomR, i, double(sRect.height()) / ch); } scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::yLeft); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::yLeft); gsl_vector_set(yLeftR, i, double(sRect.width()) / cw); } scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::yRight); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::yRight); gsl_vector_set(yRightR, i, double(sRect.width()) / cw); } // calculate max scales/canvas dimensions ratio for each line and column and // stores them to vectors int row = i / cols; if (row >= rows) row = rows - 1; int col = i % cols; double aux = gsl_vector_get(xTopR, i); double old_max = gsl_vector_get(maxXTopHeight, row); if (aux >= old_max) gsl_vector_set(maxXTopHeight, row, aux); aux = gsl_vector_get(xBottomR, i); if (aux >= gsl_vector_get(maxXBottomHeight, row)) gsl_vector_set(maxXBottomHeight, row, aux); aux = gsl_vector_get(yLeftR, i); if (aux >= gsl_vector_get(maxYLeftWidth, col)) gsl_vector_set(maxYLeftWidth, col, aux); aux = gsl_vector_get(yRightR, i); if (aux >= gsl_vector_get(maxYRightWidth, col)) gsl_vector_set(maxYRightWidth, col, aux); } double c_heights = 0.0; for (i = 0; i < rows; i++) { gsl_vector_set(Y, i, c_heights); c_heights += 1 + gsl_vector_get(maxXTopHeight, i) + gsl_vector_get(maxXBottomHeight, i); } double c_widths = 0.0; for (i = 0; i < cols; i++) { gsl_vector_set(X, i, c_widths); c_widths += 1 + gsl_vector_get(maxYLeftWidth, i) + gsl_vector_get(maxYRightWidth, i); } if (!userSize) { l_canvas_width = int( (rect.width() - (cols - 1) * colsSpace - right_margin - left_margin) / c_widths); l_canvas_height = int( (rect.height() - (rows - 1) * rowsSpace - top_margin - bottom_margin) / c_heights); } QSize size = QSize(l_canvas_width, l_canvas_height); for (i = 0; i < graphs; i++) { int row = i / cols; if (row >= rows) row = rows - 1; int col = i % cols; // calculate sizes and positions for layers const int w = int(l_canvas_width * (1 + gsl_vector_get(yLeftR, i) + gsl_vector_get(yRightR, i))); const int h = int(l_canvas_height * (1 + gsl_vector_get(xTopR, i) + gsl_vector_get(xBottomR, i))); int x = left_margin + col * colsSpace; if (hor_align == HCenter) x += int(l_canvas_width * (gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i))); else if (hor_align == Left) x += int(l_canvas_width * gsl_vector_get(X, col)); else if (hor_align == Right) x += int(l_canvas_width * (gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i) + gsl_vector_get(maxYRightWidth, col) - gsl_vector_get(yRightR, i))); int y = top_margin + row * rowsSpace; if (vert_align == VCenter) y += int(l_canvas_height * (gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i))); else if (vert_align == Top) y += int(l_canvas_height * gsl_vector_get(Y, row)); else if (vert_align == Bottom) y += int(l_canvas_height * (gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i) + +gsl_vector_get(maxXBottomHeight, row) - gsl_vector_get(xBottomR, i))); // resizes and moves layers Graph *gr = (Graph *)graphsList.at(i); bool autoscaleFonts = false; if (!userSize) { // When the user specifies the layer canvas size, the // window is resized // and the fonts must be scaled accordingly. If the size is calculated // automatically we don't rescale the fonts in order to prevent problems // with too small fonts when the user adds new layers or when removing // layers autoscaleFonts = gr->autoscaleFonts(); // save user settings gr->setAutoscaleFonts(false); } gr->setGeometry(QRect(x, y, w, h)); gr->plotWidget()->resize(QSize(w, h)); if (!userSize) gr->setAutoscaleFonts(autoscaleFonts); // restore user settings } // free memory gsl_vector_free(maxXTopHeight); gsl_vector_free(maxXBottomHeight); gsl_vector_free(maxYLeftWidth); gsl_vector_free(maxYRightWidth); gsl_vector_free(xTopR); gsl_vector_free(xBottomR); gsl_vector_free(yLeftR); gsl_vector_free(yRightR); gsl_vector_free(X); gsl_vector_free(Y); return size; }
int main(int argc, char **argv) { srand(time(NULL)); parse_args(argc, argv); time_t time_begin, time_end; time(&time_begin); display_time("start"); Community c(filename, type, -1, precision); display_time("file read"); double mod = c.modularity(); //cerr << "network : " // << c.g.nb_nodes << " nodes, " //<< c.g.nb_links << " links, " //<< c.g.total_weight << " weight." << endl; double new_mod = c.one_level(); display_time("communities computed"); //cerr << "modularity increased from " << mod << " to " << new_mod << endl; if (display_level==-1) c.display_partition(); Graph g = c.partition2graph_binary(); display_time("network of communities computed"); int level=0; while(new_mod-mod>precision) { mod=new_mod; Community c(g, -1, precision); //cerr << "\nnetwork : " //<< c.g.nb_nodes << " nodes, " //<< c.g.nb_links << " links, " //<< c.g.total_weight << " weight." << endl; new_mod = c.one_level(); display_time("communities computed"); //cerr << "modularity increased from " << mod << " to " << new_mod << endl; if (display_level==-1) c.display_partition(); g = c.partition2graph_binary(); level++; if (level==display_level) g.display(); display_time("network of communities computed"); } time(&time_end); //cerr << precision << " " << new_mod << " " << (time_end-time_begin) << endl; }
EdgeDataType verify(Graph & g){ return kruskal_impl(g.size(), read_edges(g)); }
TEST_F(HexBoardTest,HexBoardSetMove) { //test 5x5 Hexboard HexBoard board(5); Game hexboardgame(board); Player playera(board, hexgonValKind_RED); //test with private set setPlayerBoard method and corresponding MST tree ASSERT_TRUE(hexboardgame.setMove(playera, 1, 1)); HexBoard playerasboard = playera.getPlayersboard(); EXPECT_EQ(0, playerasboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 1); ASSERT_TRUE(hexboardgame.setMove(playera, 2, 1)); playerasboard = playera.getPlayersboard(); EXPECT_EQ(1, playerasboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 2); ASSERT_TRUE(hexboardgame.setMove(playera, 3, 1)); playerasboard = playera.getPlayersboard(); EXPECT_EQ(2, playerasboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 3); ASSERT_TRUE(hexboardgame.setMove(playera, 4, 1)); playerasboard = playera.getPlayersboard(); EXPECT_EQ(3, playerasboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 4); ASSERT_TRUE(hexboardgame.setMove(playera, 5, 1)); playerasboard = playera.getPlayersboard(); EXPECT_EQ(4, playerasboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 5); MinSpanTreeAlgo<hexgonValKind, int> mstalgo(playerasboard); MinSpanTreeAlgo<hexgonValKind, int>::UnionFind unionfind(mstalgo); mstalgo.calculate(unionfind); Graph<hexgonValKind, int> msttree = mstalgo.getMsttree(); EXPECT_EQ(4, msttree.getSizeOfEdges()); vector<vector<int> > subgraphs = msttree.getAllSubGraphs(); EXPECT_EQ(1, subgraphs.size()); Player playerb(board, hexgonValKind_BLUE); ASSERT_TRUE(hexboardgame.setMove(playerb, 1, 2)); HexBoard playerbsboard = playerb.getPlayersboard(); EXPECT_EQ(0, playerbsboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 6); ASSERT_TRUE(hexboardgame.setMove(playerb, 2, 2)); playerbsboard = playerb.getPlayersboard(); EXPECT_EQ(1, playerbsboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 7); ASSERT_TRUE(hexboardgame.setMove(playerb, 3, 2)); playerbsboard = playerb.getPlayersboard(); EXPECT_EQ(2, playerbsboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 8); ASSERT_TRUE(hexboardgame.setMove(playerb, 4, 2)); playerbsboard = playerb.getPlayersboard(); EXPECT_EQ(3, playerbsboard.getSizeOfEdges()); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 9); ASSERT_TRUE(hexboardgame.setMove(playerb, 2, 5)); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 10); ASSERT_TRUE(hexboardgame.setMove(playerb, 3, 5)); EXPECT_EQ(board.getNumofemptyhexgons(), board.getSizeOfVertices() - 11); playerbsboard = playerb.getPlayersboard(); EXPECT_EQ(4, playerbsboard.getSizeOfEdges()); MinSpanTreeAlgo<hexgonValKind, int> mstalgob(playerbsboard); MinSpanTreeAlgo<hexgonValKind, int>::UnionFind unionfindb(mstalgob); mstalgo.calculate(unionfindb); Graph<hexgonValKind, int> msttreeb = mstalgob.getMsttree(); EXPECT_EQ(4, msttreeb.getSizeOfEdges()); vector<vector<int> > subgraphsb = msttreeb.getAllSubGraphs(); EXPECT_EQ(2, subgraphsb.size()); }
double WCCRule::calculate(const Graph &g, const Partition &p) const { double score = 0.0; const int *labels = p.labels; int *eit = new int[2 * g.m]; int *it = new int[g.n]; int *itd = new int[g.n]; fill(eit, eit + (2 * g.m), 0); fill(it, it + g.n, 0); fill(itd, itd + g.n, 0); #pragma omp parallel for schedule(dynamic, 128) for (int v = 0; v < g.n; v++) { int l = labels[v]; for (const int *r = g.begin_neighbors(v); r != g.end_neighbors(v); r++) { int u = *r; if (u >= v) { break; } if (l != labels[u]) { continue; } const int *x = g.begin_neighbors(v); const int *y = g.begin_neighbors(u); const int *x_end = g.end_neighbors(v); const int *y_end = g.end_neighbors(u); while (x != x_end && *x < u && y != y_end && *y < u) { int d = *x - *y; if (d == 0 && labels[*x] == l) { __sync_fetch_and_add(eit + (x - g.adj), 1); __sync_fetch_and_add(eit + (y - g.adj), 1); __sync_fetch_and_add(eit + (r - g.adj), 1); } if (d <= 0) x++; if (d >= 0) y++; } } } #pragma omp parallel for schedule(dynamic, 128) for (int v = 0; v < g.n; v++) { for (const int *r = g.begin_neighbors(v); r != g.end_neighbors(v); r++) { int u = *r; const int int_tri = eit[r - g.adj]; if (int_tri > 0) { __sync_fetch_and_add(it + v, int_tri); __sync_fetch_and_add(itd + v, 1); __sync_fetch_and_add(it + u, int_tri); __sync_fetch_and_add(itd + u, 1); } } } #pragma omp parallel for reduction(+:score) for (int v = 0; v < g.n; v++) { int size = p.sizes[p.labels[v]]; int tri = g.tri[v]; int dtri = g.tri_deg[v]; int itri = it[v]; int ditri = itd[v]; if (tri > 0) { double a = itri / double(tri); double b = dtri / double(size - 1 + dtri - ditri); score += (a * b) / g.n; } } delete[] eit; delete[] it; delete[] itd; return score; }
void Graph::_cloneGraph_KeepIndices (const Graph &other) { if (vertexCount() > 0 || edgeCount() > 0) throw Error("can not _clone_KeepIndices into a non-empty graph"); int i, j, i_prev; int max_vertex_idx = -1; int max_edge_idx = -1; for (i = other.vertexBegin(); i != other.vertexEnd(); i = other.vertexNext(i)) if (max_vertex_idx < i) max_vertex_idx = i; for (i = other.edgeBegin(); i != other.edgeEnd(); i = other.edgeNext(i)) if (max_edge_idx < i) max_edge_idx = i; for (i = 0; i <= max_vertex_idx; i++) if (addVertex() != i) throw Error("_clone_KeepIndices: unexpected vertex index"); i_prev = -1; for (i = other.vertexBegin(); i != other.vertexEnd(); i = other.vertexNext(i)) { for (j = i_prev + 1; j < i; j++) removeVertex(j); i_prev = i; } if (vertexCount() != other.vertexCount()) throw Error("_clone_KeepIndices: internal"); for (i = 0; i <= max_edge_idx; i++) if (_edges.add() != i) throw Error("_clone_KeepIndices: unexpected edge index"); i_prev = -1; for (i = other.edgeBegin(); i != other.edgeEnd(); i = other.edgeNext(i)) { for (j = i_prev + 1; j < i; j++) _edges.remove(j); _edges[i].beg = other._edges[i].beg; _edges[i].end = other._edges[i].end; Vertex &vbeg = _vertices->at(_edges[i].beg); Vertex &vend = _vertices->at(_edges[i].end); int ve1_idx = vbeg.neighbors_list.add(); int ve2_idx = vend.neighbors_list.add(); VertexEdge &ve1 = vbeg.neighbors_list[ve1_idx]; VertexEdge &ve2 = vend.neighbors_list[ve2_idx]; ve1.v = _edges[i].end; ve2.v = _edges[i].beg; ve1.e = i; ve2.e = i; i_prev = i; } if (edgeCount() != other.edgeCount()) throw Error("_clone_KeepIndices: internal"); _topology_valid = false; _sssr_valid = false; _components_valid = false; }
void GNUPlotter::drawGraphSearch(const Graph &graph, const GraphSearch *graphSearch) { if(!file) { return; } for(int i = 0; i < graph.getNumberNodes(); ++i) { int parent = graphSearch->getParent(i); if(parent != -1) { const Vector & pos1 = graph.getNodePos(i); const Vector & pos2 = graph.getNodePos(parent); drawLine(pos1.x, pos1.y, pos2.x, pos2.y, 5); } } deque<int> path; graphSearch->getPath(&path); if(path.size() > 1) { double totalCost = 0.0; deque<int>::iterator itNode = path.begin() + 1; while(itNode != path.end()) { Vector pos1 = graph.getNodePos(*(itNode - 1)); Vector pos2 = graph.getNodePos(*(itNode )); drawArrow(pos1, pos2, 1); totalCost += vectorDistance(pos1, pos2); ++itNode; } char cost[64]; sprintf(cost, "Cost: %.3f", totalCost); drawText(-400, -320, cost); } const bool *visited = graphSearch->getVisited(); for(int i = 0; i < graph.getNumberNodes(); ++i) { if(visited[i]) { drawCircle(graph.getNodePos(i), 10, 255, 0, 0); } } vector<int> frontier; graphSearch->getFrontier(&frontier); vector<int>::iterator itFrontNode = frontier.begin(); while(itFrontNode != frontier.end()) { drawCircle(graph.getNodePos(*itFrontNode), 12, 0, 255, 0); ++itFrontNode; } }
int main (int argc, char *argv[]) { /** * Paso 1: Iniciar MPI y obtener tamaño e id para cada proceso */ int rank, size, tama; MPI_Init(&argc, &argv); // Inicializamos la comunicacion de los procesos MPI_Comm_size(MPI_COMM_WORLD, &size); // Obtenemos el número total de procesos MPI_Comm_rank(MPI_COMM_WORLD, &rank); // Obtenemos el valor de nuestro identificador /** * Paso 2: Comprobar entradas */ if (argc != 2) { // Debe haber dos argumentos if (rank == 0) { // El proceso 0 imprime el error cerr << "Sintaxis: " << argv[0] << " <archivo de grafo>" << endl; } MPI_Finalize(); return -1; } /** * Paso 3: Crear grafo y obtener número de vértices */ Graph G; int nverts; if (rank == 0) { // Solo lo hace un proceso G.lee(argv[1]); #ifdef PRINT_ALL cout << "El grafo de entrada es:" << endl; G.imprime(); #endif nverts = G.vertices; } /** * Paso 4: Hacer broadcast del número de vértices a todos los procesos */ MPI_Bcast(&nverts, 1, MPI_INT, 0, MPI_COMM_WORLD); /** * Paso 5: Reservar espacio para matriz y fila k */ int tamaLocal, tamaBloque; tamaLocal = nverts * nverts / size; tamaBloque = nverts / size; int M[tamaBloque][nverts], K[nverts]; // Matriz local y fila k /** * Paso 6: Repartir matriz entre los procesos */ MPI_Scatter(G.ptrMatriz(), tamaLocal, MPI_INT, &M[0][0], tamaLocal, MPI_INT, 0, MPI_COMM_WORLD); /** * Paso 7: Bucle principal del algoritmo */ int i, j, k, vikj, iGlobal, iIniLocal, iFinLocal, kEntreTama, kModuloTama; iIniLocal = rank * tamaBloque; // Fila inicial del proceso (valor global) iFinLocal = (rank + 1) * tamaBloque; // Fila final del proceso (valor global) double t = MPI_Wtime(); for (k = 0; k < nverts; k++) { kEntreTama = k / tamaBloque; kModuloTama = k % tamaBloque; if (k >= iIniLocal && k < iFinLocal) { // La fila K pertenece al proceso copy(M[kModuloTama], M[kModuloTama] + nverts, K); } MPI_Bcast(K, nverts, MPI_INT, kEntreTama, MPI_COMM_WORLD); for (i = 0; i < tamaBloque; i++) { // Recorrer las filas (valores locales) iGlobal = iIniLocal + i; // Convertir la fila a global for (j = 0; j < nverts; j++) { if (iGlobal != j && iGlobal != k && j != k) { // No iterar sobre celdas de valor 0 vikj = M[i][k] + K[j]; vikj = min(vikj, M[i][j]); M[i][j] = vikj; } } } } t = MPI_Wtime() - t; /** * Paso 8: Recoger resultados en la matriz */ MPI_Gather(&M[0][0], tamaLocal, MPI_INT, G.ptrMatriz(), tamaLocal, MPI_INT, 0, MPI_COMM_WORLD); /** * Paso 9: Finalizar e imprimir resultados */ MPI_Finalize(); if (rank == 0) { // Solo lo hace un proceso #ifdef PRINT_ALL cout << endl << "El grafo con las distancias de los caminos más cortos es:" << endl; G.imprime(); cout << "Tiempo gastado = " << t << endl << endl; #else cout << t << endl; #endif } }
void unpack_binary_schedules(int num_schedules, schedule_t* schedules, int* sched_sizes, SetOfGraphs* LocalGraphs) { for (uint64_t rank=0; rank<num_schedules; rank++) { ///< needs to be 64 bit because we shift it and append local node id Graph* graph = LocalGraphs->getGraphByRank(rank); int offset = 0; // parsing is done in two passes, first we add all vertices // in the second run we take care of the edges offset += sizeof(int); // jump over scratchpad size offset += sizeof(int); // jump over the number of independent actions while (offset < sched_sizes[rank]) { int node_start_offset = offset; char type; SCHED_GET(&type, schedules[rank], offset, sizeof(char)); offset += sizeof(int); // jump over dependency counter int num_outedges; SCHED_GET(&num_outedges, schedules[rank], offset, sizeof(int)); offset += num_outedges * sizeof(int); NBC_Args_send *args_s; NBC_Args_recv *args_r; switch (type) { case T_SEND: args_s = (NBC_Args_send*) (schedules[rank] + offset); graph->addSend((rank << 32) | node_start_offset, rank, args_s->count, args_s->memtype, args_s->buf, args_s->dest, /*tag*/ 0); offset += sizeof(NBC_Args_send); break; case T_RECV: args_r = (NBC_Args_recv*) (schedules[rank] + offset); graph->addRecv((rank << 32) | node_start_offset, rank, args_r->count, args_r->memtype, args_r->buf, args_r->source, /*tag*/ 0); offset += sizeof(NBC_Args_recv); break; default: printf("*** Type %u not supported ***\n", type); exit(EXIT_FAILURE); } } // this is the second pass where we add all the edges offset = 0; offset += sizeof(int); // jump over scratchpad size offset += sizeof(int); // jump over the number of independent actions while (offset < sched_sizes[rank]) { int node_start_offset = offset; char type; SCHED_GET(&type, schedules[rank], offset, sizeof(char)); offset += sizeof(int); // jump over dependency counter int num_outedges; SCHED_GET(&num_outedges, schedules[rank], offset, sizeof(int)); for (int i=0; i < num_outedges; i++) { int outedge_to; SCHED_GET(&outedge_to, schedules[rank], offset, sizeof(int)); graph->addDependency((rank << 32) | node_start_offset, (rank << 32) | outedge_to); } switch (type) { case T_SEND: offset += sizeof(NBC_Args_send); break; case T_RECV: offset += sizeof(NBC_Args_recv); break; default: printf("*** Type %u not supported ***\n", type); exit(EXIT_FAILURE); } } } }
/** * Implementação baseada no livro The Algorithm Design Manual -- Skiena */ int Dijkstra::execute( Graph graph, int source, int target) { Node p; //vetor temporário vector<bool> inTree; //O nó já esta na árvore? vector<double> distance; //armazena distância para source int v; //nó atual int w; //candidato a próximo nó int n; //número de nós adjacentes double weight; //peso da aresta double dist; //melhor distância atual para o nó de partida inTree = vector<bool> ( graph.getNumberOfNodes(), false); distance = vector<double> ( graph.getNumberOfNodes(), std::numeric_limits<double>::max() ); this->parent = vector<int> ( graph.getNumberOfNodes(), -1); v = source; distance[v] = 0; while( inTree[target] == false) { inTree[v] = true; p = graph.getNodeAtPosition(v); n = p.getDegree(); if (n == 0) { // cout<<"Topologia com nó "<<v<<" desconexo."<<endl; return -std::numeric_limits<double>::max() ; } int iterator = 0; while( iterator < n ) { w = p.getAdjacentNode(iterator); weight = p.getWeightEdge(iterator); //obtêm peso da aresta /** * Verificação de caminho */ if ( distance[w] > ( distance[v] + weight ) && inTree[w] == false ) { distance[w] = distance[v] + weight; this->parent[w] = v; } iterator++; } v = 0; dist = std::numeric_limits<double>::max(); for (int i = 0; i < graph.getNumberOfNodes(); i++) { if ( ( inTree[i] == false ) && ( dist > distance[i] ) ) { dist = distance[i]; v = i; } } if (inTree[v] == true) { break; } } return distance[target];//retorna distância }
void operator()(Graph& graph, GNode source) { typedef Galois::WorkList::dChunkedFIFO<256> WL; std::deque<Bag*> levels; graph.getData(source).visited = true; graph.getData(source).numPaths.write(1); Bag* frontier = new Bag(graph.size()); frontier->push(source, 1); levels.push_back(frontier); int round = 0; while (!frontier->empty()) { ++round; Bag* output = new Bag(graph.size()); this->outEdgeMap(memoryLimit, graph, ForwardPass(), *frontier, *output, false); //Galois::do_all_local(*output, [&](GNode n) { //Galois::do_all(output->begin(), output->end(), [&](GNode n) { Galois::for_each_local<WL>(*output, [&](size_t id, Galois::UserContext<size_t>&) { SNode& d = graph.getData(graph.nodeFromId(id), Galois::MethodFlag::NONE); d.visited = true; }); levels.push_back(output); frontier = output; } delete levels[round]; Galois::do_all_local(graph, [&](GNode n) { SNode& d = graph.getData(n, Galois::MethodFlag::NONE); d.numPaths.write(1.0/d.numPaths.read()); d.visited = false; }); frontier = levels[round-1]; //Galois::do_all_local(*frontier, [&](GNode n) { Galois::for_each_local<WL>(*frontier, [&](size_t id, Galois::UserContext<size_t>&) { SNode& d = graph.getData(graph.nodeFromId(id), Galois::MethodFlag::NONE); d.visited = true; d.dependencies.write(d.dependencies.read() + d.numPaths.read()); }); for (int r = round - 2; r >= 0; --r) { Bag output(graph.size()); this->inEdgeMap(memoryLimit, graph, BackwardPass(), *frontier, output, false); delete frontier; frontier = levels[r]; //Galois::do_all_local(*frontier, [&](GNode n) { Galois::for_each_local<WL>(*frontier, [&](size_t id, Galois::UserContext<size_t>&) { SNode& d = graph.getData(graph.nodeFromId(id), Galois::MethodFlag::NONE); d.visited = true; d.dependencies.write(d.dependencies.read() + d.numPaths.read()); }); } delete frontier; Galois::do_all_local(graph, [&](GNode n) { SNode& d = graph.getData(n, Galois::MethodFlag::NONE); d.dependencies.write((d.dependencies.read() - d.numPaths.read()) / d.numPaths.read()); }); }
//the call function that lets ClusterPlanarizationLayout compute a layout //for the input using \a weight for the computation of the cluster planar subgraph void ClusterPlanarizationLayout::call( Graph& G, ClusterGraphAttributes& acGraph, ClusterGraph& cGraph, EdgeArray<double>& edgeWeight, bool simpleCConnect) //default true { m_nCrossings = 0; bool subGraph = false; // c-planar subgraph computed? //check some simple cases if (G.numberOfNodes() == 0) return; //------------------------------------------------------------- //we set pointers and arrays to the working graph, which can be //the original or, in the case of non-c-planar input, a copy Graph* workGraph = &G; ClusterGraph* workCG = &cGraph; ClusterGraphAttributes* workACG = &acGraph; //potential copy of original if non c-planar Graph GW; //list of non c-planarity causing edges List<edge> leftEdges; //list of nodepairs to be connected (deleted edges) List<NodePair> leftWNodes; //store some information //original to copy NodeArray<node> resultNode(G); EdgeArray<edge> resultEdge(G); ClusterArray<cluster> resultCluster(cGraph); //copy to original NodeArray<node> orNode(G); EdgeArray<edge> orEdge(G); ClusterArray<cluster> orCluster(cGraph); for(node workv : G.nodes) { resultNode[workv] = workv; //will be set to copy if non-c-planar orNode[workv] = workv; } for(edge worke : G.edges) { resultEdge[worke] = worke; //will be set to copy if non-c-planar orEdge[worke] = worke; } for (cluster workc : cGraph.clusters) { resultCluster[workc] = workc; //will be set to copy if non-c-planar orCluster[workc] = workc; } //----------------------------------------------- //check if instance is clusterplanar and embed it CconnectClusterPlanarEmbed CCPE; //cccp bool cplanar = CCPE.embed(cGraph, G); List<edge> connectEdges; //if the graph is not c-planar, we have to check the reason and to //correct the problem by planarising or inserting connection edges if (!cplanar) { bool connect = false; if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) ) { //we insert edges to make the input c-connected makeCConnected(cGraph, G, connectEdges, simpleCConnect); //save edgearray info for inserted edges for(edge e : connectEdges) { resultEdge[e] = e; orEdge[e] = e; } connect = true; CCPE.embed(cGraph, G); if ( (CCPE.errCode() == CconnectClusterPlanarEmbed::nonConnected) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCConnected) ) { cerr << "no correct connection made\n"<<flush; OGDF_THROW(AlgorithmFailureException); } }//if not cconnected if ((CCPE.errCode() == CconnectClusterPlanarEmbed::nonPlanar) || (CCPE.errCode() == CconnectClusterPlanarEmbed::nonCPlanar)) { subGraph = true; EdgeArray<bool> inSubGraph(G, false); CPlanarSubClusteredGraph cps; if (edgeWeight.valid()) cps.call(cGraph, inSubGraph, leftEdges, edgeWeight); else cps.call(cGraph, inSubGraph, leftEdges); #ifdef OGDF_DEBUG // for(edge worke : G.edges) { // if (inSubGraph[worke]) // acGraph.strokeColor(worke) = "#FF0000"; // } #endif //--------------------------------------------------------------- //now we delete the copies of all edges not in subgraph and embed //the subgraph (use a new copy) //construct copy workGraph = &GW; workCG = new ClusterGraph(cGraph, GW, resultCluster, resultNode, resultEdge); //---------------------- //reinit original arrays orNode.init(GW, nullptr); orEdge.init(GW, nullptr); orCluster.init(*workCG, nullptr); //set array entries to the appropriate values for (node workv : G.nodes) orNode[resultNode[workv]] = workv; for (edge worke : G.edges) orEdge[resultEdge[worke]] = worke; for (cluster workc : cGraph.clusters) orCluster[resultCluster[workc]] = workc; //---------------------------------------------------- //create new ACG and copy values (width, height, type) workACG = new ClusterGraphAttributes(*workCG, workACG->attributes()); for (node workv : GW.nodes) { //should set same attributes in construction!!! if (acGraph.attributes() & GraphAttributes::nodeType) workACG->type(workv) = acGraph.type(orNode[workv]); workACG->height(workv) = acGraph.height(orNode[workv]); workACG->width(workv) = acGraph.width(orNode[workv]); } if (acGraph.attributes() & GraphAttributes::edgeType) { for (edge worke : GW.edges) { workACG->type(worke) = acGraph.type(orEdge[worke]); //all other attributes are not needed or will be set } } for(edge ei : leftEdges) { edge e = resultEdge[ei]; NodePair np; np.m_src = e->source(); np.m_tgt = e->target(); leftWNodes.pushBack(np); GW.delEdge(e); } CconnectClusterPlanarEmbed CCP; #ifdef OGDF_DEBUG bool subPlanar = #endif CCP.embed(*workCG, GW); OGDF_ASSERT(subPlanar); }//if not planar else { if (!connect) OGDF_THROW_PARAM(PreconditionViolatedException, pvcClusterPlanar); } }//if //if multiple CCs are handled, the connectedges (their copies resp.) //can be deleted here //now CCPE should give us the external face ClusterPlanRep CP(*workACG, *workCG); OGDF_ASSERT(CP.representsCombEmbedding()); const int numCC = CP.numberOfCCs(); //equal to one //preliminary OGDF_ASSERT(numCC == 1); // (width,height) of the layout of each connected component Array<DPoint> boundingBox(numCC); for (int ikl = 0; ikl < numCC; ikl++) { CP.initCC(ikl); CP.setOriginalEmbedding(); OGDF_ASSERT(CP.representsCombEmbedding()) Layout drawing(CP); //m_planarLayouter.get().setOptions(4);//progressive adjEntry ae = nullptr; //internally compute adjEntry for outer face //edges that are reinserted in workGraph (in the same //order as leftWNodes) List<edge> newEdges; m_planarLayouter.get().call(CP, ae, drawing, leftWNodes, newEdges, *workGraph); OGDF_ASSERT(leftWNodes.size()==newEdges.size()) OGDF_ASSERT(leftEdges.size()==newEdges.size()) ListConstIterator<edge> itE = newEdges.begin(); ListConstIterator<edge> itEor = leftEdges.begin(); while (itE.valid()) { orEdge[*itE] = *itEor; ++itE; ++itEor; } //hash index over cluster ids HashArray<int, ClusterPosition> CA; computeClusterPositions(CP, drawing, CA); // copy layout into acGraph // Later, we move nodes and edges in each connected component, such // that no two overlap. for(int i = CP.startNode(); i < CP.stopNode(); ++i) { node vG = CP.v(i); acGraph.x(orNode[vG]) = drawing.x(CP.copy(vG)); acGraph.y(orNode[vG]) = drawing.y(CP.copy(vG)); for(adjEntry adj : vG->adjEdges) { if ((adj->index() & 1) == 0) continue; edge eG = adj->theEdge(); edge orE = orEdge[eG]; if (orE) drawing.computePolylineClear(CP,eG,acGraph.bends(orE)); } }//for //even assignment for all nodes is not enough, we need all clusters for(cluster c : workCG->clusters) { int clNumber = c->index(); //int orNumber = originalClId[c]; cluster orCl = orCluster[c]; if (c != workCG->rootCluster()) { OGDF_ASSERT(CA.isDefined(clNumber)); acGraph.height(orCl) = CA[clNumber].m_height; acGraph.width(orCl) = CA[clNumber].m_width; acGraph.y(orCl) = CA[clNumber].m_miny; acGraph.x(orCl) = CA[clNumber].m_minx; }//if real cluster } // the width/height of the layout has been computed by the planar // layout algorithm; required as input to packing algorithm boundingBox[ikl] = m_planarLayouter.get().getBoundingBox(); }//for connected components //postProcess(acGraph); // // arrange layouts of connected components // Array<DPoint> offset(numCC); m_packer.get().call(boundingBox,offset,m_pageRatio); // The arrangement is given by offset to the origin of the coordinate // system. We still have to shift each node, edge and cluster by the offset // of its connected component. const Graph::CCsInfo &ccInfo = CP.ccInfo(); for(int i = 0; i < numCC; ++i) { const double dx = offset[i].m_x; const double dy = offset[i].m_y; HashArray<int, bool> shifted(false); // iterate over all nodes in ith CC for(int j = ccInfo.startNode(i); j < ccInfo.stopNode(i); ++j) { node v = ccInfo.v(j); acGraph.x(orNode[v]) += dx; acGraph.y(orNode[v]) += dy; // update cluster positions accordingly //int clNumber = cGraph.clusterOf(orNode[v])->index(); cluster cl = cGraph.clusterOf(orNode[v]); if ((cl->index() > 0) && !shifted[cl->index()]) { acGraph.y(cl) += dy; acGraph.x(cl) += dx; shifted[cl->index()] = true; }//if real cluster for(adjEntry adj : v->adjEdges) { if ((adj->index() & 1) == 0) continue; edge e = adj->theEdge(); //edge eOr = orEdge[e]; if (orEdge[e]) { DPolyline &dpl = acGraph.bends(orEdge[e]); for(DPoint &p : dpl) { p.m_x += dx; p.m_y += dy; } } } }//for nodes }//for numcc while (!connectEdges.empty()) { G.delEdge(connectEdges.popFrontRet()); } if (subGraph) { //originalClId.init(); orCluster.init(); orNode.init(); orEdge.init(); delete workCG; delete workACG; }//if subgraph created acGraph.removeUnnecessaryBendsHV(); }//call
void Load(std::istream& input, Graph& g) { vector<string> name; char s[100]; int pos = -1; vector<int> src; vector<int> dst; while(true) { input.getline(s, 100); if(input.eof()) break; pos = Find(name, string(s)); for(int i = 0;i < 5;i++) src.push_back(pos); for(int i = 0;i < 5;i++) { input.getline(s, 100); pos = Find(name, string(s)); dst.push_back(pos); } input.getline(s, 100); if(input.eof()) break; } int n = name.size(); int* all = new int[n]; for(int i = 0;i < n;i++) all[i] = 0; int** a = new int*[n]; for(int i = 0;i < n;i++) a[i] = new int[n]; for(int i = 0;i < n;i++) for(int j = 0;j < n;j++) a[i][j] = 0; int e = src.size(); for(int i = 0;i < e;i++) { a[src[i]][dst[i]]++; all[src[i]]++; } for(int i = 0;i < n;i++) all[i] /= 5; double** w = new double*[n]; for(int i = 0;i < n;i++) w[i] = new double[n]; for(int i = 0;i < n;i++) for(int j = 0;j < n;j++) { if(all[i] == 0) all[i] = 1; if(all[j] == 0) all[j] = 1; w[i][j] = (double)(a[i][j] + a[j][i]) * 100 / (double)(all[i] + all[j]); } e = 0; for(int i = 0;i < n;i++) for(int j = 0;j < n;j++) if(w[i][j] > 0) e++; g.Reserve(n, e); e = 0; for(int i = 0;i < n;i++) { g.m_name[i] = name[i]; g.m_hash[i] = true; g.m_switch[i] = i; g.m_p[i] = e; for(int j = 0;j < n;j++) if(w[i][j] > 0) { g.m_q[e] = j; g.m_r[e] = w[i][j]; e++; } } g.m_p[n] = e; delete[] all; for(int i = 0;i < n;i++) { delete[] a[i]; delete[] w[i]; } delete[] a; delete[] w; }
void do_summary() { std::cout << "NumNodes: " << graph.size() << "\n"; std::cout << "NumEdges: " << graph.sizeEdges() << "\n"; }
void SRP(Graph g, char source, int k) { // priority queue consists of int pairs of format // <vertex, distance to vertex from source> priority_queue<pair<int, int>, vector<pair<int, int> >, Comparator > PQ; // int arrays to record distances from source to vertices, and edge counts // from source to vertices. Support max of 50 vertices int dist[50], edges[50]; // initializations of distance and path edge counts for(int i=0; i<g.size(); i++) { if(g[i] != g[source-65]); { dist[i] = 999; edges[i] = 0; } } dist[source-65] = 0; // push initial source vertex PQ.push(pair<int, int>(source-65, dist[source-65])); int v, u, w; while(!PQ.empty()) { // pop highest priority vertex for exploring u = PQ.top().first; PQ.pop(); int size = g[u].size(); // only progess to neighboring vertices if edge count is not >= k if(edges[u] < k) { for(int i=0; i<size; i++) { v = g[u][i].first; w = g[u][i].second; // checking distances for possible update or distance and // path edge count if(dist[v] > dist[u] + w) { dist[v] = dist[u] + w; PQ.push(pair<int, int>(v, dist[v])); edges[v] = edges[u]+1; } } } } ofstream outFile; outFile.open("out.txt", ios::ate | ios:: app); outFile << "\n------Shortest Reliable Path's------\nSource: " << source << ", k : " << k << endl; for(int i=0; i<g.size(); i++) { outFile << "Node " << (char)(i+65) << ": "; if(dist[i] != 999) outFile << dist[i] << ", " << edges[i] << " edges\n"; else outFile << "No path with edges < " << k << endl; } outFile << "---End of Shortest Reliable Path's---\n\n"; }
/** Find a maximum size matching in a bipartite graph * by reducing the matching problem to a max flow problem. * @param[in] g is a graph * @param[in,out] matchingEdge[u] is (on return) the matching edge incident * to u or 0 if u is unmatched; if matchingEdge is not all 0 initially, * it is assumed to represent a valid initial matching */ void matchb_f(const Graph& g, edge *matchingEdge) { // divide vertices into two independent sets ListPair split(g.n()); if (!findSplit(g,split)) Util::fatal("matchb_f: graph is not bipartite"); // create flow graph, taking care to maintain edge numbers Graph_f fg(g.n()+2, g.M()+g.n(), g.n()+1, g.n()+2); for (edge e = g.first(); e != 0; e = g.next(e)) { vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e)); fg.joinWith(u,g.mate(u,e),e); fg.setCapacity(e,1); if (e == matchingEdge[u]) fg.setFlow(e,1); } for (vertex u = split.firstIn(); u != 0; u = split.nextIn(u)) { edge e = fg.join(fg.src(),u); fg.setCapacity(e,1); if (e == matchingEdge[u]) fg.setFlow(e,1); } for (vertex u = split.firstOut(); u != 0; u = split.nextOut(u)) { edge e = fg.join(u,fg.snk()); fg.setCapacity(e,1); if (e == matchingEdge[u]) fg.setFlow(e,1); } // solve flow problem (mflo_d(fg)); // parens added to eliminate ambiguity // now construct matching from flow for (vertex u = 1; u <= g.n(); u++) matchingEdge[u] = 0; for (edge e = g.first(); e != 0; e = g.next(e)) { vertex u = (split.isIn(g.left(e)) ? g.left(e) : g.right(e)); if (fg.f(u,e) != 0) matchingEdge[u] = matchingEdge[g.mate(u,e)] = e; } }
Disassembler::Disassembler(Graph& graph) : m_graph(graph) { m_dumpContext.graph = &m_graph; m_labelForBlockIndex.resize(graph.numBlocks()); }