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(UGraph, NId)); } 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; }
void TCliqueOverlap::GetMaximalCliques(const PUNGraph& G, int MinMaxCliqueSize, TVec<TIntV>& MaxCliques) { if (G->GetNodes() == 0) return; // m_G = G; m_minMaxCliqueSize = MinMaxCliqueSize; m_maxCliques =& MaxCliques; m_Q.Clr(); // THashSet<TInt> SUBG; THashSet<TInt> CAND; for (TUNGraph::TNodeI NI=m_G->BegNI(); NI<m_G->EndNI(); NI++) { TInt nId = NI.GetId(); SUBG.AddKey(nId); CAND.AddKey(nId); } // Expand(SUBG, CAND); }
double GetGroupDegreeCentr(const PUNGraph& Graph, const TIntH& GroupNodes) { int deg; TIntH NN; TIntH GroupNodes1; for (THashKeyDatI<TInt, TInt> NI = GroupNodes.BegI(); NI < GroupNodes.EndI(); NI++) GroupNodes1.AddDat(NI.GetDat(), NI.GetDat()); for (THashKeyDatI<TInt, TInt> NI = GroupNodes1.BegI(); NI < GroupNodes1.EndI(); NI++){ TUNGraph::TNodeI node = Graph->GetNI(NI.GetKey()); deg = node.GetDeg(); for (int j = 0; j < deg; j++){ if (GroupNodes1.IsKey(node.GetNbrNId(j)) == 0 && NN.IsKey(node.GetNbrNId(j)) == 0) NN.AddDat(node.GetNbrNId(j), NI.GetKey()); } } return (double)NN.Len(); }
// GIRVAN-NEWMAN algorithm // 1. The betweenness of all existing edges in the network is calculated first. // 2. The edge with the highest betweenness is removed. // 3. The betweenness of all edges affected by the removal is recalculated. // 4. Steps 2 and 3 are repeated until no edges remain. // Girvan M. and Newman M. E. J., Community structure in social and biological networks, Proc. Natl. Acad. Sci. USA 99, 7821–7826 (2002) // Keep removing edges from Graph until one of the connected components of Graph splits into two. void CmtyGirvanNewmanStep(PUNGraph& Graph, TIntV& Cmty1, TIntV& Cmty2) { TIntPrFltH BtwEH; TBreathFS<PUNGraph> BFS(Graph); Cmty1.Clr(false); Cmty2.Clr(false); while (true) { TSnap::GetBetweennessCentr(Graph, BtwEH); BtwEH.SortByDat(false); if (BtwEH.Empty()) { return; } const int NId1 = BtwEH.GetKey(0).Val1; const int NId2 = BtwEH.GetKey(0).Val2; Graph->DelEdge(NId1, NId2); BFS.DoBfs(NId1, true, false, NId2, TInt::Mx); if (BFS.GetHops(NId1, NId2) == -1) { // two components TSnap::GetNodeWcc(Graph, NId1, Cmty1); TSnap::GetNodeWcc(Graph, NId2, Cmty2); return; } } }
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); }
// 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; }
///Connect members of a given community by Erdos-Renyi void TAGM::RndConnectInsideCommunity(PUNGraph& Graph, const TIntV& CmtyV, const double& Prob, TRnd& Rnd) { int CNodes = CmtyV.Len(), CEdges; if (CNodes < 20) { CEdges = (int) Rnd.GetBinomialDev(Prob, CNodes * (CNodes-1) / 2); } else { CEdges = (int) (Prob * CNodes * (CNodes - 1) / 2); } THashSet<TIntPr> NewEdgeSet(CEdges); for (int edge = 0; edge < CEdges; ) { int SrcNId = CmtyV[Rnd.GetUniDevInt(CNodes)]; int DstNId = CmtyV[Rnd.GetUniDevInt(CNodes)]; if (SrcNId > DstNId) { Swap(SrcNId,DstNId); } if (SrcNId != DstNId && ! NewEdgeSet.IsKey(TIntPr(SrcNId, DstNId))) { // is new edge NewEdgeSet.AddKey(TIntPr(SrcNId, DstNId)); Graph->AddEdge(SrcNId, DstNId); edge++; } } }
void GetInvParticipRat(const PUNGraph& Graph, int MaxEigVecs, int TimeLimit, TFltPrV& EigValIprV) { TUNGraphMtx GraphMtx(Graph); TFltVV EigVecVV; TFltV EigValV; TExeTm ExeTm; if (MaxEigVecs<=1) { MaxEigVecs=1000; } int EigVecs = TMath::Mn(Graph->GetNodes(), MaxEigVecs); printf("start %d vecs...", EigVecs); try { TSparseSVD::Lanczos2(GraphMtx, EigVecs, TimeLimit, ssotFull, EigValV, EigVecVV, false); } catch(...) { printf("\n ***EXCEPTION: TRIED %d GOT %d values** \n", EigVecs, EigValV.Len()); } printf(" ***TRIED %d GOT %d values in %s\n", EigVecs, EigValV.Len(), ExeTm.GetStr()); TFltV EigVec; EigValIprV.Clr(); if (EigValV.Empty()) { return; } for (int v = 0; v < EigVecVV.GetCols(); v++) { EigVecVV.GetCol(v, EigVec); EigValIprV.Add(TFltPr(EigValV[v], GetInvParticipRat(EigVec))); } EigValIprV.Sort(); }
double GetDegreeCentralization(const PUNGraph& Graph) { int MaxDeg = -1; int N = Graph->GetNodes(); int Sum = 0; if (Graph->GetNodes() > 1 && (double(N - 2.0)*double(N - 1)) > 0) { for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { int deg = NI.GetDeg(); if (deg > MaxDeg) { MaxDeg = deg; } } for (TUNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Sum += MaxDeg - NI.GetDeg(); } return double(Sum) / (double(N - 2.0)*double(N - 1)); } else { return 0.0; } }
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; } }
void sample (const int *m, const int *n, const int *h, const int *ns, const int *in, const int *infection_state, const int *mde, const int *bi, const int *br, double * result) { const int nodes = *h; const int nval = (*n)/2; int num_seeds = *ns; int infect_type = *in; int mode = *mde; int burnin = *bi; int branch = *br; PUNGraph g = get_PUNGraph (m, nval, nodes); THash<TInt, TInt> * visited = choose_seeds (g, num_seeds, infection_state, infect_type); TVec <VisitedNode *> queue; TIntV qids; for (THash<TInt, TInt>::TIter n = visited->BegI(); n != visited->EndI(); n++) { queue = queue + new VisitedNode (n->Key); qids = qids + n->Key; //cerr << "enqueued " << n->Key << endl; } TInt counted = 0; TInt first_unprocessed = 0; TFlt infected_mass = 0.0; TFlt total_mass = 0.0; TFlt revisits = 0.0; TFlt trehits = 0.0; //cerr << "nodeId\tneigh\tnbh_size\tinfected?\tinfected_mass\ttotal_mass" << endl; while (counted < 500 && first_unprocessed < queue.Len()) { VisitedNode * current_node = queue [first_unprocessed]; first_unprocessed++; TUNGraph::TNodeI NI = g->GetNI (current_node->id); TInt neighborhood_size = NI.GetDeg(); // cerr << counted << " " << current_node->id << endl; if (counted >= burnin) { if (infection_state[(current_node->id) - 1] == 1) infected_mass += 1.0/TFlt(neighborhood_size); total_mass += 1.0/TFlt(neighborhood_size); } //cerr << current_node->id << "\t" << neighborhood_size << "\t" << (1.0/TFlt(neighborhood_size)) // << "\t" << infection_state[(current_node->id) - 1] << "\t" << infected_mass << "\t" << total_mass << endl; // build list of unvisited neighbors TVec<TInt> neighbors; for (int i = 0; i < neighborhood_size; i++) { TInt neighbor = NI.GetNbrNId(i); if (mode == 0 && visited->IsKey(neighbor)) continue; else if (mode == 2 && isChild (current_node, neighbor)) continue; else if (mode == 3 && current_node-> previous != NULL && current_node->previous->id == neighbor) continue; else neighbors = neighbors + neighbor; } TInt num_legal_neighbors = neighbors.Len(); TInt sample_size = TMath::Mn<TInt> (branch, num_legal_neighbors); THash <TInt, TInt> * choices = choose (num_legal_neighbors, sample_size); for (THash<TInt, TInt>::TIter n = choices->BegI(); n != choices->EndI(); n++) { if (queue.Len() >= 500) break; queue = queue + new VisitedNode (neighbors[n->Key], current_node); if (visited->IsKey(neighbors[n->Key])) revisits++; if (isChild(current_node, neighbors[n->Key])) trehits++; if (!visited->IsKey(neighbors[n->Key])) qids = qids + neighbors[n->Key]; visited->AddDat(neighbors[n->Key], 1); } counted++; } // cout << (infected_mass / total_mass) << endl; delete (visited); result[0] = (infected_mass / total_mass); result[1] = revisits; result[2] = trehits; result[3] = counted; //PUNGraph p (&g); PUNGraph p = TSnap:: GetSubGraph (g, qids, false); TCnComV convec; result[4] = TSnap::GetClustCf(p, -1); TSnap::GetWccs(p, convec); result[5] = convec.Len(); result[6] = ave_path_length (p); }
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; }
TCNMQMatrix(const PUNGraph& Graph) : CmtyQH(Graph->GetNodes()), MxQHeap(Graph->GetNodes(), 0), CmtyIdUF(Graph->GetNodes()) { Init(Graph); }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("cesna. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try TStr OutFPrx = Env.GetIfArgPrefixStr("-o:", "", "Output Graph data prefix"); const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "./1912.edges", "Input edgelist file name"); const TStr LabelFNm = Env.GetIfArgPrefixStr("-l:", "", "Input file name for node names (Node ID, Node label) "); const TStr AttrFNm = Env.GetIfArgPrefixStr("-a:", "./1912.nodefeat", "Input node attribute file name"); const TStr ANameFNm = Env.GetIfArgPrefixStr("-n:", "./1912.nodefeatnames", "Input file name for node attribute names"); int OptComs = Env.GetIfArgPrefixInt("-c:", 10, "The number of communities to detect (-1: detect automatically)"); const int MinComs = Env.GetIfArgPrefixInt("-mc:", 3, "Minimum number of communities to try"); const int MaxComs = Env.GetIfArgPrefixInt("-xc:", 20, "Maximum number of communities to try"); const int DivComs = Env.GetIfArgPrefixInt("-nc:", 5, "How many trials for the number of communities"); const int NumThreads = Env.GetIfArgPrefixInt("-nt:", 4, "Number of threads for parallelization"); const double AttrWeight = Env.GetIfArgPrefixFlt("-aw:", 0.5, "We maximize (1 - aw) P(Network) + aw * P(Attributes)"); const double LassoWeight = Env.GetIfArgPrefixFlt("-lw:", 1.0, "Weight for l-1 regularization on learning the logistic model parameters"); const double StepAlpha = Env.GetIfArgPrefixFlt("-sa:", 0.05, "Alpha for backtracking line search"); const double StepBeta = Env.GetIfArgPrefixFlt("-sb:", 0.3, "Beta for backtracking line search"); const double MinFeatFrac = Env.GetIfArgPrefixFlt("-mf:", 0.0, "If the fraction of nodes with positive values for an attribute is smaller than this, we ignore that attribute"); #ifdef USE_OPENMP omp_set_num_threads(NumThreads); #endif PUNGraph G; TIntStrH NIDNameH; TStrHash<TInt> NodeNameH; TVec<TFltV> Wck; TVec<TIntV> EstCmtyVV; if (InFNm.IsStrIn(".ungraph")) { TFIn GFIn(InFNm); G = TUNGraph::Load(GFIn); } else { G = TAGMUtil::LoadEdgeListStr<PUNGraph>(InFNm, NodeNameH); NIDNameH.Gen(NodeNameH.Len()); for (int s = 0; s < NodeNameH.Len(); s++) { NIDNameH.AddDat(s, NodeNameH.GetKey(s)); } } if (LabelFNm.Len() > 0) { TSsParser Ss(LabelFNm, ssfTabSep); while (Ss.Next()) { if (Ss.Len() > 0) { NIDNameH.AddDat(Ss.GetInt(0), Ss.GetFld(1)); } } } printf("Graph: %d Nodes %d Edges\n", G->GetNodes(), G->GetEdges()); //load attribute TIntV NIDV; G->GetNIdV(NIDV); THash<TInt, TIntV> RawNIDAttrH, NIDAttrH; TIntStrH RawFeatNameH, FeatNameH; if (ANameFNm.Len() > 0) { TSsParser Ss(ANameFNm, ssfTabSep); while (Ss.Next()) { if (Ss.Len() > 0) { RawFeatNameH.AddDat(Ss.GetInt(0), Ss.GetFld(1)); } } } TCesnaUtil::LoadNIDAttrHFromNIDKH(NIDV, AttrFNm, RawNIDAttrH, NodeNameH); TCesnaUtil::FilterLowEntropy(RawNIDAttrH, NIDAttrH, RawFeatNameH, FeatNameH, MinFeatFrac); TExeTm RunTm; TCesna CS(G, NIDAttrH, 10, 10); if (OptComs == -1) { printf("finding number of communities\n"); OptComs = CS.FindComs(NumThreads, MaxComs, MinComs, DivComs, "", false, 0.1, StepAlpha, StepBeta); } CS.NeighborComInit(OptComs); CS.SetWeightAttr(AttrWeight); CS.SetLassoCoef(LassoWeight); if (NumThreads == 1 || G->GetEdges() < 1000) { CS.MLEGradAscent(0.0001, 1000 * G->GetNodes(), "", StepAlpha, StepBeta); } else { CS.MLEGradAscentParallel(0.0001, 1000, NumThreads, "", StepAlpha, StepBeta); } CS.GetCmtyVV(EstCmtyVV, Wck); TAGMUtil::DumpCmtyVV(OutFPrx + "cmtyvv.txt", EstCmtyVV, NIDNameH); FILE* F = fopen((OutFPrx + "weights.txt").CStr(), "wt"); if (FeatNameH.Len() == Wck[0].Len()) { fprintf(F, "#"); for (int k = 0; k < FeatNameH.Len(); k++) { fprintf(F, "%s", FeatNameH[k].CStr()); if (k < FeatNameH.Len() - 1) { fprintf(F, "\t"); } } fprintf(F, "\n"); } for (int c = 0; c < Wck.Len(); c++) { for (int k = 0; k < Wck[c].Len(); k++) { fprintf(F, "%f", Wck[c][k].Val); if (k < Wck[c].Len() - 1) { fprintf(F, "\t"); } } fprintf(F, "\n"); } fclose(F); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Memetracker Converter. Build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm()), 1, true); const TStr netinfInputFile = Env.GetIfArgPrefixStr( "-netinfInputFile=", "data/memetracker/InfoNet5000Q1000NEXP.txt", "File containing the inferred network, used as underlying structure"); const TStr clusteredCascadesInputFile = Env.GetIfArgPrefixStr( "-clusteredCascadesInputFile=", "data/memetracker/clust-qt08080902w3mfq5.txt", "File containing clustered instances of memes and their path on the web"); const TInt cascadeInputLine = Env.GetIfArgPrefixInt( "-cascadeInputLine=", 75926, "Specific cascade to read from clusteredCascadesInputFile"); const TStr snapNetworkOutputFile = Env.GetIfArgPrefixStr( "-snapNetworkOutputFile=", "data/memetracker/memeNetwork.dat", "File where to write the output network as a snap binary"); const TStr groundTruthOutputFile = Env.GetIfArgPrefixStr( "-groundTruthOutputFile=", "data/memetracker/memeGroundTruth.txt", "File where to write the ground truth"); // Build the network from the most popular websites. ifstream inputfile(netinfInputFile.CStr()); string line; getline(inputfile, line); // read header line from file map<string, unsigned int> urlToNodeIdHash; PUNGraph graph = PUNGraph::New(); unsigned int nodeId = 0; while (getline(inputfile, line)) { istringstream iss(line); string idx, src, dst; iss >> idx >> src >> dst; if (urlToNodeIdHash.find(src) == urlToNodeIdHash.end()) { urlToNodeIdHash[src] = nodeId; graph->AddNode(nodeId); nodeId++; } if (urlToNodeIdHash.find(dst) == urlToNodeIdHash.end()) { urlToNodeIdHash[dst] = nodeId; graph->AddNode(nodeId); nodeId++; } graph->AddEdge(urlToNodeIdHash[src], urlToNodeIdHash[dst]); } // Save network. { TFOut FOut(snapNetworkOutputFile); graph->Save(FOut); } // Read one memetracker entry. ifstream memetracker(clusteredCascadesInputFile.CStr()); for (int i = 0; i < cascadeInputLine; ++i) getline(memetracker, line); getline(memetracker, line); int entries, dummyInt; istringstream iss(line); iss >> dummyInt >> entries; cout << "Building cascade for "; while (!iss.eof()) { string phrase; iss >> phrase; cout << phrase << " "; } cout << endl; // Dump cascade to some file. ofstream dumpStream; dumpStream.open(groundTruthOutputFile.CStr()); string dummy, url; map<string, unsigned int> infectionTimeHash; unsigned int infectionTime = 0; for (int i = 0; i < entries; ++i) { // Read through each "infected" URL. getline(memetracker, line); istringstream iss(line); // These fields of the cascade entry ar not important. iss >> dummy >> dummy >> dummy >> dummy; iss >> url; // Parse the URL and identify the host website. uri::uri instance(url); assert(instance.is_valid()); // If node not in network or already infected, skip. if (urlToNodeIdHash.find(instance.host()) == urlToNodeIdHash.end() || infectionTimeHash.find(instance.host()) != infectionTimeHash.end()) continue; infectionTimeHash[instance.host()] = infectionTime++; // Dump as pair of <nodeId, infectionTime>. dumpStream << urlToNodeIdHash[instance.host()] << " " << infectionTimeHash[instance.host()] << endl; } return 0; }
PUNGraph TAGM::GenAGM(TVec<TIntV>& CmtyVV, const double& DensityCoef, const int TargetEdges, TRnd& Rnd) { PUNGraph TryG = TAGM::GenAGM(CmtyVV, DensityCoef, 1.0, Rnd); const double ScaleCoef = (double) TargetEdges / (double) TryG->GetEdges(); return TAGM::GenAGM(CmtyVV, DensityCoef, ScaleCoef, Rnd); }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("cpm. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try TStr OutFPrx = Env.GetIfArgPrefixStr("-o:", "", "Output file name prefix"); const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "football.edgelist", "Input edgelist file name. DEMO: AGM with 2 communities"); const TStr LabelFNm = Env.GetIfArgPrefixStr("-l:", "football.labels", "Input file name for node names (Node ID, Node label) "); const TInt RndSeed = Env.GetIfArgPrefixInt("-s:", 0, "Random seed for AGM"); const TFlt Epsilon = Env.GetIfArgPrefixFlt("-e:", 0, "Edge probability between the nodes that do not share any community (default (0.0): set it to be 1 / N^2)"); const TInt Coms = Env.GetIfArgPrefixInt("-c:", 0, "Number of communities (0: determine it by AGM)"); PUNGraph G = TUNGraph::New(); TVec<TIntV> CmtyVV; TIntStrH NIDNameH; if (InFNm == "DEMO") { TVec<TIntV> TrueCmtyVV; TRnd AGMRnd(RndSeed); //generate community bipartite affiliation const int ABegin = 0, AEnd = 70, BBegin = 30, BEnd = 100; TrueCmtyVV.Add(TIntV()); TrueCmtyVV.Add(TIntV()); for (int u = ABegin; u < AEnd; u++) { TrueCmtyVV[0].Add(u); } for (int u = BBegin; u < BEnd; u++) { TrueCmtyVV[1].Add(u); } G = TAGM::GenAGM(TrueCmtyVV, 0.0, 0.2, AGMRnd); } else if (LabelFNm.Len() > 0) { G = TSnap::LoadEdgeList<PUNGraph>(InFNm); TSsParser Ss(LabelFNm, ssfTabSep); while (Ss.Next()) { if (Ss.Len() > 0) { NIDNameH.AddDat(Ss.GetInt(0), Ss.GetFld(1)); } } } else { G = TAGMUtil::LoadEdgeListStr<PUNGraph>(InFNm, NIDNameH); } printf("Graph: %d Nodes %d Edges\n", G->GetNodes(), G->GetEdges()); int MaxIter = 50 * G->GetNodes() * G->GetNodes(); if (MaxIter < 0) { MaxIter = TInt::Mx; } int NumComs = Coms; if (NumComs < 2) { int InitComs; if (G->GetNodes() > 1000) { InitComs = G->GetNodes() / 5; NumComs = TAGMUtil::FindComsByAGM(G, InitComs, MaxIter, RndSeed, 1.5, Epsilon, OutFPrx); } else { InitComs = G->GetNodes() / 5; NumComs = TAGMUtil::FindComsByAGM(G, InitComs, MaxIter, RndSeed, 1.2, Epsilon, OutFPrx); } } TAGMFit AGMFit(G, NumComs, RndSeed); if (Epsilon > 0) { AGMFit.SetPNoCom(Epsilon); } AGMFit.RunMCMC(MaxIter, 10); AGMFit.GetCmtyVV(CmtyVV, 0.9999); TAGMUtil::DumpCmtyVV(OutFPrx + "cmtyvv.txt", CmtyVV, NIDNameH); TAGMUtil::SaveGephi(OutFPrx + "graph.gexf", G, CmtyVV, 1.5, 1.5, NIDNameH); AGMFit.PrintSummary(); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
// 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); }
// 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()); }
// 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; }
/// 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 main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs( TStr::Fmt("ragm. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try TStr OutFPrx = Env.GetIfArgPrefixStr("-o:", "", "Output Graph data prefix"); const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "../as20graph.txt", "Input edgelist file name"); const TStr LabelFNm = Env.GetIfArgPrefixStr("-l:", "", "Input file name for node names (Node ID, Node label) "); int OptComs = Env.GetIfArgPrefixInt("-c:", 100, "The number of communities to detect (-1: detect automatically)"); const int MinComs = Env.GetIfArgPrefixInt("-mc:", 5, "Minimum number of communities to try"); const int MaxComs = Env.GetIfArgPrefixInt("-xc:", 100, "Maximum number of communities to try"); const int DivComs = Env.GetIfArgPrefixInt("-nc:", 10, "How many trials for the number of communities"); const int NumThreads = Env.GetIfArgPrefixInt("-nt:", 4, "Number of threads for parallelization"); const double StepAlpha = Env.GetIfArgPrefixFlt("-sa:", 0.05, "Alpha for backtracking line search"); const double StepBeta = Env.GetIfArgPrefixFlt("-sb:", 0.3, "Beta for backtracking line search"); #ifndef NOMP omp_set_num_threads(NumThreads); #endif PUNGraph G; TIntStrH NIDNameH; if (InFNm.IsStrIn(".ungraph")) { TFIn GFIn(InFNm); G = TUNGraph::Load(GFIn); } else { G = TAGMUtil::LoadEdgeListStr<PUNGraph>(InFNm, NIDNameH); } if (LabelFNm.Len() > 0) { TSsParser Ss(LabelFNm, ssfTabSep); while (Ss.Next()) { if (Ss.Len() > 0) { NIDNameH.AddDat(Ss.GetInt(0), Ss.GetFld(1)); } } } printf("Graph: %d Nodes %d Edges\n", G->GetNodes(), G->GetEdges()); TVec<TIntV> EstCmtyVV; TExeTm RunTm; TAGMFast RAGM(G, 10, 10); if (OptComs == -1) { printf("finding number of communities\n"); OptComs = RAGM.FindComsByCV(NumThreads, MaxComs, MinComs, DivComs, OutFPrx, StepAlpha, StepBeta); } RAGM.NeighborComInit(OptComs); if (NumThreads == 1 || G->GetEdges() < 1000) { RAGM.MLEGradAscent(0.0001, 1000 * G->GetNodes(), "", StepAlpha, StepBeta); } else { RAGM.MLEGradAscentParallel(0.0001, 1000, NumThreads, "", StepAlpha, StepBeta); } RAGM.GetCmtyVV(EstCmtyVV); TAGMUtil::DumpCmtyVV(OutFPrx + "cmtyvv.txt", EstCmtyVV, NIDNameH); TAGMUtil::SaveGephi(OutFPrx + "graph.gexf", G, EstCmtyVV, 1.5, 1.5, NIDNameH); Catch printf("\nrun time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
// Demos BFS functions on undirected graph that is not fully connected void DemoBFSUndirectedRandom() { PUNGraph G; TStr FName = TStr::Fmt("%s/sample_bfsdfs_unpower.txt", DIRNAME); const int NNodes = 50; G = GenRndPowerLaw(NNodes, 2.5); // Can save/here // SaveEdgeList(G, FName); // G = LoadEdgeList<PUNGraph>(FName); TIntStrH NodeLabelH; for (int i = 0; i < G->GetNodes(); i++) { NodeLabelH.AddDat(i, TStr::Fmt("%d", i)); } DrawGViz(G, gvlNeato, TStr::Fmt("%s/sample_bfsdfs_unpower.png", DIRNAME), "Sample bfsdfs Graph", NodeLabelH); TIntV NIdV; int StartNId, Hop, Nodes; int IsDir = 0; printf("IsDir = %d:\n", IsDir); StartNId = 1; Hop = 1; Nodes = GetNodesAtHop(G, StartNId, Hop, NIdV, IsDir); printf("StartNId = %d, Nodes = %d, GetNodesAtHop NIdV.Len() = %d, NIdV[0] = %d\n", StartNId, Nodes, NIdV.Len(), NIdV[0].Val); TIntPrV HopCntV; Nodes = GetNodesAtHops(G, StartNId, HopCntV, IsDir); printf("StartNId = %d, Nodes = %d, GetNodesAtHops HopCntV.Len() = %d\n", StartNId , Nodes, HopCntV.Len()); // for (int N = 0; N < HopCntV.Len(); N++) { // printf("HopCntV[%d] = (%d, %d)\n", N, HopCntV[N].Val1.Val, HopCntV[N].Val2.Val); // } int Length, SrcNId, DstNId; SrcNId = 1; DstNId = G->GetNodes() - 1; Length = GetShortPath(G, SrcNId, DstNId, IsDir); printf("%d -> %d: SPL Length = %d\n", SrcNId, DstNId, Length); SrcNId = 1; DstNId = 33; Length = GetShortPath(G, SrcNId, DstNId, IsDir); printf("%d -> %d: SPL Length = %d\n", SrcNId, DstNId, Length); TIntH NIdToDistH; int MaxDist = 9; Length = GetShortPath(G, SrcNId, NIdToDistH, IsDir, MaxDist); // for (int i = 0; i < min(5,NIdToDistH.Len()); i++) { // printf("NIdToDistH[%d] = %d\n", i, NIdToDistH[i].Val); // } TInt::Rnd.PutSeed(0); int FullDiam; double EffDiam, AvgSPL; int NTestNodes = G->GetNodes() / 3 * 2; FullDiam = GetBfsFullDiam(G, NTestNodes, IsDir); printf("FullDiam = %d\n", FullDiam); EffDiam = GetBfsEffDiam(G, NTestNodes, IsDir); printf("EffDiam = %.3f\n", EffDiam); EffDiam = GetBfsEffDiam(G, NTestNodes, IsDir, EffDiam, FullDiam); printf("EffDiam = %.3f, FullDiam = %d\n", EffDiam, FullDiam); EffDiam = GetBfsEffDiam(G, NTestNodes, IsDir, EffDiam, FullDiam, AvgSPL); printf("EffDiam = %.3f, FullDiam = %d, AvgDiam = %.3f\n", EffDiam, FullDiam, AvgSPL); TIntV SubGraphNIdV; SubGraphNIdV.Add(0); SubGraphNIdV.Add(4); SubGraphNIdV.Add(31); SubGraphNIdV.Add(45); SubGraphNIdV.Add(18); SubGraphNIdV.Add(11); SubGraphNIdV.Add(11); SubGraphNIdV.Add(48); SubGraphNIdV.Add(34); SubGraphNIdV.Add(30); EffDiam = GetBfsEffDiam(G, NTestNodes, SubGraphNIdV, IsDir, EffDiam, FullDiam); printf("For subgraph: EffDiam = %.4f, FullDiam = %d\n", EffDiam, FullDiam); }
/// estimate number of communities using AGM int TAGMUtil::FindComsByAGM(const PUNGraph& Graph, const int InitComs, const int MaxIter, const int RndSeed, const double RegGap, const double PNoCom, const TStr PltFPrx) { TRnd Rnd(RndSeed); int LambdaIter = 100; if (Graph->GetNodes() < 200) { LambdaIter = 1; } if (Graph->GetNodes() < 200 && Graph->GetEdges() > 2000) { LambdaIter = 100; } //Find coms with large C TAGMFit AGMFitM(Graph, InitComs, RndSeed); if (PNoCom > 0.0) { AGMFitM.SetPNoCom(PNoCom); } AGMFitM.RunMCMC(MaxIter, LambdaIter, ""); int TE = Graph->GetEdges(); TFltV RegV; RegV.Add(0.3 * TE); for (int r = 0; r < 25; r++) { RegV.Add(RegV.Last() * RegGap); } TFltPrV RegComsV, RegLV, RegBICV; TFltV LV, BICV; //record likelihood and number of communities with nonzero P_c for (int r = 0; r < RegV.Len(); r++) { double RegCoef = RegV[r]; AGMFitM.SetRegCoef(RegCoef); AGMFitM.MLEGradAscentGivenCAG(0.01, 1000); AGMFitM.SetRegCoef(0.0); TVec<TIntV> EstCmtyVV; AGMFitM.GetCmtyVV(EstCmtyVV, 0.99); int NumLowQ = EstCmtyVV.Len(); RegComsV.Add(TFltPr(RegCoef, (double) NumLowQ)); if (EstCmtyVV.Len() > 0) { TAGMFit AFTemp(Graph, EstCmtyVV, Rnd); AFTemp.MLEGradAscentGivenCAG(0.001, 1000); double CurL = AFTemp.Likelihood(); LV.Add(CurL); BICV.Add(-2.0 * CurL + (double) EstCmtyVV.Len() * log((double) Graph->GetNodes() * (Graph->GetNodes() - 1) / 2.0)); } else { break; } } // if likelihood does not exist or does not change at all, report the smallest number of communities or 2 if (LV.Len() == 0) { return 2; } else if (LV[0] == LV.Last()) { return (int) TMath::Mx<TFlt>(2.0, RegComsV[LV.Len() - 1].Val2); } //normalize likelihood and BIC to 0~100 int MaxL = 100; { TFltV& ValueV = LV; TFltPrV& RegValueV = RegLV; double MinValue = TFlt::Mx, MaxValue = TFlt::Mn; for (int l = 0; l < ValueV.Len(); l++) { if (ValueV[l] < MinValue) { MinValue = ValueV[l]; } if (ValueV[l] > MaxValue) { MaxValue = ValueV[l]; } } while (ValueV.Len() < RegV.Len()) { ValueV.Add(MinValue); } double RangeVal = MaxValue - MinValue; for (int l = 0; l < ValueV.Len(); l++) { RegValueV.Add(TFltPr(RegV[l], double(MaxL) * (ValueV[l] - MinValue) / RangeVal)); } } { TFltV& ValueV = BICV; TFltPrV& RegValueV = RegBICV; double MinValue = TFlt::Mx, MaxValue = TFlt::Mn; for (int l = 0; l < ValueV.Len(); l++) { if (ValueV[l] < MinValue) { MinValue = ValueV[l]; } if (ValueV[l] > MaxValue) { MaxValue = ValueV[l]; } } while (ValueV.Len() < RegV.Len()) { ValueV.Add(MaxValue); } double RangeVal = MaxValue - MinValue; for (int l = 0; l < ValueV.Len(); l++) { RegValueV.Add(TFltPr(RegV[l], double(MaxL) * (ValueV[l] - MinValue) / RangeVal)); } } //fit logistic regression to normalized likelihood. TVec<TFltV> XV(RegLV.Len()); TFltV YV (RegLV.Len()); for (int l = 0; l < RegLV.Len(); l++) { XV[l] = TFltV::GetV(log(RegLV[l].Val1)); YV[l] = RegLV[l].Val2 / (double) MaxL; } TFltPrV LRVScaled, LRV; TLogRegFit LRFit; PLogRegPredict LRMd = LRFit.CalcLogRegNewton(XV, YV, PltFPrx); for (int l = 0; l < RegLV.Len(); l++) { LRV.Add(TFltPr(RegV[l], LRMd->GetCfy(XV[l]))); LRVScaled.Add(TFltPr(RegV[l], double(MaxL) * LRV.Last().Val2)); } //estimate # communities from fitted logistic regression int NumComs = 0, IdxRegDrop = 0; double LRThres = 1.1, RegDrop; // 1 / (1 + exp(1.1)) = 0.25 double LeftReg = 0.0, RightReg = 0.0; TFltV Theta; LRMd->GetTheta(Theta); RegDrop = (- Theta[1] - LRThres) / Theta[0]; if (RegDrop <= XV[0][0]) { NumComs = (int) RegComsV[0].Val2; } else if (RegDrop >= XV.Last()[0]) { NumComs = (int) RegComsV.Last().Val2; } else { //interpolate for RegDrop for (int i = 0; i < XV.Len(); i++) { if (XV[i][0] > RegDrop) { IdxRegDrop = i; break; } } if (IdxRegDrop == 0) { printf("Error!! RegDrop:%f, Theta[0]:%f, Theta[1]:%f\n", RegDrop, Theta[0].Val, Theta[1].Val); for (int l = 0; l < RegLV.Len(); l++) { printf("X[%d]:%f, Y[%d]:%f\n", l, XV[l][0].Val, l, YV[l].Val); } } IAssert(IdxRegDrop > 0); LeftReg = RegDrop - XV[IdxRegDrop - 1][0]; RightReg = XV[IdxRegDrop][0] - RegDrop; NumComs = (int) TMath::Round( (RightReg * RegComsV[IdxRegDrop - 1].Val2 + LeftReg * RegComsV[IdxRegDrop].Val2) / (LeftReg + RightReg)); } //printf("Interpolation coeff: %f, %f, index at drop:%d (%f), Left-Right Vals: %f, %f\n", LeftReg, RightReg, IdxRegDrop, RegDrop, RegComsV[IdxRegDrop - 1].Val2, RegComsV[IdxRegDrop].Val2); printf("Num Coms:%d\n", NumComs); if (NumComs < 2) { NumComs = 2; } if (PltFPrx.Len() > 0) { TStr PlotTitle = TStr::Fmt("N:%d, E:%d ", Graph->GetNodes(), TE); TGnuPlot GPC(PltFPrx + ".l"); GPC.AddPlot(RegComsV, gpwLinesPoints, "C"); GPC.AddPlot(RegLV, gpwLinesPoints, "likelihood"); GPC.AddPlot(RegBICV, gpwLinesPoints, "BIC"); GPC.AddPlot(LRVScaled, gpwLinesPoints, "Sigmoid (scaled)"); GPC.SetScale(gpsLog10X); GPC.SetTitle(PlotTitle); GPC.SavePng(PltFPrx + ".l.png"); } return NumComs; }
///////////////////////////////////////////////// // Node centrality measures double GetDegreeCentr(const PUNGraph& Graph, const int& NId) { if (Graph->GetNodes() > 1) { return double(Graph->GetNI(NId).GetDeg()) / double(Graph->GetNodes() - 1); } else { return 0.0; } }
int main(int argc, char* argv[]) { //// what type of graph do you want to use? //typedef PUNGraph PGraph; // undirected graph typedef PNGraph PGraph; // directed graph //typedef PNEGraph PGraph; // directed multigraph //typedef TPt<TNodeNet<TInt> > PGraph; //typedef TPt<TNodeEdgeNet<TInt, TInt> > PGraph; // this code is independent of what particular graph implementation/type we use printf("Creating graph:\n"); PGraph G = PGraph::TObj::New(); for (int n = 0; n < 14; n++) { G->AddNode(); // if no parameter is given, node ids are 0,1,...,9 } G->AddEdge(1, 4); printf(" Edge 1 -- 4 added\n"); G->AddEdge(1, 3); printf(" Edge 1 -- 3 added\n"); G->AddEdge(2, 5); printf(" Edge 2 -- 5 added\n"); G->AddEdge(3, 2); printf(" Edge 3 -- 2 added\n"); G->AddEdge(3, 5); printf(" Edge 3 -- 5 added\n"); G->AddEdge(3, 10); printf(" Edge 3 -- 10 added\n"); /*for (int e = 0; e < 10; e++) { const int NId1 = G->GetRndNId(); const int NId2 = G->GetRndNId(); if (G->AddEdge(NId1, NId2) != -2) { printf(" Edge %d -- %d added\n", NId1, NId2); } else { printf(" Edge %d -- %d already exists\n", NId1, NId2); } }*/ IAssert(G->IsOk()); //G->Dump(); // delete PGraph::TObj::TNodeI NI = G->GetNI(0); printf("Delete edge %d -- %d\n", NI.GetId(), NI.GetOutNId(0)); G->DelEdge(NI.GetId(), NI.GetOutNId(0)); const int RndNId = G->GetRndNId(); printf("Delete node %d\n", RndNId); G->DelNode(RndNId); IAssert(G->IsOk()); // dump the graph printf("Graph (%d, %d)\n", G->GetNodes(), G->GetEdges()); for (PGraph::TObj::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { printf(" %d: ", NI.GetId()); for (int e = 0; e < NI.GetDeg(); e++) { printf(" %d", NI.GetNbrNId(e)); } printf("\n"); } // dump subgraph TIntV NIdV; for (PGraph::TObj::TNodeI NI = G->BegNI(); NI < G->EndNI(); NI++) { if (NIdV.Len() < G->GetNodes()/2) { NIdV.Add(NI.GetId()); } } PGraph SubG = TSnap::GetSubGraph(G, NIdV); //SubG->Dump(); // get UNGraph { PUNGraph UNG = TSnap::ConvertGraph<PUNGraph>(SubG); UNG->Dump(); IAssert(UNG->IsOk()); TSnap::ConvertSubGraph<PNGraph>(G, NIdV)->Dump(); } // get NGraph { PNGraph NG = TSnap::ConvertGraph<PNGraph>(SubG); NG->Dump(); IAssert(NG->IsOk()); TSnap::ConvertSubGraph<PNGraph>(G, NIdV)->Dump(); } // get NEGraph { PNEGraph NEG = TSnap::ConvertGraph<PNEGraph>(SubG); NEG->Dump(); IAssert(NEG->IsOk()); TSnap::ConvertSubGraph<PNGraph>(G, NIdV)->Dump(); } TSnap::TestAnf<PUNGraph>(); return 0; }
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; } } } }
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(); }
// Print graph statistics void PrintGStats(const char s[], PUNGraph Graph) { printf("graph %s, nodes %d, edges %d, empty %s\n", s, Graph->GetNodes(), Graph->GetEdges(), Graph->Empty() ? "yes" : "no"); }
void GetArtPoints(const PUNGraph& Graph, TIntV& ArtNIdV) { TArtPointVisitor Visitor(Graph->GetNodes()); TCnCom::GetDfsVisitor(Graph, Visitor); Visitor.ArtSet.GetKeyV(ArtNIdV); }