void GetEigenVectorCentr(const PUNGraph& Graph, TIntFltH& EigenH, const double& Eps, const int& MaxIter) { const int NNodes = Graph->GetNodes(); EigenH.Gen(NNodes); for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { EigenH.AddDat(NI.GetId(), 1.0/NNodes); IAssert(NI.GetId() == EigenH.GetKey(EigenH.Len()-1)); } TFltV TmpV(NNodes); double diff = TFlt::Mx; for (int iter = 0; iter < MaxIter; iter++) { int j = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { TmpV[j] = 0; for (int e = 0; e < NI.GetOutDeg(); e++) { TmpV[j] += EigenH.GetDat(NI.GetOutNId(e)); } } double sum = 0; for (int i = 0; i < TmpV.Len(); i++) { EigenH[i] = TmpV[i]; sum += EigenH[i]; } for (int i = 0; i < EigenH.Len(); i++) { EigenH[i] /= sum; } if (fabs(diff-sum) < Eps) { break; } //printf("\tdiff:%f\tsum:%f\n", fabs(diff-sum), sum); diff = sum; } }
THash<TInt, TInt> * choose_seeds (const PUNGraph g, const int num, const int * infection_state, const int infect) { THash<TInt, TInt> choices; THash<TInt, TUNGraph::TNode> nodes; THash<TInt, TInt> * output = new THash<TInt, TInt> (); TInt weight = 0; TInt num_total = 0; for (TUNGraph::TNodeI n = g->BegNI(); n != g->EndNI(); n++) { //cout << "nodeID: " << n.GetId() << ",\tStatus: " << infection_state[n.GetId () - 1] << endl; if (infection_state[n.GetId () - 1] != infect) { weight += n.GetDeg (); choices.AddDat (num_total, weight); nodes.AddDat (num_total, n.GetId()); num_total++; } } // TRnd random ((int) time(NULL)); // TRnd random (0); TInt num_chosen = 0; while (num_chosen < num) { TInt choice = my_random.GetUniDevInt (weight); TUNGraph::TNode node_choice = nodes[find (choice, choices, 0, num_total-1)]; if (!output->IsKey(node_choice.GetId())) { num_chosen++; // cout << node_choice.GetId () << "\n"; output->AddDat(node_choice.GetId (), 1); } } return output; }
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; }
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(); }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Node Centrality. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "../as20graph.txt", "Input un/directed graph"); const TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "node_centrality.tab", "Output file"); printf("Loading %s...", InFNm.CStr()); PNGraph Graph = TSnap::LoadEdgeList<PNGraph>(InFNm); //PNGraph Graph = TSnap::GenRndGnm<PNGraph>(10, 10); //TGraphViz::Plot(Graph, gvlNeato, InFNm+".gif", InFNm, true); printf("nodes:%d edges:%d\n", Graph->GetNodes(), Graph->GetEdges()); PUNGraph UGraph = TSnap::ConvertGraph<PUNGraph>(Graph); // undirected version of the graph TIntFltH BtwH, EigH, PRankH, CcfH, CloseH, HubH, AuthH; //printf("Computing...\n"); printf("Treat graph as DIRECTED: "); printf(" PageRank... "); TSnap::GetPageRank(Graph, PRankH, 0.85); printf(" Hubs&Authorities..."); TSnap::GetHits(Graph, HubH, AuthH); printf("\nTreat graph as UNDIRECTED: "); printf(" Eigenvector..."); TSnap::GetEigenVectorCentr(UGraph, EigH); printf(" Clustering..."); TSnap::GetNodeClustCf(UGraph, CcfH); printf(" Betweenness (SLOW!)..."); TSnap::GetBetweennessCentr(UGraph, BtwH, 1.0); printf(" Constraint (SLOW!)..."); TNetConstraint<PUNGraph> NetC(UGraph, true); printf(" Closeness (SLOW!)..."); for (TUNGraph::TNodeI NI = UGraph->BegNI(); NI < UGraph->EndNI(); NI++) { const int NId = NI.GetId(); CloseH.AddDat(NId, TSnap::GetClosenessCentr<PUNGraph>(UGraph, NId, false)); } printf("\nDONE! saving..."); FILE *F = fopen(OutFNm.CStr(), "wt"); fprintf(F,"#Network: %s\n", InFNm.CStr()); fprintf(F,"#Nodes: %d\tEdges: %d\n", Graph->GetNodes(), Graph->GetEdges()); fprintf(F,"#NodeId\tDegree\tCloseness\tBetweennes\tEigenVector\tNetworkConstraint\tClusteringCoefficient\tPageRank\tHubScore\tAuthorityScore\n"); for (TUNGraph::TNodeI NI = UGraph->BegNI(); NI < UGraph->EndNI(); NI++) { const int NId = NI.GetId(); const double DegCentr = UGraph->GetNI(NId).GetDeg(); const double CloCentr = CloseH.GetDat(NId); const double BtwCentr = BtwH.GetDat(NId); const double EigCentr = EigH.GetDat(NId); const double Constraint = NetC.GetNodeC(NId); const double ClustCf = CcfH.GetDat(NId); const double PgrCentr = PRankH.GetDat(NId); const double HubCentr = HubH.GetDat(NId); const double AuthCentr = AuthH.GetDat(NId); fprintf(F, "%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f\n", NId, DegCentr, CloCentr, BtwCentr, EigCentr, Constraint, ClustCf, PgrCentr, HubCentr, AuthCentr); } fclose(F); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
static double CmtyCMN(const PUNGraph& Graph, TCnComV& CmtyV) { TCNMQMatrix QMatrix(Graph); // maximize modularity while (QMatrix.MergeBestQ()) { } // reconstruct communities THash<TInt, TIntV> IdCmtyH; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { IdCmtyH.AddDat(QMatrix.CmtyIdUF.Find(NI.GetId())).Add(NI.GetId()); } CmtyV.Gen(IdCmtyH.Len()); for (int j = 0; j < IdCmtyH.Len(); j++) { CmtyV[j].NIdV.Swap(IdCmtyH[j]); } return QMatrix.Q; }
void TAGMFit::RandomInit(const int& MaxK) { CIDNSetV.Clr(); for (int c = 0; c < MaxK; c++) { CIDNSetV.Add(); int NC = Rnd.GetUniDevInt(G -> GetNodes()); TUNGraph::TNodeI NI = G -> GetRndNI(); CIDNSetV.Last().AddKey(NI.GetId()); for (int v = 0; v < NC; v++) { NI = G->GetNI(NI.GetNbrNId(Rnd.GetUniDevInt(NI.GetDeg()))); CIDNSetV.Last().AddKey(NI.GetId()); } } InitNodeData(); SetDefaultPNoCom(); }
// Loads a (directed, undirected or multi) graph from a text file InFNm with 1 node and all its edges in a single line. void IOConnListStr() { const int NNodes = 500; const int NEdges = 2000; const char *FName = "demo.graph.dat"; PUNGraph GOut, GIn; GOut = GenRndGnm<PUNGraph>(NNodes, NEdges); // Output nodes as random strings TIntStrH OutNIdStrH; TStrHash<TInt> OutStrNIdH; // Generate unique random strings for graph for (TUNGraph::TNodeI NI = GOut->BegNI(); NI < GOut->EndNI(); NI++) { TStr RandStr = ""; do { TInt RandLen = TInt::Rnd.GetUniDevInt(5, 10); for (int i = 0; i < RandLen; i++) { // TStr RandChar(TInt::Rnd.GetUniDevInt(33, 126)); TStr RandChar(TInt::Rnd.GetUniDevInt(97, 122)); RandStr += RandChar; } } while (OutStrNIdH.IsKey(RandStr) || RandStr[0] == '#'); OutNIdStrH.AddDat(NI.GetId(), RandStr); OutStrNIdH.AddDat(RandStr, NI.GetId()); } // Create graph file FILE *F = fopen(FName, "w"); for (TUNGraph::TNodeI NI = GOut->BegNI(); NI < GOut->EndNI(); NI++) { fprintf(F, "%s", OutNIdStrH[NI.GetId()].CStr()); for (int e = 0; e < NI.GetOutDeg(); e++) { fprintf(F, " %s", OutNIdStrH[NI.GetOutNId(e)].CStr()); } fprintf(F, "\n"); } fclose(F); TStrHash<TInt> InStrToNIdH; GIn = LoadConnListStr<PUNGraph>(FName, InStrToNIdH); PrintGStats("ConnListStr - Out", GOut); PrintGStats("ConnListStr - In", GIn); }
double ave_path_length (PUNGraph p) { TVec<TInt> v; double tot_lengths = 0.0; for (TUNGraph::TNodeI n = p->BegNI(); n != p->EndNI(); n++) { v = v + n.GetId(); } // cerr << "vlen: " << v.Len() << endl; TBreathFS<PUNGraph> b(p); double tot_pairs = 0.0; while (v.Len () > 0) { TInt last = v[v.Len()-1]; b.DoBfs (last, true, true); for (TVec<TInt>::TIter i = v.BegI(); (*i) != last; i++) { int length; length = b.GetHops (last, (*i)); if (length == length) { tot_lengths += length; tot_pairs += 1; } } // cerr << "tps: " << tot_pairs << ", last: " << last << ", beg: " << v[*(v.BegI())] << endl; v.Del(v.Len()-1); } // cerr << "paths: " << tot_lengths << " " << tot_pairs << " " << (tot_lengths/tot_pairs) << endl; return tot_lengths / tot_pairs; }
int Intersect(TUNGraph::TNodeI Node, int *NNodes, int NNodes_br){ int br = 0; int neig; for (int i = 0; i<Node.GetDeg(); i++) { neig = Node.GetNbrNId(i); for (int j = 0; j<NNodes_br; j++) { if (neig == NNodes[j]) { br++; j = NNodes_br; } } } neig = Node.GetId(); for (int j = 0; j<NNodes_br; j++) { if (neig == NNodes[j]) { br++; j = NNodes_br; } } return br; }
void TAGMFit::InitNodeData() { TSnap::DelSelfEdges(G); NIDComVH.Gen(G->GetNodes()); for (TUNGraph::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { NIDComVH.AddDat(NI.GetId()); } TAGMUtil::GetNodeMembership(NIDComVH, CIDNSetV); GetEdgeJointCom(); LambdaV.Gen(CIDNSetV.Len()); for (int c = 0; c < CIDNSetV.Len(); c++) { int MaxE = (CIDNSetV[c].Len()) * (CIDNSetV[c].Len() - 1) / 2; if (MaxE < 2) { LambdaV[c] = MaxLambda; } else{ LambdaV[c] = -log((double) (MaxE - ComEdgesV[c]) / MaxE); } if (LambdaV[c] > MaxLambda) { LambdaV[c] = MaxLambda; } if (LambdaV[c] < MinLambda) { LambdaV[c] = MinLambda; } } NIDCIDPrS.Gen(G->GetNodes() * 10); for (int c = 0; c < CIDNSetV.Len(); c++) { for (TIntSet::TIter SI = CIDNSetV[c].BegI(); SI < CIDNSetV[c].EndI(); SI++) { NIDCIDPrS.AddKey(TIntPr(SI.GetKey(), c)); } } }
void GetEigenVectorCentr(const PUNGraph& Graph, TIntFltH& NIdEigenH, const double& Eps, const int& MaxIter) { const int NNodes = Graph->GetNodes(); NIdEigenH.Gen(NNodes); // initialize vector values for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NIdEigenH.AddDat(NI.GetId(), 1.0 / NNodes); IAssert(NI.GetId() == NIdEigenH.GetKey(NIdEigenH.Len() - 1)); } TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { int j = 0; // add neighbor values for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { TmpV[j] = 0; for (int e = 0; e < NI.GetOutDeg(); e++) { TmpV[j] += NIdEigenH.GetDat(NI.GetOutNId(e)); } } // normalize double sum = 0; for (int i = 0; i < TmpV.Len(); i++) { sum += (TmpV[i] * TmpV[i]); } sum = sqrt(sum); for (int i = 0; i < TmpV.Len(); i++) { TmpV[i] /= sum; } // compute difference double diff = 0.0; j = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { diff += fabs(NIdEigenH.GetDat(NI.GetId()) - TmpV[j]); } // set new values j = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { NIdEigenH.AddDat(NI.GetId(), TmpV[j]); } if (diff < Eps) { break; } } }
double GetAsstyCor(const PUNGraph& Graph) { TIntFltH deg(Graph->GetNodes()), deg_sq(Graph->GetNodes()); for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { deg.AddDat(NI.GetId()) = NI.GetOutDeg(); deg_sq.AddDat(NI.GetId()) = NI.GetOutDeg() * NI.GetOutDeg(); } double m = Graph->GetEdges(), num1 = 0.0, num2 = 0.0, den1 = 0.0; for (TUNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { double t1 = deg.GetDat(EI.GetSrcNId()).Val, t2 = deg.GetDat(EI.GetDstNId()).Val; num1 += t1 * t2; num2 += t1 + t2; den1 += deg_sq.GetDat(EI.GetSrcNId()).Val + deg_sq.GetDat(EI.GetDstNId()).Val; } num1 /= m; den1 /= (2.0 * m); num2 = (num2 / (2.0 * m)) * (num2 / (2.0 * m)); return (num1 - num2) / (den1 - num2); }
/// Rewire the network. Keeps node degrees as is but randomly rewires the edges. /// Use this function to generate a random graph with the same degree sequence /// as the OrigGraph. /// See: On the uniform generation of random graphs with prescribed degree /// sequences by R. Milo, N. Kashtan, S. Itzkovitz, M. E. J. Newman, U. Alon /// URL: http://arxiv.org/abs/cond-mat/0312028 PUNGraph GenRewire(const PUNGraph& OrigGraph, const int& NSwitch, TRnd& Rnd) { const int Nodes = OrigGraph->GetNodes(); const int Edges = OrigGraph->GetEdges(); PUNGraph GraphPt = TUNGraph::New(); TUNGraph& Graph = *GraphPt; Graph.Reserve(Nodes, -1); TExeTm ExeTm; // generate a graph that satisfies the constraints printf("Randomizing edges (%d, %d)...\n", Nodes, Edges); TIntPrSet EdgeSet(Edges); for (TUNGraph::TNodeI NI = OrigGraph->BegNI(); NI < OrigGraph->EndNI(); NI++) { const int NId = NI.GetId(); for (int e = 0; e < NI.GetOutDeg(); e++) { if (NId <= NI.GetOutNId(e)) { continue; } EdgeSet.AddKey(TIntPr(NId, NI.GetOutNId(e))); } Graph.AddNode(NI.GetId()); } // edge switching uint skip=0; for (uint swps = 0; swps < 2*uint(Edges)*uint(NSwitch); swps++) { const int keyId1 = EdgeSet.GetRndKeyId(Rnd); const int keyId2 = EdgeSet.GetRndKeyId(Rnd); if (keyId1 == keyId2) { skip++; continue; } const TIntPr& E1 = EdgeSet[keyId1]; const TIntPr& E2 = EdgeSet[keyId2]; TIntPr NewE1(E1.Val1, E2.Val1), NewE2(E1.Val2, E2.Val2); if (NewE1.Val1 > NewE1.Val2) { Swap(NewE1.Val1, NewE1.Val2); } if (NewE2.Val1 > NewE2.Val2) { Swap(NewE2.Val1, NewE2.Val2); } if (NewE1!=NewE2 && NewE1.Val1!=NewE1.Val2 && NewE2.Val1!=NewE2.Val2 && ! EdgeSet.IsKey(NewE1) && ! EdgeSet.IsKey(NewE2)) { EdgeSet.DelKeyId(keyId1); EdgeSet.DelKeyId(keyId2); EdgeSet.AddKey(TIntPr(NewE1)); EdgeSet.AddKey(TIntPr(NewE2)); } else { skip++; } if (swps % Edges == 0) { printf("\r %uk/%uk: %uk skip [%s]", swps/1000u, 2*uint(Edges)*uint(NSwitch)/1000u, skip/1000u, ExeTm.GetStr()); if (ExeTm.GetSecs() > 2*3600) { printf(" *** Time limit!\n"); break; } // time limit 2 hours } } printf("\r total %uk switchings attempted, %uk skiped [%s]\n", 2*uint(Edges)*uint(NSwitch)/1000u, skip/1000u, ExeTm.GetStr()); for (int e = 0; e < EdgeSet.Len(); e++) { Graph.AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); } return GraphPt; }
void Init(const PUNGraph& Graph) { const double M = 0.5/Graph->GetEdges(); // 1/2m Q = 0.0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { CmtyIdUF.Add(NI.GetId()); const int OutDeg = NI.GetOutDeg(); if (OutDeg == 0) { continue; } TCmtyDat& Dat = CmtyQH.AddDat(NI.GetId(), TCmtyDat(M * OutDeg, OutDeg)); for (int e = 0; e < NI.GetOutDeg(); e++) { const int DstNId = NI.GetOutNId(e); const double DstMod = 2 * M * (1.0 - OutDeg * Graph->GetNI(DstNId).GetOutDeg() * M); Dat.AddQ(DstNId, DstMod); } Q += -1.0*TMath::Sqr(OutDeg*M); if (NI.GetId() < Dat.GetMxQNId()) { MxQHeap.Add(TFltIntIntTr(Dat.GetMxQ(), NI.GetId(), Dat.GetMxQNId())); } } MxQHeap.MakeHeap(); }
int Intersect(TUNGraph::TNodeI Node, TIntH NNodes){ int br = 0; for (int i = 0; i<Node.GetDeg(); i++) { if (NNodes.IsKey(Node.GetNbrNId(i))) br++; } if (NNodes.IsKey(Node.GetId())) br++; return br; }
// network cascade: add spurious edges // for more details see "Correcting for Missing Data in Information Cascades" by E. Sadikov, M. Medina, J. Leskovec, H. Garcia-Molina. WSDM, 2011 PNGraph AddSpuriousEdges(const PUNGraph& Graph, const PNGraph& Casc, TIntH NIdTmH) { TIntPrV EdgeV; for (TNGraph::TNodeI NI = Casc->BegNI(); NI < Casc->EndNI(); NI++) { TUNGraph::TNodeI GNI = Graph->GetNI(NI.GetId()); const int Tm = NIdTmH.GetDat(NI.GetId()); for (int i=0,j=0; i < GNI.GetOutDeg(); i++) { const int Dst = GNI.GetOutNId(i); if (NIdTmH.IsKey(Dst) && Tm<NIdTmH.GetDat(Dst) && ! NI.IsNbhNId(Dst)) { EdgeV.Add(TIntPr(GNI.GetId(), Dst)); } } } PNGraph NetCasc = TNGraph::New(); *NetCasc = *Casc; for (int e = 0; e < EdgeV.Len(); e++) { NetCasc->AddEdge(EdgeV[e].Val1, EdgeV[e].Val2); } return NetCasc; }
int FastCorePeriphery(PUNGraph& Graph, TIntIntH& out) { TIntIntH nodes; double Z=0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { // Calculate and store the degrees of each node. int deg = NI.GetDeg(); int id = NI.GetId(); Z += deg; nodes.AddDat(id,deg); } Z = Z/2; nodes.SortByDat(false); // Then sort the nodes in descending order of degree, to get a list of nodes {v1, v2, . . . , vn}. double Zbest = 99999900000000000; int kbest = 0; int br=0; for (int k=0; k<nodes.Len(); k++) { br++; Z = Z + br - 1 - nodes[k]; if (Z < Zbest) { // or <= Zbest = Z; kbest = br; } } int cp = 0; br = 0; for (THashKeyDatI<TInt, TInt> it = nodes.BegI(); !it.IsEnd(); it++) { if (br < kbest) cp = 1; else cp = 0; out.AddDat(it.GetKey(), cp); br++; } return kbest; }
// simulate SI model cascade using infection probability Beta until the cascade stops or reaches size MxCascSz PNGraph RunSICascade2(PUNGraph G, const double& Beta, const int& MxCascSz, TIntH& NIdInfTmH) { PNGraph Casc = TNGraph::New(); const int StartNId = G->GetRndNId(); Casc->AddNode(StartNId); NIdInfTmH.AddDat(StartNId, NIdInfTmH.Len()); TIntQ Q; Q.Push(StartNId); while (! Q.Empty()) { const TUNGraph::TNodeI NI = G->GetNI(Q.Top()); Q.Pop(); for (int i = 0; i < NI.GetOutDeg(); i++) { if (TInt::Rnd.GetUniDev() < Beta && ! NIdInfTmH.IsKey(NI.GetOutNId(i))) { Casc->AddNode(NI.GetOutNId(i)); NIdInfTmH.AddDat(NI.GetOutNId(i), NIdInfTmH.Len()); Casc->AddEdge(NI.GetId(), NI.GetOutNId(i)); if (Casc->GetNodes() == MxCascSz) { return Casc; } Q.Push(NI.GetOutNId(i)); } } } return Casc; }
int Intersect1(TUNGraph::TNodeI Node, TStr NNodes){ int br = 0; for (int i = 0; i<Node.GetDeg(); i++) { TInt digi = Node.GetNbrNId(i); TStr buf = ""; buf = digi.GetStr(); if (NNodes.SearchStr(buf.CStr()) != -1) br++; } TInt digi = Node.GetId(); TStr buf = digi.GetStr(); if (NNodes.SearchStr(buf.CStr()) != -1) br++; return br; }
// For each (u, v) in edges, precompute C_uv (the set of communities u and v share). void TAGMFit::GetEdgeJointCom() { ComEdgesV.Gen(CIDNSetV.Len()); EdgeComVH.Gen(G->GetEdges()); for (TUNGraph::TNodeI SrcNI = G->BegNI(); SrcNI < G->EndNI(); SrcNI++) { int SrcNID = SrcNI.GetId(); for (int v = 0; v < SrcNI.GetDeg(); v++) { int DstNID = SrcNI.GetNbrNId(v); if (SrcNID >= DstNID) { continue; } TIntSet JointCom; IAssert(NIDComVH.IsKey(SrcNID)); IAssert(NIDComVH.IsKey(DstNID)); TAGMUtil::GetIntersection(NIDComVH.GetDat(SrcNID), NIDComVH.GetDat(DstNID), JointCom); EdgeComVH.AddDat(TIntPr(SrcNID,DstNID),JointCom); for (int k = 0; k < JointCom.Len(); k++) { ComEdgesV[JointCom[k]]++; } } } IAssert(EdgeComVH.Len() == G->GetEdges()); }
// renumber node ids 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++) { NewGraph.AddNode(n); NIdSet.AddKey(NIdV[n]); } for (int n = 0; n < NIdV.Len(); n++) { const TUNGraph::TNodeI NI = Graph->GetNI(NIdV[n]); const int SrcNId = NIdSet.GetKeyId(NI.GetId()); for (int edge = 0; edge < NI.GetDeg(); edge++) { const int OutNId = NIdSet.GetKeyId(NI.GetNbhNId(edge)); if (NewGraph.IsNode(OutNId)) { NewGraph.AddEdge(SrcNId, OutNId); } } } return NewGraphPt; }
// Maximum modularity clustering by Girvan-Newman algorithm (slow) // Girvan M. and Newman M. E. J., Community structure in social and biological networks, Proc. Natl. Acad. Sci. USA 99, 7821–7826 (2002) double CommunityGirvanNewman(PUNGraph& Graph, TCnComV& CmtyV) { TIntH OutDegH; const int NEdges = Graph->GetEdges(); for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { OutDegH.AddDat(NI.GetId(), NI.GetOutDeg()); } double BestQ = -1; // modularity TCnComV CurCmtyV; CmtyV.Clr(); TIntV Cmty1, Cmty2; while (true) { CmtyGirvanNewmanStep(Graph, Cmty1, Cmty2); const double Q = _GirvanNewmanGetModularity(Graph, OutDegH, NEdges, CurCmtyV); //printf("current modularity: %f\n", Q); if (Q > BestQ) { BestQ = Q; CmtyV.Swap(CurCmtyV); } if (Cmty1.Len()==0 || Cmty2.Len() == 0) { break; } } return BestQ; }
// simulate SI model cascade using infection probability Beta until the cascade reaches size CascSz PNGraph RunSICascade(PUNGraph G, const double& Beta, const int& CascSz, TIntH& NIdInfTmH) { PNGraph Casc = TNGraph::New(); const int StartId = G->GetRndNId(); Casc->AddNode(StartId); NIdInfTmH.AddDat(StartId, NIdInfTmH.Len()); for (int X = 0; X < 10*CascSz; X++) { TIntV CascNIdV; Casc->GetNIdV(CascNIdV); for (int n = 0; n < CascNIdV.Len(); n++) { const TUNGraph::TNodeI NI = G->GetNI(CascNIdV[n]); for (int i = 0; i < NI.GetOutDeg(); i++) { if (Casc->IsNode(NI.GetOutNId(i))) { continue; } if (TInt::Rnd.GetUniDev() < Beta) { Casc->AddNode(NI.GetOutNId(i)); NIdInfTmH.AddDat(NI.GetOutNId(i), NIdInfTmH.Len()); Casc->AddEdge(NI.GetId(), NI.GetOutNId(i)); if (Casc->GetNodes() == CascSz) { return Casc; } } } } } return Casc; }
int Intersect(TUNGraph::TNodeI Node, TStr NNodes){ int br = 0; TInt digi = -1; TStr buf = ""; for (int i = 0; i<Node.GetDeg(); i++) { digi = Node.GetNbrNId(i); TStr buf = digi.GetStr(); if (NNodes.IsStrIn(buf.CStr())) br++; } digi = Node.GetId(); buf = digi.GetStr(); if (NNodes.IsStrIn(buf.CStr())) br++; return br; }
void GetBetweennessCentr(const PUNGraph& Graph, const TIntV& BtwNIdV, TIntFltH& NodeBtwH, const bool& DoNodeCent, TIntPrFltH& EdgeBtwH, const bool& DoEdgeCent) { if (DoNodeCent) { NodeBtwH.Clr(); } if (DoEdgeCent) { EdgeBtwH.Clr(); } const int nodes = Graph->GetNodes(); TIntS S(nodes); TIntQ Q(nodes); TIntIntVH P(nodes); // one vector for every node TIntFltH delta(nodes); TIntH sigma(nodes), d(nodes); // init for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { if (DoNodeCent) { NodeBtwH.AddDat(NI.GetId(), 0); } if (DoEdgeCent) { for (int e = 0; e < NI.GetOutDeg(); e++) { if (NI.GetId() < NI.GetOutNId(e)) { EdgeBtwH.AddDat(TIntPr(NI.GetId(), NI.GetOutNId(e)), 0); } } } sigma.AddDat(NI.GetId(), 0); d.AddDat(NI.GetId(), -1); P.AddDat(NI.GetId(), TIntV()); delta.AddDat(NI.GetId(), 0); } // calc betweeness for (int k = 0; k < BtwNIdV.Len(); k++) { const TUNGraph::TNodeI NI = Graph->GetNI(BtwNIdV[k]); // reset for (int i = 0; i < sigma.Len(); i++) { sigma[i] = 0; d[i] = -1; delta[i] = 0; P[i].Clr(false); } S.Clr(false); Q.Clr(false); sigma.AddDat(NI.GetId(), 1); d.AddDat(NI.GetId(), 0); Q.Push(NI.GetId()); while (!Q.Empty()) { const int v = Q.Top(); Q.Pop(); const TUNGraph::TNodeI NI2 = Graph->GetNI(v); S.Push(v); const int VDat = d.GetDat(v); for (int e = 0; e < NI2.GetOutDeg(); e++) { const int w = NI2.GetOutNId(e); if (d.GetDat(w) < 0) { // find w for the first time Q.Push(w); d.AddDat(w, VDat + 1); } //shortest path to w via v ? if (d.GetDat(w) == VDat + 1) { sigma.AddDat(w) += sigma.GetDat(v); P.GetDat(w).Add(v); } } } while (!S.Empty()) { const int w = S.Top(); const double SigmaW = sigma.GetDat(w); const double DeltaW = delta.GetDat(w); const TIntV NIdV = P.GetDat(w); S.Pop(); for (int i = 0; i < NIdV.Len(); i++) { const int nid = NIdV[i]; const double c = (sigma.GetDat(nid)*1.0 / SigmaW) * (1 + DeltaW); delta.AddDat(nid) += c; if (DoEdgeCent) { EdgeBtwH.AddDat(TIntPr(TMath::Mn(nid, w), TMath::Mx(nid, w))) += c; } } if (DoNodeCent && w != NI.GetId()) { NodeBtwH.AddDat(w) += delta.GetDat(w) / 2.0; } } } }
// Maximum Domination Problem void MaxCPGreedyBetter(const PUNGraph& Graph, const int k, TIntH& GroupNodes) { // buildup cpntainer of group nodes const int n = Graph->GetNodes(); int *NNodes = new int[n]; // container of neighbouring nodes int NNodes_br = 0; TIntH Nodes; // nodes sorted by vd double gc = 0, gc0 = 0; int addId = 0, addIdPrev = 0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++){ Nodes.AddDat(NI.GetId(), NI.GetDeg()); } Nodes.SortByDat(false); int br = 0; while (br < k) { for (THashKeyDatI<TInt, TInt> NI = Nodes.BegI(); NI < Nodes.EndI(); NI++){ if ((NI.GetDat() <= (int)gc0)) break; gc = NI.GetDat() - Intersect(Graph->GetNI(NI.GetKey()), NNodes, NNodes_br); if (gc>gc0){ gc0 = gc; addId = NI.GetKey(); } } if (addId != addIdPrev) { GroupNodes.AddDat(br, addId); br++; gc0 = 0; int nn = addId; bool nnnew = true; for (int j = 0; j<NNodes_br; j++) if (NNodes[j] == nn){ nnnew = false; j = NNodes_br; } if (nnnew){ NNodes[NNodes_br] = nn; NNodes_br++; } for (int i = 0; i<Graph->GetNI(addId).GetDeg(); i++) { int nn = Graph->GetNI(addId).GetNbrNId(i); bool nnnew = true; for (int j = 0; j<NNodes_br; j++) { if (NNodes[j] == nn){ nnnew = false; j = NNodes_br; } } if (nnnew){ NNodes[NNodes_br] = nn; NNodes_br++; } } addIdPrev = addId; Nodes.DelKey(addId); } else { br = k; } printf("%i,", br); } delete NNodes; }
int main(int argc, char* argv[]) { // const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "graph.txt", "Input graph (one edge per line, tab/space separated)"); // const TBool IsDir = Env.GetIfArgPrefixBool("-d:", true, "Directed graph"); // const TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "graph", "Output file prefix"); // const TStr Desc = Env.GetIfArgPrefixStr("-t:", "", "Title (description)"); // const TStr Plot = Env.GetIfArgPrefixStr("-p:", "cdhwsCvV", "What statistics to plot string:" // "\n\tc: cummulative degree distribution" // "\n\td: degree distribution" // "\n\th: hop plot (diameter)" // "\n\tw: distribution of weakly connected components" // "\n\ts: distribution of strongly connected components" // "\n\tC: clustering coefficient" // "\n\tv: singular values" // "\n\tV: left and right singular vector\n\t"); // bool PlotDD, PlotCDD, PlotHop, PlotWcc, PlotScc, PlotSVal, PlotSVec, PlotClustCf; // PlotDD = Plot.SearchCh('d') != -1; // PlotCDD = Plot.SearchCh('c') != -1; // PlotHop = Plot.SearchCh('h') != -1; // PlotWcc = Plot.SearchCh('w') != -1; // PlotScc = Plot.SearchCh('s') != -1; // PlotClustCf = Plot.SearchCh('C') != -1; // PlotSVal = Plot.SearchCh('v') != -1; // PlotSVec = Plot.SearchCh('V') != -1; // if (Env.IsEndOfRun()) { return 0; } //PNGraph G = TGGen<PNGraph>::GenRMat(1000, 3000, 0.40, 0.25, 0.2); //G->SaveEdgeList("graph.txt", "RMat graph (a:0.40, b:0.25, c:0.20)"); printf("Loading..."); if (argc < 3) return 0; TStr InFNm = argv[1]; TStr prefix = argv[2]; // ostringstream os; // os << InFNm << "_OutDegreeDistribution"; // TStr FNOutDD = os.str(); // os.str(""); // os.clear(); const TStr Desc = prefix; TStr FNOutDD = prefix; // os << InFNm << "_InDegreeDistribution"; // TStr FNInDD = os.str(); // os.str(""); // os.clear(); TStr FNInDD = prefix; // os << InFNm << "_HopPlot"; // TStr FNHops = os.str(); // os.str(""); // os.clear(); TStr FNHops = prefix; // os << InFNm << "_WeaklyConnectedComponents"; // TStr FNWeaklyConnectedComps = os.str(); // os.str(""); // os.clear(); TStr FNWeaklyConnectedComps = prefix; // os << InFNm << "_StronglyConnectedComponents"; // TStr FNStronglyConnectedComps = os.str(); // os.str(""); // os.clear(); TStr FNStronglyConnectedComps = prefix; // os << InFNm << "ClusteringCoefficient"; // TStr FNClusteringCoeff = os.str(); // os.str(""); // os.clear(); TStr FNClusteringCoeff = prefix; TStr FNCentrality = prefix + "_centrality.dat"; Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("GraphInfo. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try PNGraph Graph = TSnap::LoadEdgeList<PNGraph>(InFNm); // if (! IsDir) { TSnap::MakeUnDir(Graph); } printf("nodes:%d edges:%d\nCreating plots...\n", Graph->GetNodes(), Graph->GetEdges()); // const int Vals = Graph->GetNodes()/2 > 200 ? 200 : Graph->GetNodes()/2; // if (PlotDD) { TSnap::PlotOutDegDistr(Graph, FNOutDD, Desc, false, false); TSnap::PlotInDegDistr(Graph, FNInDD, Desc, false, false); printf("In and Out done\n"); // } // if (PlotCDD) { // TSnap::PlotOutDegDistr(Graph, FNOutCDD, Desc, true, false); // <======== waere interessant // TSnap::PlotInDegDistr(Graph, FNInCDD, Desc, true, false); // } // if (PlotHop) { TSnap::PlotHops(Graph, FNHops, Desc, false, 8); printf("hops done\n"); // } // if (PlotWcc) { TSnap::PlotWccDistr(Graph, FNWeaklyConnectedComps, Desc); printf("wcc done\n"); // } // if (PlotScc) { TSnap::PlotSccDistr(Graph, FNStronglyConnectedComps, Desc); printf("scc done\n"); // } // if (PlotClustCf) { TSnap::PlotClustCf(Graph, FNClusteringCoeff, Desc); printf("CC done\n"); // } // if (PlotSVal) { // TSnap::PlotSngValRank(Graph, Vals, OutFNm, Desc); // } // if(PlotSVec) { // TSnap::PlotSngVec(Graph, OutFNm, Desc); // } PUNGraph UGraph = TSnap::ConvertGraph<PUNGraph>(Graph); TIntFltH BtwH, PRankH, CcfH, CloseH; printf(" PageRank... "); TSnap::GetPageRank(Graph, PRankH, 0.85); printf(" Betweenness (SLOW!)..."); TSnap::GetBetweennessCentr(UGraph, BtwH, 0.1); printf(" Clustering..."); TSnap::GetNodeClustCf(UGraph, CcfH); printf(" Closeness (SLOW!)..."); for (TUNGraph::TNodeI NI = UGraph->BegNI(); NI < UGraph->EndNI(); NI++) { const int NId = NI.GetId(); CloseH.AddDat(NId, TSnap::GetClosenessCentr(UGraph, NId)); } printf("\nDONE! saving..."); FILE *F = fopen(FNCentrality.CStr(), "wt"); fprintf(F,"#Network: %s\n", prefix.CStr()); fprintf(F,"#Nodes: %d\tEdges: %d\n", Graph->GetNodes(), Graph->GetEdges()); fprintf(F,"#NodeId\tDegree\tCloseness\tBetweennes\tClusteringCoefficient\tPageRank\n"); for (TUNGraph::TNodeI NI = UGraph->BegNI(); NI < UGraph->EndNI(); NI++) { const int NId = NI.GetId(); const double DegCentr = UGraph->GetNI(NId).GetDeg(); const double CloCentr = CloseH.GetDat(NId); const double BtwCentr = BtwH.GetDat(NId); const double ClustCf = CcfH.GetDat(NId); const double PgrCentr = PRankH.GetDat(NId); fprintf(F, "%d\t%f\t%f\t%f\t%f\t%f\n", NId, DegCentr, CloCentr, BtwCentr, ClustCf, PgrCentr); } fclose(F); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
/// save graph into a gexf file which Gephi can read void TAGMUtil::SaveGephi(const TStr& OutFNm, const PUNGraph& G, const TVec<TIntV>& CmtyVVAtr, const double MaxSz, const double MinSz, const TIntStrH& NIDNameH, const THash<TInt, TIntTr>& NIDColorH ) { THash<TInt,TIntV> NIDComVHAtr; TAGMUtil::GetNodeMembership(NIDComVHAtr, CmtyVVAtr); FILE* F = fopen(OutFNm.CStr(), "wt"); fprintf(F, "<?xml version='1.0' encoding='UTF-8'?>\n"); fprintf(F, "<gexf xmlns='http://www.gexf.net/1.2draft' xmlns:viz='http://www.gexf.net/1.1draft/viz' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd' version='1.2'>\n"); fprintf(F, "\t<graph mode='static' defaultedgetype='undirected'>\n"); if (CmtyVVAtr.Len() > 0) { fprintf(F, "\t<attributes class='node'>\n"); for (int c = 0; c < CmtyVVAtr.Len(); c++) { fprintf(F, "\t\t<attribute id='%d' title='c%d' type='boolean'>", c, c); fprintf(F, "\t\t<default>false</default>\n"); fprintf(F, "\t\t</attribute>\n"); } fprintf(F, "\t</attributes>\n"); } fprintf(F, "\t\t<nodes>\n"); for (TUNGraph::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { int NID = NI.GetId(); TStr Label = NIDNameH.IsKey(NID)? NIDNameH.GetDat(NID): ""; Label.ChangeChAll('<', ' '); Label.ChangeChAll('>', ' '); Label.ChangeChAll('&', ' '); Label.ChangeChAll('\'', ' '); TIntTr Color = NIDColorH.IsKey(NID)? NIDColorH.GetDat(NID) : TIntTr(120, 120, 120); double Size = MinSz; double SizeStep = (MaxSz - MinSz) / (double) CmtyVVAtr.Len(); if (NIDComVHAtr.IsKey(NID)) { Size = MinSz + SizeStep * (double) NIDComVHAtr.GetDat(NID).Len(); } double Alpha = 1.0; fprintf(F, "\t\t\t<node id='%d' label='%s'>\n", NID, Label.CStr()); fprintf(F, "\t\t\t\t<viz:color r='%d' g='%d' b='%d' a='%.1f'/>\n", Color.Val1.Val, Color.Val2.Val, Color.Val3.Val, Alpha); fprintf(F, "\t\t\t\t<viz:size value='%.3f'/>\n", Size); //specify attributes if (NIDComVHAtr.IsKey(NID)) { fprintf(F, "\t\t\t\t<attvalues>\n"); for (int c = 0; c < NIDComVHAtr.GetDat(NID).Len(); c++) { int CID = NIDComVHAtr.GetDat(NID)[c]; fprintf(F, "\t\t\t\t\t<attvalue for='%d' value='true'/>\n", CID); } fprintf(F, "\t\t\t\t</attvalues>\n"); } fprintf(F, "\t\t\t</node>\n"); } fprintf(F, "\t\t</nodes>\n"); //plot edges int EID = 0; fprintf(F, "\t\t<edges>\n"); for (TUNGraph::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { if (NI.GetId() > NI.GetOutNId(e)) { continue; } fprintf(F, "\t\t\t<edge id='%d' source='%d' target='%d'/>\n", EID++, NI.GetId(), NI.GetOutNId(e)); } } fprintf(F, "\t\t</edges>\n"); fprintf(F, "\t</graph>\n"); fprintf(F, "</gexf>\n"); fclose(F); }
int FastCorePeripheryGC(PUNGraph& Graph, TIntIntH& out) { TIntH GroupNodes; // buildup cpntainer of group nodes int *NNodes = new int[Graph->GetNodes()]; // container of neighbouring nodes int NNodes_br = 0; TIntIntH nodes; TIntIntH nodesIds; double Z=0; for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { // Calculate and store the degrees of each node. int deg = NI.GetDeg(); int id = NI.GetId(); Z += deg; nodes.AddDat(id,deg); } Z = Z/2; nodes.SortByDat(false); // Then sort the nodes in descending order of degree, to get a list of nodes {v1, v2, . . . , vn}. int br1=0; for (THashKeyDatI<TInt,TInt> NI = nodes.BegI(); NI < nodes.EndI(); NI++) { nodesIds.AddDat(NI.GetKey(),NI.GetKey()); br1++; } double Zbest = 99999900000000000; //int kbest; //int olddeg; int br=0; for (int k=0; k<nodes.Len(); k++) { if (k<nodes.Len()-1) { if (nodes[k]==nodes[k+1]) { // go into same deg mode int kmin=-2; int knew=-1; while (kmin < 999999 && kmin !=-1 ) { int kind=-1; knew=k; kmin=999999; while(nodes[k]==nodes[knew] && knew < nodes.Len()-1) { int inter = Intersect(Graph->GetNI(nodesIds[knew]),NNodes,NNodes_br); int deg = nodes[knew]; //if (((((nodes.Len()-NNodes_br)*(nodes.Len()-NNodes_br)))-(nodes.Len()-NNodes_br))/2<(((br*br)-br)/2)) if ((deg-inter)<kmin && !GroupNodes.IsKey(nodesIds[knew])) { kmin = deg-inter; kind = knew; } knew++; } if (kind!=-1) { br++; Z = Z + br - 1 - nodes[kind]; if (Z < (Zbest)) { // or <= //if (olddeg>nodes[kind]) //olddeg = nodes[kind]; Zbest = Z; //kbest = br; int w = nodes[kind]; int id = nodesIds[kind]; GroupNodes.AddDat(id,w); NNodes[NNodes_br] = id; NNodes_br++; } else { break; } } } k=knew-1; } else { br++; Z = Z + br - 1 - nodes[k]; if (Z < (Zbest)) { // or <= //if (olddeg>nodes[k]) //olddeg = nodes[k]; Zbest = Z; //kbest = br; int w = nodes[k]; int id = nodesIds[k]; GroupNodes.AddDat(id,w); NNodes[NNodes_br] = id; NNodes_br++; } } } else { br++; Z = Z + br - 1 - nodes[k]; if (Z < Zbest) { // or <= //if (olddeg>nodes[k]) //olddeg = nodes[k]; Zbest = Z; //kbest = br; int w = nodes[k]; int id = nodesIds[k]; GroupNodes.AddDat(id,w); NNodes[NNodes_br] = id; NNodes_br++; } } } int cp = 0; br = 0; for (THashKeyDatI<TInt, TInt> it = nodes.BegI(); !it.IsEnd(); it++) { if (GroupNodes.IsKey(it.GetKey())) cp = 1; else cp = 0; out.AddDat(it.GetKey(), cp); br++; } /*for (THashKeyDatI<TInt, TInt> it = GroupNodes.BegI(); it < GroupNodes.EndI(); it++) { out.AddDat(it.GetKey(), 1); br++; }*/ //return kbest; return GroupNodes.Len(); }