int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Trust Rank. Build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); TExeTm ExeTm; Try const TStr Gnod = Env.GetIfArgPrefixStr("-g:", "Gnode.txt", "Good Nodes"); const TStr Bnod = Env.GetIfArgPrefixStr("-b:", "Bnode.txt", "Bad Nodes" ); const TStr Iput = Env.GetIfArgPrefixStr("-i:", "Input.txt", "Input File"); const TStr Oput = Env.GetIfArgPrefixStr("-o:", "Output.txt", "Output File"); const double C = 0.85; const int MaxIter = 50; const double Eps = 1e-9; FILE* fpO = fopen(Oput.CStr(), "w"); PNGraph Graph = TSnap::LoadEdgeList< PNGraph > (Iput); fprintf(fpO, "\nNodes: %d, Edges: %d\n\n", Graph->GetNodes(), Graph->GetEdges()); const int NNodes = Graph->GetNodes(); TIntFltH TRankH; TRankH.Gen(NNodes); int maxNId = 0, NId = 0, ret = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) maxNId = max(maxNId, NI.GetId()); TFltV initialTrustScore(maxNId + 1); for (int i = 0; i < initialTrustScore.Len(); i++) initialTrustScore[i] = 0.5; FILE* fpI = fopen(Gnod.CStr(), "r"); while (true) { ret = fscanf(fpI, "%d", &NId); if (ret == EOF) break; if (Graph->IsNode(NId)) initialTrustScore[NId] = 1.0; } fclose(fpI); fpI = fopen(Bnod.CStr(), "r"); while (true) { ret = fscanf(fpI, "%d", &NId); if (ret == EOF) break; if (Graph->IsNode(NId)) initialTrustScore[NId] = 0.0; } fclose(fpI); double Tot = 0.0; for(int i = 0; i < initialTrustScore.Len(); i++) Tot += initialTrustScore[i]; for(int i = 0; i < initialTrustScore.Len(); i++) initialTrustScore[i] /= Tot; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) TRankH.AddDat( NI.GetId(), initialTrustScore[NI.GetId()] ); TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { int j = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++, j++) { TmpV[j] = 0; for (int e = 0; e < NI.GetOutDeg(); e++) { const int OutNId = NI.GetOutNId(e); const int InDeg = Graph->GetNI(InNId).GetInDeg(); if (InDeg > 0) TmpV[j] += (double) TRankH.GetDat(OutNId) / (double) InDeg; } TmpV[j] = C * TmpV[j] + (1.0 - C) * initialTrustScore[NI.GetId()]; } for (int i = 0; i < TRankH.Len(); i++) TRankH[i] = TmpV[i]; } fprintf(fpO, "Node ID\t\tTrustRank\n"); for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++){ int Id = NI.GetId(); double tr = TRankH.GetDat(Id); fprintf(fpO, "%d\t\t\t%.5lf\n", Id, tr); } fclose(fpO); Catch printf("\nRun Time: %s (%s)\n", ExeTm.GetTmStr(), TSecTm::GetCurTm().GetTmStr().CStr()); return 0; }
// Test node, edge creation TEST(TNGraph, ManipulateNodesEdges) { int NNodes = 10000; int NEdges = 100000; const char *FName = "test.graph.dat"; PNGraph Graph; PNGraph Graph1; PNGraph Graph2; int i; int n; int NCount; int x,y; int Deg, InDeg, OutDeg; Graph = TNGraph::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 (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } EXPECT_EQ(NNodes,NCount); // edges per node iterator NCount = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { NCount++; } } EXPECT_EQ(NEdges,NCount); // edges iterator NCount = 0; for (TNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { NCount++; } EXPECT_EQ(NEdges,NCount); // node degree for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Deg = NI.GetDeg(); InDeg = NI.GetInDeg(); OutDeg = NI.GetOutDeg(); EXPECT_EQ(Deg,InDeg+OutDeg); } // assignment Graph1 = TNGraph::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 = TNGraph::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()); }
// Node selects N~geometric(1.0-FwdBurnProb)-1 out-links and burns them. Then same for in-links. // geometirc(p) has mean 1/(p), so for given FwdBurnProb, we burn 1/(1-FwdBurnProb) void TForestFire::BurnGeoFire() { const double OldFwdBurnProb=FwdBurnProb; const double OldBckBurnProb=BckBurnProb; const int& NInfect = InfectNIdV.Len(); const TNGraph& G = *Graph; TIntH BurnedNIdH; // burned nodes TIntV BurningNIdV = InfectNIdV; // currently burning nodes TIntV NewBurnedNIdV; // nodes newly burned in current step bool HasAliveInNbrs, HasAliveOutNbrs; // has unburned neighbors TIntV AliveNIdV; // NIds of alive neighbors int NBurned = NInfect, time; for (int i = 0; i < InfectNIdV.Len(); i++) { BurnedNIdH.AddDat(InfectNIdV[i]); } NBurnedTmV.Clr(false); NBurningTmV.Clr(false); NewBurnedTmV.Clr(false); for (time = 0; ; time++) { NewBurnedNIdV.Clr(false); for (int node = 0; node < BurningNIdV.Len(); node++) { const int& BurningNId = BurningNIdV[node]; const TNGraph::TNodeI Node = G.GetNI(BurningNId); // find unburned links HasAliveOutNbrs = false; AliveNIdV.Clr(false); // unburned links for (int e = 0; e < Node.GetOutDeg(); e++) { const int OutNId = Node.GetOutNId(e); if (! BurnedNIdH.IsKey(OutNId)) { HasAliveOutNbrs = true; AliveNIdV.Add(OutNId); } } // number of links to burn (geometric coin). Can also burn 0 links const int BurnNFwdLinks = Rnd.GetGeoDev(1.0-FwdBurnProb) - 1; if (HasAliveOutNbrs && BurnNFwdLinks > 0) { AliveNIdV.Shuffle(Rnd); for (int i = 0; i < TMath::Mn(BurnNFwdLinks, AliveNIdV.Len()); i++) { BurnedNIdH.AddDat(AliveNIdV[i]); NewBurnedNIdV.Add(AliveNIdV[i]); NBurned++; } } // backward links if (BckBurnProb > 0.0) { // find unburned links HasAliveInNbrs = false; AliveNIdV.Clr(false); for (int e = 0; e < Node.GetInDeg(); e++) { const int InNId = Node.GetInNId(e); if (! BurnedNIdH.IsKey(InNId)) { HasAliveInNbrs = true; AliveNIdV.Add(InNId); } } // number of links to burn (geometric coin). Can also burn 0 links const int BurnNBckLinks = Rnd.GetGeoDev(1.0-BckBurnProb) - 1; if (HasAliveInNbrs && BurnNBckLinks > 0) { AliveNIdV.Shuffle(Rnd); for (int i = 0; i < TMath::Mn(BurnNBckLinks, AliveNIdV.Len()); i++) { BurnedNIdH.AddDat(AliveNIdV[i]); NewBurnedNIdV.Add(AliveNIdV[i]); NBurned++; } } } } NBurnedTmV.Add(NBurned); NBurningTmV.Add(BurningNIdV.Len()); NewBurnedTmV.Add(NewBurnedNIdV.Len()); // BurningNIdV.AddV(NewBurnedNIdV); // node is burning eternally BurningNIdV.Swap(NewBurnedNIdV); // node is burning just 1 time step if (BurningNIdV.Empty()) break; FwdBurnProb = FwdBurnProb * ProbDecay; BckBurnProb = BckBurnProb * ProbDecay; } BurnedNIdV.Gen(BurnedNIdH.Len(), 0); for (int i = 0; i < BurnedNIdH.Len(); i++) { BurnedNIdV.Add(BurnedNIdH.GetKey(i)); } FwdBurnProb = OldFwdBurnProb; BckBurnProb = OldBckBurnProb; }
// Test node, edge creation void ManipulateNodesEdges() { int NNodes = 10000; int NEdges = 100000; const char *FName = "demo.graph.dat"; PNGraph Graph; PNGraph Graph1; PNGraph Graph2; int i; int n; int NCount; int ECount1; int ECount2; int x,y; bool t; Graph = TNGraph::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 (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } // get all the edges for all the nodes ECount1 = 0; for (TNGraph::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { for (int e = 0; e < NI.GetOutDeg(); e++) { ECount1++; } } // get all the edges directly ECount2 = 0; for (TNGraph::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { ECount2++; } printf("ManipulateNodesEdges:Graph, nodes %d, edges1 %d, edges2 %d\n", NCount, ECount1, ECount2); // assignment Graph1 = TNGraph::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 = TNGraph::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); }