int ComputeKCore(const PUNGraph& G) { int cnt = 0; for(TUNGraph::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) cnt = max(cnt, NI.GetOutDeg()); THashSet <TInt> D[cnt+1]; THash <TInt, TInt> deg; for(TUNGraph::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { TInt tmp = NI.GetOutDeg() - G->IsEdge(NI.GetId(), NI.GetId() ); D[tmp.Val].AddKey(NI.GetId()); deg.AddDat(NI.GetId()) = tmp; } int max_k = 0; for(int num_iters = 0;num_iters < G->GetNodes(); num_iters++) for(int i = 0; i < cnt; i++) if(D[i].Empty() == 0) { max_k = max(max_k, i); TInt a = *(D[i].BegI()); D[i].DelKey(a); deg.AddDat(a.Val) = -1; // Hope overwriting works TUNGraph::TNodeI NI = G->GetNI(a.Val); for(int e = 0; e < NI.GetOutDeg(); e++) { TInt b = NI.GetOutNId(e); if(deg.GetDat(b) >= 0) { int Id = deg.GetKeyId(b); D[deg[Id].Val].DelKey(b); deg[Id] = deg[Id] - 1; //Hope the overwriting works D[deg[Id]].AddKey(b); } } break; } return max_k; }
void UndirCopy(PNGraph& dir_graph, PUNGraph& undir_graph) { // Add all of the nodes into the new graph for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); undir_graph->AddNode(curr_node); } for (TNGraph::TNodeI node = dir_graph->BegNI(); node < dir_graph->EndNI(); node++) { int curr_node = node.GetId(); for (int e = 0; e < node.GetOutDeg(); ++e) { int nbr_node = node.GetOutNId(e); if (!undir_graph->IsEdge(curr_node, nbr_node)) { undir_graph->AddEdge(curr_node, nbr_node); } } } }
// Test node, edge creation void ManipulateNodesEdges() { int NNodes = 10000; int NEdges = 100000; const char *FName = "test.graph"; PUNGraph Graph; PUNGraph Graph1; PUNGraph Graph2; int i; int n; int NCount; int ECount1; int ECount2; int x,y; bool t; Graph = TUNGraph::New(); t = Graph->Empty(); // create the nodes for (i = 0; i < NNodes; i++) { Graph->AddNode(i); } t = Graph->Empty(); n = 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--; } } PrintGStats("ManipulateNodesEdges:Graph",Graph); // get all the nodes NCount = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } // get all the edges for all the nodes ECount1 = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { ECount1++; } } ECount1 /= 2; // get all the edges directly ECount2 = 0; for (TUNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { ECount2++; } printf("graph ManipulateNodesEdges:Graph, nodes %d, edges1 %d, edges2 %d\n", NCount, ECount1, ECount2); // assignment Graph1 = TUNGraph::New(); *Graph1 = *Graph; PrintGStats("ManipulateNodesEdges:Graph1",Graph1); // save the graph { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); } // load the graph { TFIn FIn(FName); Graph2 = TUNGraph::Load(FIn); } PrintGStats("ManipulateNodesEdges:Graph2",Graph2); // remove all the nodes and edges for (i = 0; i < NNodes; i++) { n = Graph->GetRndNId(); Graph->DelNode(n); } PrintGStats("ManipulateNodesEdges:Graph",Graph); Graph1->Clr(); PrintGStats("ManipulateNodesEdges:Graph1",Graph1); }
void GetMotifCount(const PUNGraph& G, const int MotifSize, TVec <int64> & MotifV, const int num) { if (MotifSize == 3) { MotifV = TVec <int64> (2); MotifV.PutAll(0); TSnap::GetTriads(G,MotifV[mtThreeClosed],MotifV[mtThreeOpen],num); } else { MotifV = TVec <int64> (6); MotifV.PutAll(0); TIntPrV V(G->GetEdges(), 0); for (TUNGraph::TEdgeI EI = G->BegEI(); EI < G->EndEI(); EI++) { V.Add(TIntPr(EI.GetSrcNId(), EI.GetDstNId())); } TRnd blargh; V.Shuffle(blargh); for (int z = 0; z < num; z++) { int SrcNId = V[z].Val1.Val, DstNId = V[z].Val2.Val; TUNGraph::TNodeI SrcNI = G->GetNI(SrcNId), DstNI = G->GetNI(DstNId); TIntV SrcV(SrcNI.GetOutDeg(),0), DstV(DstNI.GetOutDeg(),0), BothV(min(SrcNI.GetOutDeg(), DstNI.GetOutDeg()),0); SrcV.Clr(0,-1); DstV.Clr(0,-1); BothV.Clr(0,-1); //Grouping the vertices into sets for (int e = 0; e < SrcNI.GetOutDeg(); e++) { if (SrcNI.GetOutNId(e) == DstNId) continue; if (G->IsEdge(DstNId, SrcNI.GetOutNId(e)) ) { BothV.Add(SrcNI.GetOutNId(e)); } else { SrcV.Add(SrcNI.GetOutNId(e)); } } for (int e = 0; e < DstNI.GetOutDeg(); e++) { if (DstNI.GetOutNId(e) == SrcNId) continue; if (G->IsEdge(SrcNId, DstNI.GetOutNId(e)) == 0) { DstV.Add(DstNI.GetOutNId(e)); } } //Compute Motif 0 and 1 for (int i = 0; i < SrcV.Len(); i++) { for (int j = 0; j < DstV.Len(); j++) { if (G->IsEdge(SrcV[i], DstV[j]) ) { MotifV[mfFourSquare]++; } else MotifV[mfFourLine]++; } } //Compute Motif 2 and 3 for (int i = 0; i < SrcV.Len(); i++) { for (int j = i + 1; j < SrcV.Len(); j++) { if (G->IsEdge(SrcV[i], SrcV[j]) ) { MotifV[mfFourTriangleEdge]++; } else MotifV[mfFourStar]++; } } for (int i = 0; i < DstV.Len(); i++) { for (int j = i + 1; j < DstV.Len(); j++) { if (G->IsEdge(DstV[i], DstV[j]) ) { MotifV[mfFourTriangleEdge]++; } else MotifV[mfFourStar]++; } } //Compute Motif 4 and 5 for (int i = 0; i < BothV.Len(); i++) { for (int j = i + 1; j < BothV.Len(); j++) { if (G->IsEdge(BothV[i], BothV[j]) ) { MotifV[mfFourComplete]++; } else MotifV[mfFourSquareDiag]++; } } } MotifV[mfFourSquare] /= 4ll; MotifV[mfFourStar] /= 3ll; MotifV[mfFourComplete] /= 6ll; } }
// Test node, edge creation TEST(TUNGraph, ManipulateNodesEdges) { int NNodes = 10000; int NEdges = 100000; const char *FName = "test.graph"; PUNGraph Graph; PUNGraph Graph1; PUNGraph Graph2; int i; int n; int NCount; int x,y; int Deg, InDeg, OutDeg; Graph = TUNGraph::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 (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } EXPECT_EQ(NNodes,NCount); // edges per node iterator NCount = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { NCount++; } } EXPECT_EQ(NEdges*2,NCount); // edges iterator NCount = 0; for (TUNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { NCount++; } EXPECT_EQ(NEdges,NCount); // node degree for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Deg = NI.GetDeg(); InDeg = NI.GetInDeg(); OutDeg = NI.GetOutDeg(); EXPECT_EQ(Deg,InDeg); EXPECT_EQ(Deg,OutDeg); } // assignment Graph1 = TUNGraph::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 = TUNGraph::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()); }