void TAGMFast::SetGraph(const PUNGraph& GraphPt) { G = GraphPt; HOVIDSV.Gen(G->GetNodes()); NodesOk = true; GraphPt->GetNIdV(NIDV); // check that nodes IDs are {0,1,..,Nodes-1} for (int nid = 0; nid < GraphPt->GetNodes(); nid++) { if (! GraphPt->IsNode(nid)) { NodesOk = false; break; } } if (! NodesOk) { printf("rearrage nodes\n"); G = TSnap::GetSubGraph(GraphPt, NIDV, true); for (int nid = 0; nid < G->GetNodes(); nid++) { IAssert(G->IsNode(nid)); } } TSnap::DelSelfEdges(G); PNoCom = 1.0 / (double) G->GetNodes(); DoParallel = false; if (1.0 / PNoCom > sqrt(TFlt::Mx)) { PNoCom = 0.99 / sqrt(TFlt::Mx); } // to prevent overflow NegWgt = 1.0; }
// actors collaboration graph PUNGraph TImdbNet::GetActorGraph() const { TIntPrSet EdgeSet; for (TNodeI NI = BegNI(); NI < EndNI(); NI++) { if (NI().GetTy() == mtyActor) { const int NId1 = NI.GetId(); for (int e = 0; e < NI.GetOutDeg(); e++) { if (NI.GetOutNDat(e).GetTy() != mtyActor) { TNodeI NI2 = GetNI(NI.GetOutNId(e)); for (int e2 = 0; e2 < NI2.GetInDeg(); e2++) { if (NI2.GetInNDat(e2).GetTy() == mtyActor) { const int NId2 = NI2.GetInNId(e2); EdgeSet.AddKey(TIntPr(TMath::Mn(NId1, NId2), TMath::Mx(NId1, NId2))); } } } } } } PUNGraph G = TUNGraph::New(); for (int i = 0; i < EdgeSet.Len(); i++) { const int NId1 = EdgeSet[i].Val1; const int NId2 = EdgeSet[i].Val2; if (! G->IsNode(NId1)) { G->AddNode(NId1); } if (! G->IsNode(NId2)) { G->AddNode(NId2); } G->AddEdge(NId1, NId2); } return G; }
double TAGMUtil::GetConductance(const PUNGraph& Graph, const TIntSet& CmtyS, const int Edges) { const int Edges2 = Edges >= 0 ? 2*Edges : Graph->GetEdges(); int Vol = 0, Cut = 0; double Phi = 0.0; for (int i = 0; i < CmtyS.Len(); i++) { if (! Graph->IsNode(CmtyS[i])) { continue; } TUNGraph::TNodeI NI = Graph->GetNI(CmtyS[i]); for (int e = 0; e < NI.GetOutDeg(); e++) { if (! CmtyS.IsKey(NI.GetOutNId(e))) { Cut += 1; } } Vol += NI.GetOutDeg(); } // get conductance if (Vol != Edges2) { if (2 * Vol > Edges2) { Phi = Cut / double (Edges2 - Vol); } else if (Vol == 0) { Phi = 0.0; } else { Phi = Cut / double(Vol); } } else { if (Vol == Edges2) { Phi = 1.0; } } return Phi; }
///Generate graph using the AGM model. CProbV = vector of Pc PUNGraph TAGM::GenAGM(TVec<TIntV>& CmtyVV, const TFltV& CProbV, TRnd& Rnd, const double PNoCom) { PUNGraph G = TUNGraph::New(100 * CmtyVV.Len(), -1); printf("AGM begins\n"); for (int i = 0; i < CmtyVV.Len(); i++) { TIntV& CmtyV = CmtyVV[i]; for (int u = 0; u < CmtyV.Len(); u++) { if ( G->IsNode(CmtyV[u])) { continue; } G->AddNode(CmtyV[u]); } double Prob = CProbV[i]; RndConnectInsideCommunity(G, CmtyV, Prob, Rnd); } if (PNoCom > 0.0) { //if we want to connect nodes that do not share any community TIntSet NIDS; for (int c = 0; c < CmtyVV.Len(); c++) { for (int u = 0; u < CmtyVV[c].Len(); u++) { NIDS.AddKey(CmtyVV[c][u]); } } TIntV NIDV; NIDS.GetKeyV(NIDV); RndConnectInsideCommunity(G,NIDV,PNoCom,Rnd); } printf("AGM completed (%d nodes %d edges)\n",G->GetNodes(),G->GetEdges()); G->Defrag(); return G; }
double GetGroupDegreeCentr(const PUNGraph& Graph, const PUNGraph& Group) { int deg; TIntH NN; for (TUNGraph::TNodeI NI = Group->BegNI(); NI < Group->EndNI(); NI++) { deg = Graph->GetNI(NI.GetId()).GetDeg(); for (int i = 0; i<deg; i++) { if (Group->IsNode(Graph->GetNI(NI.GetId()).GetNbrNId(i)) == 0) NN.AddDat(Graph->GetNI(NI.GetId()).GetNbrNId(i), NI.GetId()); } } return (double)NN.Len(); }
/// Generates a random scale-free graph using the Geometric Preferential /// Attachment model by Flexman, Frieze and Vera. /// See: A geometric preferential attachment model of networks by Flexman, /// Frieze and Vera. WAW 2004. /// URL: http://math.cmu.edu/~af1p/Texfiles/GeoWeb.pdf PUNGraph GenGeoPrefAttach(const int& Nodes, const int& OutDeg, const double& Beta, TRnd& Rnd) { PUNGraph G = TUNGraph::New(Nodes, Nodes*OutDeg); TFltTrV PointV(Nodes, 0); TFltV ValV; // points on a sphere of radius 1/(2*pi) const double Rad = 0.5 * TMath::Pi; for (int i = 0; i < Nodes; i++) { TSnapDetail::GetSphereDev(3, Rnd, ValV); PointV.Add(TFltTr(Rad*ValV[0], Rad*ValV[1], Rad*ValV[2])); } const double R2 = TMath::Sqr(log((double) Nodes) / (pow((double) Nodes, 0.5-Beta))); TIntV DegV, NIdV; int SumDeg; for (int t = 0; t < Nodes; t++) { const int pid = t; const TFltTr& P1 = PointV[pid]; // add node if (! G->IsNode(pid)) { G->AddNode(pid); } // find neighborhood DegV.Clr(false); NIdV.Clr(false); SumDeg=0; for (int p = 0; p < t; p++) { const TFltTr& P2 = PointV[p]; if (TMath::Sqr(P1.Val1-P2.Val1)+TMath::Sqr(P1.Val2-P2.Val2)+TMath::Sqr(P1.Val3-P2.Val3) < R2) { NIdV.Add(p); DegV.Add(G->GetNI(p).GetDeg()+1); SumDeg += DegV.Last(); } } // add edges for (int m = 0; m < OutDeg; m++) { const int rnd = Rnd.GetUniDevInt(SumDeg); int sum = 0, dst = -1; for (int s = 0; s < DegV.Len(); s++) { sum += DegV[s]; if (rnd < sum) { dst=s; break; } } if (dst != -1) { G->AddEdge(pid, NIdV[dst]); SumDeg -= DegV[dst]; NIdV.Del(dst); DegV.Del(dst); } } } return G; }
// RenumberNodes ... Renumber node ids in the subgraph to 0...N-1 PUNGraph GetSubGraph(const PUNGraph& Graph, const TIntV& NIdV, const bool& RenumberNodes) { //if (! RenumberNodes) { return TSnap::GetSubGraph(Graph, NIdV); } PUNGraph NewGraphPt = TUNGraph::New(); TUNGraph& NewGraph = *NewGraphPt; NewGraph.Reserve(NIdV.Len(), -1); TIntSet NIdSet(NIdV.Len()); for (int n = 0; n < NIdV.Len(); n++) { if (Graph->IsNode(NIdV[n])) { NIdSet.AddKey(NIdV[n]); if (! RenumberNodes) { NewGraph.AddNode(NIdV[n]); } else { NewGraph.AddNode(NIdSet.GetKeyId(NIdV[n])); } } } if (! RenumberNodes) { for (int n = 0; n < NIdSet.Len(); n++) { const int SrcNId = NIdSet[n]; const TUNGraph::TNodeI NI = Graph->GetNI(SrcNId); for (int edge = 0; edge < NI.GetOutDeg(); edge++) { const int OutNId = NI.GetOutNId(edge); if (NIdSet.IsKey(OutNId)) { NewGraph.AddEdge(SrcNId, OutNId); } } } } else { for (int n = 0; n < NIdSet.Len(); n++) { const int SrcNId = NIdSet[n]; const TUNGraph::TNodeI NI = Graph->GetNI(SrcNId); for (int edge = 0; edge < NI.GetOutDeg(); edge++) { const int OutNId = NI.GetOutNId(edge); if (NIdSet.IsKey(OutNId)) { NewGraph.AddEdge(NIdSet.GetKeyId(SrcNId), NIdSet.GetKeyId(OutNId)); } } } } return NewGraphPt; }
// 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()); }