// Save and load directed, undirected and multi-graphs as list of edges, where nodes are ids void SaveLoadEdgeList() { const int NNodes = 500; const int NEdges = 2000; const char *FName = "demo.graph.dat"; const char *Desc = "Randomly generated graph for input/output."; PNGraph GOut, GIn; GOut = GenRndGnm<PNGraph>(NNodes, NEdges); // Output node IDs as numbers SaveEdgeList(GOut, FName, Desc); // Load edge list GIn = LoadEdgeList<PNGraph>(FName); // Verify all nodes exist in input and output graphs THashSet<TInt> OutNIdH, InNIdH; for (TNGraph::TNodeI NI = GOut->BegNI(); NI < GOut->EndNI(); NI++) { // Nodes that do not have edges are left off during input if (NI.GetDeg() > 0) { OutNIdH.AddKey(NI.GetId()); } } for (TNGraph::TNodeI NI = GIn->BegNI(); NI < GIn->EndNI(); NI++) { InNIdH.AddKey(NI.GetId()); } PrintGStats<PNGraph>("EdgeList - Out", GOut); PrintGStats<PNGraph>("EdgeList - In", GIn); }
// Saves and loads a graph in a MATLAB sparse matrix format void IOMatlabSparseMtx() { const int NNodes = 500; const int NEdges = 2000; const char *FName = "demo.matlab.dat"; PNGraph GOut, GIn; GOut = GenRndGnm<PNGraph>(NNodes, NEdges); SaveMatlabSparseMtx(GOut, FName); GIn = TNGraph::New(); GIn->Reserve(NNodes, NEdges); // Read-in Matlab-file FILE *F = fopen(FName, "r"); while (! feof(F)) { int Src, Dst, Edge; fscanf(F, "%d %d %d\n", &Src, &Dst, &Edge); Src--; Dst--; // SNAP graphs start at Node Ids of 0 if (not GIn->IsNode(Src)) { GIn->AddNode(Src); } if (not GIn->IsNode(Dst)) { GIn->AddNode(Dst); } GIn->AddEdge(Src, Dst); } fclose(F); // Verify all nodes exist in input and output graphs (and no more) THashSet<TInt> OutNIdH, InNIdH; for (TNGraph::TNodeI NI = GOut->BegNI(); NI < GOut->EndNI(); NI++) { // Nodes that do not have edges are left off during input if (NI.GetDeg() > 0) { OutNIdH.AddKey(NI.GetId()); } } for (TNGraph::TNodeI NI = GIn->BegNI(); NI < GIn->EndNI(); NI++) { InNIdH.AddKey(NI.GetId()); } PrintGStats("Matlab - Out", GOut); PrintGStats("Matlab - In", GIn); }
// Rok #13 //template<class PGraph> int64 CountTriangles1(const TVec<TNGraph::TNodeI,int>& NV, const TIntV& IndV, const TIntV& MapV) { struct timeval start, end; float delta; TTmProfiler Profiler; int TimerId = Profiler.AddTimer("Profiler"); int ind = MapV.Len(); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); TVec<TIntV> HigherDegNbrV(ind); for (int i = 0; i < ind; i++) { HigherDegNbrV[i] = TVec<TInt>(); HigherDegNbrV[i].Reserve(NV[i].GetDeg()); HigherDegNbrV[i].Reduce(0); } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__valloc__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); #pragma omp parallel for schedule(dynamic) for (TInt i = 0; i < ind; i++) { TNGraph::TNodeI NI = NV[i]; //HigherDegNbrV[i] = TVec<TInt>(); //HigherDegNbrV[i].Reserve(NI.GetDeg()); //HigherDegNbrV[i].Reduce(0); GetMergeSortedV(HigherDegNbrV[i], NI); int k = 0; for (TInt j = 0; j < HigherDegNbrV[i].Len(); j++) { TInt Vert = HigherDegNbrV[i][j]; TInt Deg = NV[IndV[Vert]].GetDeg(); if (Deg > NI.GetDeg() || (Deg == NI.GetDeg() && Vert > NI.GetId())) { HigherDegNbrV[i][k] = Vert; k++; } } HigherDegNbrV[i].Reduce(k); } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__sort__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); int64 cnt = 0; #pragma omp parallel for schedule(dynamic) reduction(+:cnt) for (TInt i = 0; i < HigherDegNbrV.Len(); i++) { for (TInt j = 0; j < HigherDegNbrV[i].Len(); j++) { //TInt NbrInd = H.GetDat(HigherDegNbrV[i][j]); TInt NbrInd = IndV[HigherDegNbrV[i][j]]; int64 num = GetCommon(HigherDegNbrV[i], HigherDegNbrV[NbrInd]); cnt += num; } } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__count__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); return cnt; }
int64 CountTriangles2(const PNGraph &Graph) { struct timeval start, end; float delta; TTmProfiler Profiler; int TimerId = Profiler.AddTimer("Profiler"); const int NNodes = Graph->GetNodes(); TIntV MapV(NNodes); TVec<TNGraph::TNodeI> NV(NNodes); NV.Reduce(0); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); int MxId = -1; int ind = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NV.Add(NI); int Id = NI.GetId(); if (Id > MxId) { MxId = Id; } MapV[ind] = Id; ind++; } TIntV IndV(MxId+1); for (int j = 0; j < NNodes; j++) { IndV[MapV[j]] = j; } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__nodemap__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); ind = MapV.Len(); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); TVec<TIntV> HigherDegNbrV(ind); for (int i = 0; i < ind; i++) { HigherDegNbrV[i] = TVec<TInt>(); HigherDegNbrV[i].Reserve(NV[i].GetDeg()); HigherDegNbrV[i].Reduce(0); } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__valloc__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); #pragma omp parallel for schedule(dynamic) for (TInt i = 0; i < ind; i++) { TNGraph::TNodeI NI = NV[i]; //HigherDegNbrV[i] = TVec<TInt>(); //HigherDegNbrV[i].Reserve(NI.GetDeg()); //HigherDegNbrV[i].Reduce(0); GetMergeSortedV(HigherDegNbrV[i], NI); int k = 0; for (TInt j = 0; j < HigherDegNbrV[i].Len(); j++) { TInt Vert = HigherDegNbrV[i][j]; TInt Deg = NV[IndV[Vert]].GetDeg(); if (Deg > NI.GetDeg() || (Deg == NI.GetDeg() && Vert > NI.GetId())) { HigherDegNbrV[i][k] = Vert; k++; } } HigherDegNbrV[i].Reduce(k); } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__sort__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); Profiler.ResetTimer(TimerId); Profiler.StartTimer(TimerId); gettimeofday(&start, NULL); int64 cnt = 0; #pragma omp parallel for schedule(dynamic) reduction(+:cnt) for (TInt i = 0; i < HigherDegNbrV.Len(); i++) { for (TInt j = 0; j < HigherDegNbrV[i].Len(); j++) { //TInt NbrInd = H.GetDat(HigherDegNbrV[i][j]); TInt NbrInd = IndV[HigherDegNbrV[i][j]]; int64 num = GetCommon(HigherDegNbrV[i], HigherDegNbrV[NbrInd]); cnt += num; } } gettimeofday(&end, NULL); Profiler.StopTimer(TimerId); delta = ((end.tv_sec - start.tv_sec) * 1000000u + end.tv_usec - start.tv_usec) / 1.e6; printf("__count__\ttime %7.3f\tcpu %8.3f\n", delta, Profiler.GetTimerSec(TimerId)); return cnt; }
// Test node, edge creation TEST(TNGraph, ManipulateNodesEdges) { int NNodes = 10000; int NEdges = 100000; const char *FName = "test.graph.dat"; PNGraph Graph; PNGraph Graph1; PNGraph Graph2; int i; int n; int NCount; int x,y; int Deg, InDeg, OutDeg; Graph = TNGraph::New(); EXPECT_EQ(1,Graph->Empty()); // create the nodes for (i = 0; i < NNodes; i++) { Graph->AddNode(i); } EXPECT_EQ(0,Graph->Empty()); EXPECT_EQ(NNodes,Graph->GetNodes()); // create random edges NCount = NEdges; while (NCount > 0) { x = (long) (drand48() * NNodes); y = (long) (drand48() * NNodes); // Graph->GetEdges() is not correct for the loops (x == y), // skip the loops in this test if (x != y && !Graph->IsEdge(x,y)) { n = Graph->AddEdge(x, y); NCount--; } } EXPECT_EQ(NEdges,Graph->GetEdges()); EXPECT_EQ(0,Graph->Empty()); EXPECT_EQ(1,Graph->IsOk()); for (i = 0; i < NNodes; i++) { EXPECT_EQ(1,Graph->IsNode(i)); } EXPECT_EQ(0,Graph->IsNode(NNodes)); EXPECT_EQ(0,Graph->IsNode(NNodes+1)); EXPECT_EQ(0,Graph->IsNode(2*NNodes)); // nodes iterator NCount = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } EXPECT_EQ(NNodes,NCount); // edges per node iterator NCount = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { NCount++; } } EXPECT_EQ(NEdges,NCount); // edges iterator NCount = 0; for (TNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { NCount++; } EXPECT_EQ(NEdges,NCount); // node degree for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Deg = NI.GetDeg(); InDeg = NI.GetInDeg(); OutDeg = NI.GetOutDeg(); EXPECT_EQ(Deg,InDeg+OutDeg); } // assignment Graph1 = TNGraph::New(); *Graph1 = *Graph; EXPECT_EQ(NNodes,Graph1->GetNodes()); EXPECT_EQ(NEdges,Graph1->GetEdges()); EXPECT_EQ(0,Graph1->Empty()); EXPECT_EQ(1,Graph1->IsOk()); // saving and loading { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); } { TFIn FIn(FName); Graph2 = TNGraph::Load(FIn); } EXPECT_EQ(NNodes,Graph2->GetNodes()); EXPECT_EQ(NEdges,Graph2->GetEdges()); EXPECT_EQ(0,Graph2->Empty()); EXPECT_EQ(1,Graph2->IsOk()); // remove all the nodes and edges for (i = 0; i < NNodes; i++) { n = Graph->GetRndNId(); Graph->DelNode(n); } EXPECT_EQ(0,Graph->GetNodes()); EXPECT_EQ(0,Graph->GetEdges()); EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(1,Graph->Empty()); Graph1->Clr(); EXPECT_EQ(0,Graph1->GetNodes()); EXPECT_EQ(0,Graph1->GetEdges()); EXPECT_EQ(1,Graph1->IsOk()); EXPECT_EQ(1,Graph1->Empty()); }