// Test node subgraph conversion void TestConvertSubGraphs() { PNGraph NGraph; PUNGraph UNGraph; int N1, N2, N3; int E1, E2, E3; TIntV NIdV; int i; NGraph = GetTestTNGraph(); N1 = NGraph->GetNodes(); E1 = NGraph->GetEdges(); for (i = 0; i < 20; i += 2) { NIdV.Add(i); } // TODO: fix TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true), it fails // UNGraph = TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true); UNGraph = TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV); N2 = UNGraph->GetNodes(); E2 = UNGraph->GetEdges(); NGraph = TSnap::ConvertSubGraph<PNGraph>(UNGraph, NIdV); N3 = NGraph->GetNodes(); E3 = NGraph->GetEdges(); printf("---- TestConvertSubGraphs -----\n"); printf("nodes: %d,%d,%d, edges: %d,%d,%d\n", N1, N2, N3, E1, E2, E3); printf("\n"); }
// Test GetCmnNbrs: the number of neighbors in common TEST(triad, TestGetCmnNbrs) { // Test TUNGraph PUNGraph GraphTUN = TriadGetTestTUNGraph(); for (int i = 0; i < GraphTUN->GetNodes(); i++) { for (int j = i + 1; j < GraphTUN->GetNodes(); j++) { VerifyCmnNbrs(i, j, TSnap::GetCmnNbrs(GraphTUN, i, j)); } } // Test TNGraph which is same as undirected. PNGraph GraphTN = TriadGetTestTNGraph(); for (int i = 0; i < GraphTN->GetNodes(); i++) { for (int j = i + 1; j < GraphTN->GetNodes(); j++) { VerifyCmnNbrs(i, j, TSnap::GetCmnNbrs(GraphTN, i, j)); } } // Test TNEGraph which is same as undirected. PNEGraph GraphTNE = TriadGetTestTNEGraph(); for (int i = 0; i < GraphTNE->GetNodes(); i++) { for (int j = i + 1; j < GraphTNE->GetNodes(); j++) { VerifyCmnNbrs(i, j, TSnap::GetCmnNbrs(GraphTNE, i, j)); } } }
void TGStatVec::Add(const PNGraph& Graph, const TSecTm& Time, const TStr& GraphNm) { if (Graph->GetNodes() < (int) TGStatVec::MinNodesEdges) { printf(" ** TGStatVec::Add: graph too small (%d nodes).SKIP\n", Graph->GetNodes()); return; } Add(TGStat::New(Graph, Time, StatFSet, GraphNm)); }
// Test GetLen2Paths: Number of path lengths 2 between pair of nodes TEST(triad, TestGetLen2Paths) { // Test TUNGraph PUNGraph GraphTUN = TriadGetTestTUNGraph(); for (int i = 0; i < GraphTUN->GetNodes(); i++) { for (int j = i + 1; j < GraphTUN->GetNodes(); j++) { VerifyLen2Paths(i, j, TSnap::GetLen2Paths(GraphTUN, i, j), 0); } } // Test TNGraph which is different from undirected due to out neighbors. PNGraph GraphTN = TriadGetTestTNGraph(); for (int i = 0; i < GraphTN->GetNodes(); i++) { for (int j = i + 1; j < GraphTN->GetNodes(); j++) { VerifyLen2Paths(i, j, TSnap::GetLen2Paths(GraphTN, i, j), 1); } } // Test TNEGraph which is different from undirected due to out neighbors. PNEGraph GraphTNE = TriadGetTestTNEGraph(); for (int i = 0; i < GraphTNE->GetNodes(); i++) { for (int j = i + 1; j < GraphTNE->GetNodes(); j++) { VerifyLen2Paths(i, j, TSnap::GetLen2Paths(GraphTNE, i, j), 2); } } }
// Test edge subgraph conversion TEST(subgraph, TestConvertESubGraphs) { PNEGraph NEGraph; PNGraph NGraph; TIntV NIdV; TIntV EIdV; int i; NGraph = GetTestTNGraph(); EXPECT_EQ(20,NGraph->GetNodes()); EXPECT_EQ(60,NGraph->GetEdges()); for (i = 0; i < 20; i += 2) { NIdV.Add(i); } // TODO: fix TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true), it fails // UNGraph = TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true); NEGraph = TSnap::ConvertGraph<PNEGraph>(NGraph); EXPECT_EQ(20,NEGraph->GetNodes()); EXPECT_EQ(60,NEGraph->GetEdges()); // select every second edge i = 0; for (TNEGraph::TEdgeI EI = NEGraph->BegEI(); EI < NEGraph->EndEI(); EI++) { if (i == 0) { EIdV.Add(EI.GetId()); } i = (i + 1) % 2; } NGraph = TSnap::ConvertESubGraph<PNGraph>(NEGraph, EIdV); EXPECT_EQ(20,NGraph->GetNodes()); EXPECT_EQ(30,NGraph->GetEdges()); }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Motifs. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "../as20graph.txt", "Input directed graph file (single directed edge per line)"); const int MotifSz = Env.GetIfArgPrefixInt("-m:", 3, "Motif size (has to be 3 or 4)"); const bool DrawMotifs = Env.GetIfArgPrefixBool("-d:", true, "Draw motif shapes (requires GraphViz)"); TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "", "Output file prefix"); if (OutFNm.Empty()) { OutFNm = InFNm.GetFMid(); } EAssert(MotifSz==3 || MotifSz==4); // load graph PNGraph G; if (InFNm.GetFExt().GetLc()==".ungraph") { TFIn FIn(InFNm); G=TSnap::ConvertGraph<PNGraph>(TUNGraph::Load(FIn), true); } else if (InFNm.GetFExt().GetLc()==".ngraph") { TFIn FIn(InFNm); G=TNGraph::Load(FIn); } else { G = TSnap::LoadEdgeList<PNGraph>(InFNm, 0, 1); } bool IsOk = true; for (int nid = 0; nid < G->GetNodes(); nid++) { if (! G->IsNode(nid)) { IsOk=false; break; } } if (! IsOk) { printf("Nodes of the input graph have to be numbered 0...N-1\nRenumbering nodes...\n"); PNGraph OG = G; G = TNGraph::New(); TGraphEnumUtils::GetNormalizedGraph(OG, G); } // G = TSnap::GenRndGnm<PNGraph>(100, Kilo(1)); // count frequency of connected subgraphs in G that have MotifSz nodes TD34GraphCounter GraphCounter(MotifSz); TSubGraphEnum<TD34GraphCounter> GraphEnum; GraphEnum.GetSubGraphs(G, MotifSz, GraphCounter); FILE *F = fopen(TStr::Fmt("%s-counts.tab", OutFNm.CStr()).CStr(), "wt"); fprintf(F, "MotifId\tNodes\tEdges\tCount\n"); for (int i = 0; i < GraphCounter.Len(); i++) { const int gid = GraphCounter.GetId(i); PNGraph SG = GraphCounter.GetGraph(gid); if (DrawMotifs) { TGraphViz::Plot(SG, gvlNeato, TStr::Fmt("%s-motif%03d.gif", OutFNm.CStr(), i), TStr::Fmt("GId:%d Count: %llu", gid, GraphCounter.GetCnt(gid))); } fprintf(F, "%d\t%d\t%d\t%llu\n", gid, SG->GetNodes(), SG->GetEdges(), GraphCounter.GetCnt(gid)); } printf("done."); 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("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; }
void PlotSngVec(const PNGraph& Graph, const TStr& FNmPref, TStr DescStr) { TFltV LeftSV, RightSV; TSnap::GetSngVec(Graph, LeftSV, RightSV); LeftSV.Sort(false); RightSV.Sort(false); TFltV BinV; if (DescStr.Empty()) { DescStr = FNmPref; } TGUtil::MakeExpBins(LeftSV, BinV, 1.01); TGnuPlot::PlotValV(BinV, "sngVecL."+FNmPref, TStr::Fmt("%s. G(%d, %d). Left signular vector", DescStr.CStr(), Graph->GetNodes(), Graph->GetEdges()), "Rank", "Component of left singular vector", gpsLog10XY, false, gpwLinesPoints); TGnuPlot::PlotValV(BinV, "sngVecL."+FNmPref, TStr::Fmt("%s. G(%d, %d). Right signular vector", DescStr.CStr(), Graph->GetNodes(), Graph->GetEdges()), "Rank", "Component of right singular vector", gpsLog10XY, false, gpwLinesPoints); }
void GetGraphs(const vector <TStr>& Parameters, const TStr& ModelGen, const TStr&ModelPlt) { PNGraph G; size_t PSize = Parameters.size(); if (GRAPHGEN >= PSize || MTXGEN >= PSize || KRONGEN >= PSize || KRONFIT >= PSize) Error("GetGraphs", "Wrong index in array of parameters"); GetModel(Parameters[GRAPHGEN], G); if (G->GetNodes() == 0) Error("GetGraphs", "Empty graph"); TFltPrV MDegIn, MDegOut; TSnap::GetInDegCnt(G, MDegIn); TSnap::GetOutDegCnt(G, MDegOut); PlotDegrees(Parameters, MDegIn, MDegOut, "model"); TFile << "Model nodes: " << G->GetNodes() << ", model edges: " << G->GetEdges() << endl; TFile << "Maximum output degree in model graph: " << MDegOut[MDegOut.Len()-1].GetVal1() << endl; TFile << "Maximum input degree in model graph: " << MDegIn[MDegIn.Len()-1].GetVal1() << endl; if (ModelGen == "model+kron"){ // generate (or read) Kronecker initiator matrix TKronMtx FitMtxM; if (!GetMtx(Parameters[MTXGEN], FitMtxM)) GenNewMtx(G, Parameters[KRONFIT], FitMtxM); PrintMtx(FitMtxM, TFile); TFile << "Scaling for the number of edges... " << endl; FitMtxM.SetForEdges(G->GetNodes(), G->GetEdges()); int ModelNodes = G->GetNodes(), ModelEdges = G->GetEdges(); Env = TEnv(Parameters[KRONGEN], TNotify::NullNotify); TStr IsDir = Env.GetIfArgPrefixStr("-isdir:", "false", "Produce directed graph (true, false)"); const TInt NIter = Env.GetIfArgPrefixInt("-i:", 1, "Number of iterations of Kronecker product"); if (pow(FitMtxM.GetDim(), static_cast<double>(NIter)) != ModelNodes) Error("GetGraphs", "Inconsistent value of -i: parameter, KronNodes != ModelNodes"); // in and out average degrees of Kronecker graphs TFltPrV KronDegAvgIn, KronDegAvgOut; GenKron(Parameters[KRONGEN], FitMtxM, KronDegAvgIn, KronDegAvgOut); PlotDegrees(Parameters, KronDegAvgIn, KronDegAvgOut, "kron"); } }
double DirectedModularity(PNGraph& graph, std::vector<int>& communities) { if (graph->GetNodes() != communities.size()) { throw std::logic_error("Number of nodes does not match community size."); } int num_edges = graph->GetEdges(); double score = 0.0; int num_unique = 10; std::map<int, double> outdeg_sums; std::map<int, double> indeg_sums; for (TNGraph::TNodeI node = graph->BegNI(); node < graph->EndNI(); node++) { int comm = communities[node.GetId()]; outdeg_sums[comm] += node.GetOutDeg(); indeg_sums[comm] += node.GetInDeg(); } for (auto& kv : outdeg_sums) { score -= (kv.second / num_edges) * indeg_sums[kv.first]; } for (TNGraph::TNodeI node = graph->BegNI(); node < graph->EndNI(); node++) { int node_ID = node.GetId(); for (int e = 0; e < node.GetOutDeg(); ++e) { int nbr = node.GetOutNId(e); if (communities[node_ID] == communities[nbr]) { score += 1.0; } } } return score / num_edges; }
void analyzeSimNetProps(TStr messGraph, TStr netGraph) { // Make graphs PNGraph eGraph = TSnap::LoadEdgeListStr<PNGraph>(netGraph, 0, 1); PNGraph mGraph = TSnap::LoadEdgeListStr<PNGraph>(messGraph, 0, 1); PNGraph randGraph = TSnap::GenRndGnm<PNGraph>(mGraph->GetNodes(), mGraph->GetEdges(), true, TInt::Rnd); // Induce network graph from the entire network based on message graph TIntV NIdV; for (TNGraph::TNodeI NI = mGraph->BegNI(); NI < mGraph->EndNI(); NI++) NIdV.AddUnique(NI.GetId()); PNGraph indGraph = TSnap::GetSubGraph<PNGraph>(eGraph, NIdV); //printf("%s:: ", messGraph.CStr()); printf("nodes %d; ", indGraph->GetNodes()); //printf("induced edges %d, random edges %d\n", indGraph->GetEdges(), randGraph->GetEdges()); printf("%d\t%d\t%d\n", indGraph->GetNodes(), indGraph->GetEdges(), mGraph->GetEdges()); }
bool CheckReciprocity(const PNGraph& G){ for (int i = 0; i < G->GetNodes(); i++){ if (G->GetNI(i).GetInDeg() != G->GetNI(i).GetOutDeg()) return false; } return true; }
void TGStat::TakeSpectral(const PNGraph& Graph, TFSet StatFSet, int _TakeSngVals) { if (_TakeSngVals == -1) { _TakeSngVals = TakeSngVals; } // singular values, vectors if (StatFSet.In(gsdSngVal)) { const int SngVals = TMath::Mn(_TakeSngVals, Graph->GetNodes()/2); TFltV SngValV1; TSnap::GetSngVals(Graph, SngVals, SngValV1); SngValV1.Sort(false); TFltPrV& SngValV = DistrStatH.AddDat(gsdSngVal); SngValV.Gen(SngValV1.Len(), 0); for (int i = 0; i < SngValV1.Len(); i++) { SngValV.Add(TFltPr(i+1, SngValV1[i])); } } if (StatFSet.In(gsdSngVec)) { TFltV LeftV, RightV; TSnap::GetSngVec(Graph, LeftV, RightV); LeftV.Sort(false); TFltPrV& SngVec = DistrStatH.AddDat(gsdSngVec); SngVec.Gen(LeftV.Len(), 0); for (int i = 0; i < TMath::Mn(Kilo(10), LeftV.Len()/2); i++) { if (LeftV[i] > 0) { SngVec.Add(TFltPr(i+1, LeftV[i])); } } } }
void TGStat::TakeStat(const PNGraph& Graph, const TSecTm& _Time, TFSet StatFSet, const TStr& GraphName) { printf("\n===TakeStat: G(%u, %u)\n", Graph->GetNodes(), Graph->GetEdges()); TExeTm ExeTm, FullTm; Time = _Time; GraphNm = GraphName; if (StatFSet.In(gsvNone)) { return; } TakeBasicStat(Graph, false); TakeDiam(Graph, StatFSet, false); if (StatFSet.In(gsdWcc) || StatFSet.In(gsdWccHops) || StatFSet.In(gsvFullDiam) || StatFSet.In(gsvEffWccDiam)) { PNGraph WccGraph = TSnap::GetMxWcc(Graph); TakeBasicStat(WccGraph, true); TakeDiam(WccGraph, StatFSet, true); } // degrees TakeDegDistr(Graph, StatFSet); // components TakeConnComp(Graph, StatFSet); // spectral TakeSpectral(Graph, StatFSet, -1); // clustering coeffient if (StatFSet.In(gsdClustCf) || StatFSet.In(gsvClustCf)) { TakeClustCf(Graph); } if (StatFSet.In(gsdTriadPart)) { TakeTriadPart(Graph); } printf(" [%s]\n", FullTm.GetTmStr()); }
// Test graph conversion TEST(subgraph, TestConvertGraphs) { PNGraph NGraph; PUNGraph UNGraph; NGraph = GetTestTNGraph(); EXPECT_EQ(20,NGraph->GetNodes()); EXPECT_EQ(60,NGraph->GetEdges()); UNGraph = TSnap::ConvertGraph<PUNGraph>(NGraph); EXPECT_EQ(20,UNGraph->GetNodes()); EXPECT_EQ(60,UNGraph->GetEdges()); NGraph = TSnap::ConvertGraph<PNGraph>(UNGraph); EXPECT_EQ(20,NGraph->GetNodes()); EXPECT_EQ(120,NGraph->GetEdges()); }
void analyzeSimNetProps() { const char *eFName = "epidemicRoutingNetEdges.txt"; const char *pFName = "prophetRoutingNetEdges.txt"; PNGraph eGraph = TSnap::LoadEdgeListStr<PNGraph>(eFName, 0, 1); PNEGraph pGraph = TSnap::LoadEdgeListStr<PNEGraph>(pFName, 0, 1); PNGraph randGraph = TSnap::GenRndGnm<PNGraph>(eGraph->GetNodes(), eGraph->GetEdges(), true, TInt::Rnd); chdir("dot"); for (int i=0; i<10; i++) { TIntV NIdV; for (int j = 0; j < 10; j++) { int randNode = eGraph->GetRndNId(); NIdV.AddUnique(randNode); } // Plot the mesage propagtion in Endroy-Renyi graphs PNGraph randFlow = TSnap::GetSubGraph<PNGraph>(randGraph, NIdV); char randf[50]; sprintf(randf,"%d-erdos.dot",i); TSnap::SaveGViz(randFlow, randf, TStr("Edros-Renyi random graph")); // Now plot epidemic routing PNGraph epidemicFlow = TSnap::GetSubGraph<PNGraph>(eGraph, NIdV); char epf[50]; sprintf(epf,"%d-epidemic.dot",i); TSnap::SaveGViz(epidemicFlow, epf, TStr("Epidemic routing")); } }
// Test GetNodeTriads (Open and Closed) TEST(triad, TestGetNodeCOTriads) { // Test TUNGraph PUNGraph GraphTUN = TriadGetTestTUNGraph(); for (int i = 0; i < GraphTUN->GetNodes(); i++) { int ClosedTr = -1, OpenTr = -1; TSnap::GetNodeTriads(GraphTUN, i, ClosedTr, OpenTr); VerifyClosedTriads(i, ClosedTr); VerifyOpenTriads(i, OpenTr); } // Test TNGraph which is treated same as undirected. PNGraph GraphTN = TriadGetTestTNGraph(); for (int i = 0; i < GraphTN->GetNodes(); i++) { int ClosedTr = -1, OpenTr = -1; TSnap::GetNodeTriads(GraphTN, i, ClosedTr, OpenTr); VerifyClosedTriads(i, ClosedTr); VerifyOpenTriads(i, OpenTr); } // Test TNEGraph which is treated same as undirected. PNEGraph GraphTNE = TriadGetTestTNEGraph(); for (int i = 0; i < GraphTNE->GetNodes(); i++) { int ClosedTr = -1, OpenTr = -1; TSnap::GetNodeTriads(GraphTNE, i, ClosedTr, OpenTr); VerifyClosedTriads(i, ClosedTr); VerifyOpenTriads(i, OpenTr); } }
void GetSngVec(const PNGraph& Graph, TFltV& LeftSV, TFltV& RightSV) { const int Nodes = Graph->GetNodes(); TFltVV LSingV, RSingV; TFltV SngValV; if (Nodes < 500) { // perform full SVD TFltVV AdjMtx(Nodes+1, Nodes+1); TIntH NodeIdH; // create adjecency matrix for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { NodeIdH.AddKey(NodeI.GetId()); } for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { const int NodeId = NodeIdH.GetKeyId(NodeI.GetId()) + 1; for (int e = 0; e < NodeI.GetOutDeg(); e++) { const int DstNId = NodeIdH.GetKeyId(NodeI.GetOutNId(e)) + 1; // no self edges if (NodeId != DstNId) AdjMtx.At(NodeId, DstNId) = 1; } } try { // can fail to converge but results seem to be good TSvd::Svd1Based(AdjMtx, LSingV, SngValV, RSingV); } catch(...) { printf("\n***No SVD convergence: G(%d, %d)\n", Nodes, Graph->GetEdges()); } } else { // Lanczos TNGraphMtx GraphMtx(Graph); TSparseSVD::LanczosSVD(GraphMtx, 1, 8, ssotFull, SngValV, LSingV, RSingV); } TFlt MxSngVal = TFlt::Mn; int ValN = 0; for (int i = 0; i < SngValV.Len(); i++) { if (MxSngVal < SngValV[i]) { MxSngVal = SngValV[i]; ValN = i; } } LSingV.GetCol(ValN, LeftSV); RSingV.GetCol(ValN, RightSV); IsAllValVNeg(LeftSV, true); IsAllValVNeg(RightSV, true); }
// Test GetNodeClustCf (Vector) TEST(triad, TestGetNodeClustCfVector) { // Test TUNGraph PUNGraph GraphTUN = TriadGetTestTUNGraph(); TIntFltH NIdCCfH; TSnap::GetNodeClustCf(GraphTUN, NIdCCfH); for (int i = 0; i < GraphTUN->GetNodes(); i++) { double ClustCf = NIdCCfH.GetDat(i); VerifyNodeClustCf(i, ClustCf); } // TNGraph should be treated as TUNGraph for calculations PNGraph GraphTN = TriadGetTestTNGraph(); NIdCCfH.Clr(); TSnap::GetNodeClustCf(GraphTN, NIdCCfH); for (int i = 0; i < GraphTN->GetNodes(); i++) { double ClustCf = NIdCCfH.GetDat(i); VerifyNodeClustCf(i, ClustCf); } // TNEGraph should be treated as TUNGraph for calculations PNEGraph GraphTNE = TriadGetTestTNEGraph(); NIdCCfH.Clr(); TSnap::GetNodeClustCf(GraphTNE, NIdCCfH); for (int i = 0; i < GraphTNE->GetNodes(); i++) { double ClustCf = NIdCCfH.GetDat(i); VerifyNodeClustCf(i, ClustCf); } }
// Test GetNodeClustCf (Specific Node) TEST(triad, TestGetNodeClustCfSpecific) { // Test TUNGraph PUNGraph GraphTUN = TriadGetTestTUNGraph(); for (int i = 0; i < GraphTUN->GetNodes(); i++) { double ClustCf = TSnap::GetNodeClustCf(GraphTUN, i); VerifyNodeClustCf(i, ClustCf); } // TNGraph should be treated as TUNGraph for calculations PNGraph GraphTN = TriadGetTestTNGraph(); for (int i = 0; i < GraphTN->GetNodes(); i++) { double ClustCf = TSnap::GetNodeClustCf(GraphTN, i); VerifyNodeClustCf(i, ClustCf); } // TNEGraph should be treated as TUNGraph for calculations PNEGraph GraphTNE = TriadGetTestTNEGraph(); for (int i = 0; i < GraphTNE->GetNodes(); i++) { double ClustCf = TSnap::GetNodeClustCf(GraphTNE, i); VerifyNodeClustCf(i, ClustCf); } }
void PlotSngValRank(const PNGraph& Graph, const int& SngVals, const TStr& FNmPref, TStr DescStr) { TFltV SngValV; TSnap::GetSngVals(Graph, SngVals, SngValV); SngValV.Sort(false); if (DescStr.Empty()) { DescStr = FNmPref; } TGnuPlot::PlotValV(SngValV, "sngVal."+FNmPref, TStr::Fmt("%s. G(%d, %d). Largest eig val = %f", DescStr.CStr(), Graph->GetNodes(), Graph->GetEdges(), SngValV[0].Val), "Rank", "Singular value", gpsLog10XY, false, gpwLinesPoints); }
void SaveAndPlot(const PNGraph& G, const TStr& name, bool isCum){ TFltPrV in, out; TSnap::GetInDegCnt(G, in); TSnap::GetOutDegCnt(G, out); int nodes = G->GetNodes(), edges = G->GetEdges(); TSnap::PlotDegDistr(in, nodes, edges, name, name, isCum, false, true); TSnap::PlotDegDistr(out, nodes, edges, name, name, isCum, false, false); }
void TGraphKey::TakeGraph(const PNGraph& Graph, TIntPrV& NodeMap) { TIntSet NodeIdH; int n = 0; NodeMap.Gen(Graph->GetNodes(), 0); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, n++) { NodeIdH.AddKey(NI.GetId()); NodeMap.Add(TIntPr(NI.GetId(), n)); } Nodes = Graph->GetNodes(); EdgeV.Gen(Nodes, 0); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { const int NewNId = NodeIdH.GetKeyId(NI.GetId()); for (int i = 0; i < NI.GetOutDeg(); i++) { EdgeV.Add(TIntPr(NewNId, NodeIdH.GetKeyId(NI.GetOutNId(i)))); } } EdgeV.Sort(true); EdgeV.Pack(); }
void PrintGraphStat(const PNGraph& G) { PNGraph WCC = TSnap::GetMxWcc(G); PNGraph SCC = TSnap::GetMxScc(G); TFltPrV DegCCfV; int ClosedTriads, OpenTriads, FullDiam; double EffDiam; printf("Nodes\t%d\n", G->GetNodes()); printf("Edges\t%d\n", G->GetEdges()); printf("Nodes in largest WCC\t%d (%.3f)\n", WCC->GetNodes(), WCC->GetNodes()/double(G->GetNodes())); printf("Edges in largest WCC\t%d (%.3f)\n", WCC->GetEdges(), WCC->GetEdges()/double(G->GetEdges())); printf("Nodes in largest SCC\t%d (%.3f)\n", SCC->GetNodes(), SCC->GetNodes()/double(G->GetNodes())); printf("Edges in largest SCC\t%d (%.3f)\n", SCC->GetEdges(), SCC->GetEdges()/double(G->GetEdges())); const double CCF = TSnap::GetClustCf(G, DegCCfV, ClosedTriads, OpenTriads); printf("Average clustering coefficient\t%.4f\n", CCF); printf("Number of triangles\t%d\n", ClosedTriads); printf("Fraction of closed triangles\t%.4g\n", ClosedTriads/double(ClosedTriads+OpenTriads)); TSnap::GetBfsEffDiam(G, 1000, false, EffDiam, FullDiam); printf("Diameter (longest shortest path)\t%d\n", FullDiam); printf("90-percentile effective diameter\t%.2g\n", EffDiam); }
// Test the default constructor TEST(TNGraph, DefaultConstructor) { PNGraph Graph; Graph = TNGraph::New(); EXPECT_EQ(0,Graph->GetNodes()); EXPECT_EQ(0,Graph->GetEdges()); EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(1,Graph->Empty()); EXPECT_EQ(1,Graph->HasFlag(gfDirected)); }
// Test small graph TEST(TNGraph, GetSmallGraph) { PNGraph Graph; Graph = TNGraph::GetSmallGraph(); EXPECT_EQ(5,Graph->GetNodes()); EXPECT_EQ(6,Graph->GetEdges()); EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(0,Graph->Empty()); EXPECT_EQ(1,Graph->HasFlag(gfDirected)); }
uint64 TGraphEnumUtils::GraphId(const PNGraph &G) { int nodes = G->GetNodes(); uint64 id=0; for(TNGraph::TEdgeI it=G->BegEI(); it<G->EndEI(); it++) { int srcId = it.GetSrcNId(); int dstId = it.GetDstNId(); // id += TMath::Pow2(srcId*nodes + dstId); } // return id; }
// Test edge subgraph conversion void TestConvertESubGraphs() { PNEGraph NEGraph; PNGraph NGraph; int N1, N2, N3; int E1, E2, E3; TIntV NIdV; TIntV EIdV; int i; NGraph = GetTestTNGraph(); N1 = NGraph->GetNodes(); E1 = NGraph->GetEdges(); for (i = 0; i < 20; i += 2) { NIdV.Add(i); } // TODO: fix TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true), it fails // UNGraph = TSnap::ConvertSubGraph<PUNGraph>(NGraph, NIdV, true); NEGraph = TSnap::ConvertGraph<PNEGraph>(NGraph); N2 = NEGraph->GetNodes(); E2 = NEGraph->GetEdges(); // select every second edge i = 0; for (TNEGraph::TEdgeI EI = NEGraph->BegEI(); EI < NEGraph->EndEI(); EI++) { if (i == 0) { EIdV.Add(EI.GetId()); } i = (i + 1) % 2; } NGraph = TSnap::ConvertESubGraph<PNGraph>(NEGraph, EIdV); N3 = NGraph->GetNodes(); E3 = NGraph->GetEdges(); printf("---- TestConvertESubGraphs -----\n"); printf("nodes: %d,%d,%d, edges: %d,%d,%d\n", N1, N2, N3, E1, E2, E3); printf("\n"); }
// Test graph conversion void TestConvertGraphs() { PNGraph NGraph; PUNGraph UNGraph; int N1, N2, N3; int E1, E2, E3; NGraph = GetTestTNGraph(); N1 = NGraph->GetNodes(); E1 = NGraph->GetEdges(); UNGraph = TSnap::ConvertGraph<PUNGraph>(NGraph); N2 = UNGraph->GetNodes(); E2 = UNGraph->GetEdges(); NGraph = TSnap::ConvertGraph<PNGraph>(UNGraph); N3 = NGraph->GetNodes(); E3 = NGraph->GetEdges(); printf("---- TestConvertGraphs -----\n"); printf("nodes: %d,%d,%d, edges: %d,%d,%d\n", N1, N2, N3, E1, E2, E3); printf("\n"); }
void TGraphKey::TakeSig(const PNGraph& Graph, const int& MnSvdGraph, const int& MxSvdGraph) { const int Edges = Graph->GetEdges(); Nodes = Graph->GetNodes(); VariantId = 0; SigV.Gen(2+Nodes, 0); // degree sequence TIntPrV DegV(Nodes, 0); for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { DegV.Add(TIntPr(NodeI.GetInDeg(), NodeI.GetOutDeg())); } DegV.Sort(false); SigV.Add(TFlt(Nodes)); SigV.Add(TFlt(Edges)); for (int i = 0; i < DegV.Len(); i++) { SigV.Add(DegV[i].Val1()); SigV.Add(DegV[i].Val2()); } // singular values signature // it turns out that it is cheaper to do brute force isomorphism // checking than to calculate SVD and then check isomorphism if (Nodes >= MnSvdGraph && Nodes < MxSvdGraph) { // perform full SVD TFltVV AdjMtx(Nodes+1, Nodes+1); TFltV SngValV; TFltVV LSingV, RSingV; TIntH NodeIdH; // create adjecency matrix for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { NodeIdH.AddKey(NodeI.GetId()); } for (TNGraph::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) { const int NodeId = NodeIdH.GetKeyId(NodeI.GetId()) + 1; for (int e = 0; e < NodeI.GetOutDeg(); e++) { const int DstNId = NodeIdH.GetKeyId(NodeI.GetOutNId(e)) + 1; // no self edges if (NodeId != DstNId) AdjMtx.At(NodeId, DstNId) = 1; } } try { // can fail to converge but results seem to be good TSvd::Svd(AdjMtx, LSingV, SngValV, RSingV); } catch(...) { printf("\n***No SVD convergence: G(%d, %d): SngValV.Len():%d\n", Nodes(), Graph->GetEdges(), SngValV.Len()); } // round singular values SngValV.Sort(false); for (int i = 0; i < SngValV.Len(); i++) { SigV.Add(TMath::Round(SngValV[i], RoundTo)); } } //printf("SIG:\n"); for (int i = 0; i < SigV.Len(); i++) { printf("\t%f\n", SigV[i]); } SigV.Pack(); }