//---------------------------------------------------------------- void GraphView::addEdgesInternal(unsigned int nbAdded, const std::vector<edge> *ee, const std::vector<std::pair<node, node>> &ends) { _edges.reserve(_edges.size() + nbAdded); bool hasEnds = !ends.empty(); unsigned int i = 0; std::vector<edge>::const_iterator it; if (ee) it = ee->begin(); else { ee = &getSuperGraph()->edges(); it = ee->begin() + ee->size() - nbAdded; } std::vector<edge>::const_iterator ite = ee->end(); for (; it != ite; ++it, ++i) { edge e = *it; assert(getRootImpl()->isElement(e)); _edges.add(e); std::pair<node, node> eEnds(hasEnds ? ends[i] : this->ends(e)); node src = eEnds.first; node tgt = eEnds.second; _nodeData.get(src.id)->outDegreeAdd(1); _nodeData.get(tgt.id)->inDegreeAdd(1); } if (hasOnlookers()) sendEvent(GraphEvent(*this, GraphEvent::TLP_ADD_EDGES, nbAdded)); }
TEST_F(DynSSSPGTest, testDynamicDijkstraBatches) { METISGraphReader reader; std::default_random_engine random_generator; std::normal_distribution<double> distribution(100,10); DorogovtsevMendesGenerator generator(100); Graph G1 = generator.generate(); Graph G(G1, true, false); DEBUG("Generated graph of dimension ", G.upperNodeIdBound()); // add random normal weights to G G.forNodes([&] (node source) { DynDijkstra dyn_dij(G, source, true); Dijkstra dij(G, source); dyn_dij.run(); dij.run(); DEBUG("Before the edge insertion: "); GraphEvent ev; count batchSize = 8; count nBatches = 1, i = 0; for (count j=0; j<nBatches; j++) { std::vector<GraphEvent> batch; i = 0; while (i < batchSize) { DEBUG("Sampling a new edge"); node v1 = Sampling::randomNode(G); node v2 = Sampling::randomNode(G); if (v1 != v2 && !G.hasEdge(v1, v2)) { i++; double number = distribution(random_generator); G.addEdge(v1, v2, number); batch.push_back(GraphEvent(GraphEvent::EDGE_ADDITION, v1, v2, number)); } } DEBUG("batch size: ", batch.size()); DEBUG("Updating with dynamic dijkstra"); dyn_dij.update(batch); DEBUG("Running from scratch with dijkstra"); dij.run(); G.forNodes([&] (node i) { // std::cout<<"Node "<<i<<":"<<std::endl; // std::cout<<"Actual distance: "<<dij.distance(i)<<", computed distance: "<<ddij.distance(i)<<std::endl; // std::cout<<"Actual number of paths: "<<dij.numberOfPaths(i)<<", computed one: "<<ddij.numberOfPaths(i)<<std::endl; EXPECT_EQ(dyn_dij.distance(i), dij.distance(i)); EXPECT_EQ(dyn_dij.numberOfPaths(i), dij.numberOfPaths(i)); if (i != source) assert(dyn_dij.distance(i) != 0); // EXPECT_EQ(dyn_dij.getPredecessors(i).size(), dij.getPredecessors(i).size()); }); } }); }
TEST_F(DynSSSPGTest, testDynamicDijkstraGeneratedGraph) { METISGraphReader reader; DorogovtsevMendesGenerator generator(1000); Graph G1 = generator.generate(); Graph G(G1, true, false); DEBUG("Generated graph of dimension ", G.upperNodeIdBound()); DynDijkstra dyn_dij(G, 0); Dijkstra dij(G, 0); dyn_dij.run(); dij.run(); DEBUG("Before the edge insertion: "); GraphEvent ev; count nInsertions = 10, i = 0; while (i < nInsertions) { DEBUG("Sampling a new edge"); node v1 = Sampling::randomNode(G); node v2 = Sampling::randomNode(G); if (v1 != v2 && !G.hasEdge(v1, v2)) { i++; DEBUG("Adding edge number ", i); G.addEdge(v1, v2); std::vector<GraphEvent> batch; batch.push_back(GraphEvent(GraphEvent::EDGE_ADDITION, v1, v2, 1.0)); DEBUG("Running update with dynamic dijkstra"); dyn_dij.update(batch); DEBUG("Running from scratch with dijkstra"); dij.run(); G.forNodes([&] (node i) { // std::cout<<"Node "<<i<<":"<<std::endl; // std::cout<<"Actual distance: "<<dij.distance(i)<<", computed distance: "<<ddij.distance(i)<<std::endl; // std::cout<<"Actual number of paths: "<<dij.numberOfPaths(i)<<", computed one: "<<ddij.numberOfPaths(i)<<std::endl; EXPECT_EQ(dyn_dij.distance(i), dij.distance(i)); EXPECT_EQ(dyn_dij.numberOfPaths(i), dij.numberOfPaths(i)); }); } } }
//---------------------------------------------------------------- void GraphView::addNodesInternal(unsigned int nbAdded, const std::vector<node> *nodes) { _nodes.reserve(_nodes.size() + nbAdded); std::vector<node>::const_iterator it; if (nodes) it = nodes->begin(); else { nodes = &getSuperGraph()->nodes(); it = nodes->begin() + nodes->size() - nbAdded; } std::vector<node>::const_iterator ite = nodes->end(); for (; it != ite; ++it) { node n(*it); assert(getRootImpl()->isElement(n)); _nodeData.set(n.id, new SGraphNodeData()); _nodes.add(n); } if (hasOnlookers()) sendEvent(GraphEvent(*this, GraphEvent::TLP_ADD_NODES, nbAdded)); }
std::vector<GraphEvent> NetworKit::DGSStreamParser::getStream() { if (! dgsFile.is_open()) { throw std::runtime_error("DGS input file could not be opened."); } std::vector<GraphEvent> stream; // stream containing the events std::string line; count lc = 0; // line count std::string cookie = "DGS004"; std::getline(dgsFile, line); // get DGS version lc++; if (line.compare(0, cookie.size(), cookie)) { ERROR("found " , line , " instead of " , cookie , " in first line"); throw std::runtime_error("expected cookie in first line"); } std::getline(dgsFile, line); lc++; INFO("DGS stream description: ", line); if (mapped) { // mapped format /** * Maps key string to consecutive, 0-based node id. */ auto map = [&](std::string key) { auto iter = this->key2id.find(key); if (iter == key2id.end()) { key2id[key] = nextNode; nextNode++; return key2id[key]; } else { return iter->second; } }; while (std::getline(dgsFile, line)) { // TRACE(line); lc++; std::vector<std::string> split = Aux::StringTools::split(line); // TRACE("split line: ", split); std::string tag = split[0]; // TODO: remove TRACE // parse commands if (tag.compare("st") == 0) { // clock stream.push_back(GraphEvent(GraphEvent::TIME_STEP)); } else if (tag.compare("an") == 0) { // add node node u = map(split[1]); auto ev = GraphEvent(GraphEvent::NODE_ADDITION, u); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("ae") == 0) { // add edge node u = map(split[2]); node v = map(split[3]); edgeweight w = 1.0; if (split.size() >= 5) { w = std::stod(Aux::StringTools::split(split[4], '=')[1]); // weight=<w> } auto ev = GraphEvent(GraphEvent::EDGE_ADDITION, u, v, w); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("ce") == 0) { // update edge. Only the "weight" attribute is supported so far std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = map(uvs[0]); node v = map(uvs[1]); edgeweight w = std::stod(Aux::StringTools::split(split[2], '=')[1]); // weight=<w> auto ev = GraphEvent(GraphEvent::EDGE_WEIGHT_UPDATE, u, v, w); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("ie") == 0) { // update edge. Only the "weight" attribute is supported so far std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = map(uvs[0]); node v = map(uvs[1]); edgeweight w = std::stod(Aux::StringTools::split(split[2], '=')[1]); // weight=<w> auto ev = GraphEvent(GraphEvent::EDGE_WEIGHT_INCREMENT, u, v, w); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("de") == 0) { std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = map(uvs[0]); node v = map(uvs[1]); auto ev = GraphEvent(GraphEvent::EDGE_REMOVAL, u, v); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("dn") == 0) { node u = map(split[1]); auto ev = GraphEvent(GraphEvent::NODE_REMOVAL, u); // TRACE(ev.toString()); stream.push_back(ev); } else if (tag.compare("rn") == 0) { node u = map(split[1]); auto ev = GraphEvent(GraphEvent::NODE_RESTORATION, u); // TRACE(ev.toString()); stream.push_back(ev); } else { ERROR("malformed line (" , lc , ") : " , line); throw std::runtime_error("malformed line in .DGS file"); } } } else { // direct format auto offset = [&](node u) { return (u - baseIndex); }; while (std::getline(dgsFile, line)) { // TRACE(line); lc++; std::vector<std::string> split = Aux::StringTools::split(line); std::string tag = split[0]; // parse commands if (tag.compare("st") == 0) { // clock stream.push_back(GraphEvent(GraphEvent::TIME_STEP)); // TRACE("read: st "); } else if (tag.compare("an") == 0) { // add node node u = offset(std::stoul(split[1])); stream.push_back(GraphEvent(GraphEvent::NODE_ADDITION, u)); // TRACE("read: an ", u); } else if (tag.compare("ae") == 0) { // add edge node u = offset(std::stoul(split[2])); node v = offset(std::stoul(split[3])); edgeweight w = std::stod(Aux::StringTools::split(split[4], '=')[1]); // weight=<w> stream.push_back(GraphEvent(GraphEvent::EDGE_ADDITION, u, v, w)); // TRACE("read: ae ", u, ",", v, ",", w); } else if (tag.compare("ce") == 0) { // update edge. Only the "weight" attribute is supported so far std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = offset(std::stoul(uvs[0])); node v = offset(std::stoul(uvs[1])); edgeweight w = std::stod(Aux::StringTools::split(split[2], '=')[1]); // weight=<w> stream.push_back(GraphEvent(GraphEvent::EDGE_WEIGHT_UPDATE, u, v, w)); // TRACE("read: ce ", u, ",", v, ",", w); } else if (tag.compare("ie") == 0) { // update edge. Only the "weight" attribute is supported so far std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = offset(std::stoul(uvs[0])); node v = offset(std::stoul(uvs[1])); edgeweight w = std::stod(Aux::StringTools::split(split[2], '=')[1]); // weight=<w> stream.push_back(GraphEvent(GraphEvent::EDGE_WEIGHT_INCREMENT, u, v, w)); // TRACE("read: ce ", u, ",", v, ",", w); } else if (tag.compare("de") == 0) { std::vector<std::string> uvs = Aux::StringTools::split(split[1], '-'); node u = offset(std::stoul(uvs[0])); node v = offset(std::stoul(uvs[1])); stream.push_back(GraphEvent(GraphEvent::EDGE_REMOVAL, u, v)); // TRACE("read: de ", u, ",", v); } else if (tag.compare("dn") == 0) { node u = offset(std::stoul(split[1])); stream.push_back(GraphEvent(GraphEvent::NODE_REMOVAL, u)); // TRACE("read: dn ", u); } else if (tag.compare("rn") == 0) { node u = offset(std::stoul(split[1])); stream.push_back(GraphEvent(GraphEvent::NODE_RESTORATION, u)); TRACE("read: rn ", u); } else { ERROR("malformed line (" , lc , ") : " , line); throw std::runtime_error("malformed line in .DGS file"); } } } return stream; }