void checkTNEANetCorrect(PNEANet G, PNEANet G2) { EXPECT_EQ(G->GetNodes(), G2->GetNodes()); EXPECT_EQ(G->GetEdges(), G2->GetEdges()); TStr attr2 = "int"; TStr attr3 = "float"; TStr attr1 = "str"; EXPECT_EQ(G->GetNAIntI(attr2, 3).GetDat(), G2->GetNAIntI(attr2, 3).GetDat()); EXPECT_EQ(G->GetNAIntI(attr2, 50).GetDat(), G2->GetNAIntI(attr2, 50).GetDat()); EXPECT_EQ(G->GetNAFltI(attr3, 5).GetDat(), G2->GetNAFltI(attr3, 5).GetDat()); EXPECT_EQ(G->GetNAFltI(attr3, 50).GetDat(), G2->GetNAFltI(attr3, 50).GetDat()); EXPECT_EQ(G->GetNAStrI(attr1, 10).GetDat().LastCh(), G2->GetNAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ(G->GetNAStrI(attr1, 20).GetDat().LastCh(), G2->GetNAStrI(attr1, 20).GetDat().LastCh()); }
TPRManager(PNEANet &Net) : Net(Net), CapIndex(0), FlowV(Net->GetMxEId()), ExcessV(Net->GetMxNId()), EdgeNumsV(Net->GetMxNId()), LabelsV(Net->GetMxNId()), LabelCounts(Net->GetNodes() + 1), LabelLimit(0), MaxLabel(Net->GetNodes()), ActiveNodeSet(Net->GetMxNId()), ActiveCount(0) { CapIndex = Net->GetIntAttrIndE(CapAttrName); for (int i = 0; i <= Net->GetNodes(); i++) { LabelCounts[i] = 0; } for (TNEANet::TEdgeI EI = Net->BegEI(); EI != Net->EndEI(); EI++) { int EId = EI.GetId(); IAssert(Capacity(EId) >= 0); FlowV[EId] = 0; } for (TNEANet::TNodeI NI = Net->BegNI(); NI != Net->EndNI(); NI++) { int NId = NI.GetId(); ExcessV[NId] = 0; EdgeNumsV[NId] = 0; ActiveNodeSet[NId] = 0; } LabelCounts[0] = Net->GetNodes(); }
int GetWeightedPageRankMP1(const PNEANet Graph, TIntFltH& PRankH, const TStr& Attr, const double& C, const double& Eps, const int& MaxIter) { if (!Graph->IsFltAttrE(Attr)) return -1; TFltV Weights = Graph->GetFltAttrVecE(Attr); int mxid = Graph->GetMxNId(); TFltV OutWeights(mxid); Graph->GetWeightOutEdgesV(OutWeights, Weights); /*for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { OutWeights[NI.GetId()] = Graph->GetWeightOutEdges(NI, Attr); }*/ /*TIntFltH Weights; for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Weights.AddDat(NI.GetId(), Graph->GetWeightOutEdges(NI, Attr)); }*/ const int NNodes = Graph->GetNodes(); TVec<TNEANet::TNodeI> NV; //const double OneOver = 1.0/double(NNodes); PRankH.Gen(NNodes); for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NV.Add(NI); PRankH.AddDat(NI.GetId(), 1.0/NNodes); //IAssert(NI.GetId() == PRankH.GetKey(PRankH.Len()-1)); } TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { #pragma omp parallel for schedule(dynamic,10000) for (int j = 0; j < NNodes; j++) { TNEANet::TNodeI NI = NV[j]; TmpV[j] = 0; for (int e = 0; e < NI.GetInDeg(); e++) { const int InNId = NI.GetInNId(e); const TFlt OutWeight = OutWeights[InNId]; int EId = Graph->GetEId(InNId, NI.GetId()); const TFlt Weight = Weights[Graph->GetFltKeyIdE(EId)]; if (OutWeight > 0) { TmpV[j] += PRankH.GetDat(InNId) * Weight / OutWeight; } } TmpV[j] = C*TmpV[j]; // Berkhin (the correct way of doing it) //TmpV[j] = C*TmpV[j] + (1.0-C)*OneOver; // iGraph } double diff=0, sum=0, NewVal; #pragma omp parallel for reduction(+:sum) schedule(dynamic,10000) for (int i = 0; i < TmpV.Len(); i++) { sum += TmpV[i]; } const double Leaked = (1.0-sum) / double(NNodes); #pragma omp parallel for reduction(+:diff) schedule(dynamic,10000) for (int i = 0; i < PRankH.Len(); i++) { // re-instert leaked PageRank NewVal = TmpV[i] + Leaked; // Berkhin //NewVal = TmpV[i] / sum; // iGraph diff += fabs(NewVal-PRankH[i]); PRankH[i] = NewVal; } if (diff < Eps) { break; } } return 0; }
// Test the default constructor TEST(TNEANet, DefaultConstructor) { PNEANet Graph; Graph = TNEANet::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(TNEANet, GetSmallGraph) { PNEANet Graph; return; // not implemented //Graph = TNEANet::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)); }
int GetMaxFlowIntPR (PNEANet &Net, const int& SrcNId, const int& SnkNId) { IAssert(Net->IsNode(SrcNId)); IAssert(Net->IsNode(SnkNId)); if (SrcNId == SnkNId) { return 0; } TPRManager PRM(Net); int MaxLabel = PRM.GetMaxLabel(); TNEANet::TNodeI SrcNI = Net->GetNI(SrcNId); for (int EdgeN = 0; EdgeN < SrcNI.GetOutDeg(); EdgeN++) { int EId = SrcNI.GetOutEId(EdgeN); int OutNId = SrcNI.GetOutNId(EdgeN); if (OutNId != SrcNId) { int Capacity = PRM.Capacity(EId); PRM.Flow(EId) = Capacity; PRM.Excess(OutNId) = Capacity; } } GlobalRelabel(Net, PRM, SrcNId, SnkNId); PRM.SetLabel(SrcNId, MaxLabel); int RelabelCount = 1; int GRRate = Net->GetNodes(); while (PRM.HasActive()) { int NId = PRM.PopActive(); const TNEANet::TNodeI &NI = Net->GetNI(NId); int PrevLabel = MaxLabel; while (PRM.Excess(NId) > 0 && PRM.Label(NId) <= PrevLabel) { PrevLabel = PRM.Label(NId); int NbrNId = PushRelabel(PRM, NId, NI); if (NbrNId != -1 && NbrNId != SnkNId && PRM.Excess(NbrNId) > 0 && !PRM.IsActive(NbrNId)) { PRM.PushActive(NbrNId); } } if (PRM.Excess(NId) > 0 && PRM.Label(NId) < MaxLabel) { PRM.PushActive(NId); } if (RelabelCount % GRRate == 0) { GlobalRelabel(Net, PRM, SrcNId, SnkNId); } } return PRM.Excess(SnkNId); }
// Print graph statistics void PrintGStats(const char s[], PNEANet Graph) { printf("graph %s, nodes %d, edges %d, empty %s\n", s, Graph->GetNodes(), Graph->GetEdges(), Graph->Empty() ? "yes" : "no"); }
// Test node, edge creation void ManipulateNodesEdges() { int NNodes = 1000; int NEdges = 100000; const char *FName = "demo.graph.dat"; PNEANet Graph; PNEANet Graph1; PNEANet Graph2; int i; int n; int NCount; int ECount1; int ECount2; int x,y; bool t; Graph = TNEANet::New(); t = Graph->Empty(); // create the nodes for (i = 0; i < NNodes; i++) { Graph->AddNode(i); } n = Graph->GetNodes(); t = Graph->Empty(); // create random edges NCount = NEdges; while (NCount > 0) { x = rand() % NNodes; y = rand() % NNodes; n = Graph->AddEdge(x, y); NCount--; } PrintGStats("ManipulateNodesEdges:Graph",Graph); // get all the nodes NCount = 0; for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } // get all the edges for all the nodes ECount1 = 0; for (TNEANet::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 (TNEANet::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 = TNEANet::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 = TNEANet::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); }
int main(int argc, char* argv[]) { Env = TEnv(argc, argv, TNotify::StdNotify); Env.PrepArgs(TStr::Fmt("Flow. build: %s, %s. Time: %s", __TIME__, __DATE__, TExeTm::GetCurTm())); double NetPRTimeSum = 0; double NetEKTimeSum = 0; int NumWins = 0; Try const TStr InFNm = Env.GetIfArgPrefixStr("-i:", "", "Input file"); const int Iters = Env.GetIfArgPrefixInt("-n:", 10, "Number of runs per thread"); const int Threads = Env.GetIfArgPrefixInt("-t:", 4, "Number of threads"); printf("Integer Flow Test\n"); printf("Filename: %s\n", InFNm.CStr()); printf("Building Network...\n"); TFIn InFile(InFNm); // If the input file is a binary, use the following line to load the network PNEANet Net = TNEANet::Load(InFile); // If the input file is a text file, use the following to load the network and save as binary // PNEANet Net; // int MaxEdgeCap = BuildCapacityNetwork(InFNm, Net); // const TStr OutFNm = Env.GetIfArgPrefixStr("-o:", "", "Output file"); // TFOut OutFile(OutFNm); // Net->Save(OutFile); printf("PNEANet Nodes: %d, Edges: %d\n\n", Net->GetNodes(), Net->GetEdges()); #pragma omp parallel for reduction(+:NetEKTimeSum,NetPRTimeSum,NumWins) schedule(static, 1) for (int t = 0; t < Threads; t++) { TRnd Random(t); for (int i = 0; i < Iters; i++) { int SrcNId = Net->GetRndNId(Random); int SnkNId = Net->GetRndNId(Random); double PRBeginTime = getcputime(); int NetMaxFlowPR = TSnap::GetMaxFlowIntPR(Net, SrcNId, SnkNId); double PREndTime = getcputime(); double NetPRFlowRunTime = PREndTime - PRBeginTime; double EKBeginTime = getcputime(); int NetMaxFlowEK = TSnap::GetMaxFlowIntEK(Net, SrcNId, SnkNId); double EKEndTime = getcputime(); double NetEKFlowRunTime = EKEndTime - EKBeginTime; IAssert(NetMaxFlowPR == NetMaxFlowEK); if (NetPRFlowRunTime < NetEKFlowRunTime) { NumWins++; } NetPRTimeSum += NetPRFlowRunTime; NetEKTimeSum += NetEKFlowRunTime; #pragma omp critical { #ifndef NOMP printf("Thread: %d\n", omp_get_thread_num()); #endif printf("Source: %d, Sink %d\n", SrcNId, SnkNId); printf("Max Flow: %d\n", NetMaxFlowEK); printf("PR CPU Time: %f\n", NetPRFlowRunTime); printf("EK CPU Time: %f\n", NetEKFlowRunTime); printf("\n"); } } } int TotalRuns = Iters*Threads; printf ("Avg PR PNEANet Time: %f\n", NetPRTimeSum/TotalRuns); printf ("Avg EK PNEANet Time: %f\n", NetEKTimeSum/TotalRuns); printf ("%d out of %d PR was faster\n", NumWins, TotalRuns); Catch return 0; }
int GetWeightedPageRankMP2(const PNEANet Graph, TIntFltH& PRankH, const TStr& Attr, const double& C, const double& Eps, const int& MaxIter) { if (!Graph->IsFltAttrE(Attr)) return -1; const int NNodes = Graph->GetNodes(); TVec<TNEANet::TNodeI> NV; //const double OneOver = 1.0/double(NNodes); PRankH.Gen(NNodes); int MxId; for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NV.Add(NI); PRankH.AddDat(NI.GetId(), 1.0/NNodes); int Id = NI.GetId(); if (Id > MxId) { MxId = Id; } } TFltV PRankV(MxId+1); TFltV OutWeights(MxId+1); TFltV Weights = Graph->GetFltAttrVecE(Attr); #pragma omp parallel for schedule(dynamic,10000) for (int j = 0; j < NNodes; j++) { TNEANet::TNodeI NI = NV[j]; int Id = NI.GetId(); OutWeights[Id] = Graph->GetWeightOutEdges(NI, Attr); PRankV[Id] = 1/NNodes; } TFltV TmpV(NNodes); for (int iter = 0; iter < MaxIter; iter++) { #pragma omp parallel for schedule(dynamic,10000) for (int j = 0; j < NNodes; j++) { TNEANet::TNodeI NI = NV[j]; TFlt Tmp = 0; for (int e = 0; e < NI.GetInDeg(); e++) { const int InNId = NI.GetInNId(e); const TFlt OutWeight = OutWeights[InNId]; int EId = Graph->GetEId(InNId, NI.GetId()); const TFlt Weight = Weights[Graph->GetFltKeyIdE(EId)]; if (OutWeight > 0) { Tmp += PRankH.GetDat(InNId) * Weight / OutWeight; } } TmpV[j] = C*Tmp; // Berkhin (the correct way of doing it) //TmpV[j] = C*TmpV[j] + (1.0-C)*OneOver; // iGraph } double sum = 0; #pragma omp parallel for reduction(+:sum) schedule(dynamic,10000) for (int i = 0; i < TmpV.Len(); i++) { sum += TmpV[i]; } const double Leaked = (1.0-sum) / double(NNodes); double diff = 0; #pragma omp parallel for reduction(+:diff) schedule(dynamic,10000) for (int i = 0; i < NNodes; i++) { TNEANet::TNodeI NI = NV[i]; double NewVal = TmpV[i] + Leaked; // Berkhin //NewVal = TmpV[i] / sum; // iGraph int Id = NI.GetId(); diff += fabs(NewVal-PRankV[Id]); PRankV[Id] = NewVal; } if (diff < Eps) { break; } } #pragma omp parallel for schedule(dynamic,10000) for (int i = 0; i < NNodes; i++) { TNEANet::TNodeI NI = NV[i]; PRankH[i] = PRankV[NI.GetId()]; } return 0; }
// Test node, edge creation TEST(TNEANet, ManipulateNodesEdges) { int NNodes = 1000; int NEdges = 100000; const char *FName = "test.graph.dat"; PNEANet Graph; PNEANet Graph1; PNEANet Graph2; int i; int n; int NCount; int x,y; int Deg, InDeg, OutDeg; Graph = TNEANet::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); 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 (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { NCount++; } EXPECT_EQ(NNodes,NCount); // edges per node iterator NCount = 0; for (TNEANet::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 (TNEANet::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) { NCount++; } EXPECT_EQ(NEdges,NCount); // node degree for (TNEANet::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) { Deg = NI.GetDeg(); InDeg = NI.GetInDeg(); OutDeg = NI.GetOutDeg(); EXPECT_EQ(Deg,InDeg+OutDeg); } // assignment Graph1 = TNEANet::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 = TNEANet::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()); }
// Test node, edge attribute functionality TEST(TNEANet, ManipulateNodesEdgeAttributes) { int NNodes = 1000; int NEdges = 1000; const char *FName = "demo.graph.dat"; PNEANet Graph; PNEANet Graph1; int i; int x, y; bool t; Graph = TNEANet::New(); t = Graph->Empty(); // create the nodes for (i = NNodes - 1; i >= 0; i--) { Graph->AddNode(i); } EXPECT_EQ(NNodes, Graph->GetNodes()); // create the edges for (i = NEdges - 1; i >= 0; i--) { x = (long) (drand48() * NNodes); y = (long) (drand48() * NNodes); Graph->AddEdge(x, y, i); } // create attributes and fill all nodes TStr attr1 = "str"; TStr attr2 = "int"; TStr attr3 = "float"; TStr attr4 = "default"; // Test vertical int iterator for node 3, 50, 700, 900 // Check if we can set defaults to 0 for Int data. Graph->AddIntAttrN(attr2, 0); Graph->AddIntAttrDatN(3, 3*2, attr2); Graph->AddIntAttrDatN(50, 50*2, attr2); Graph->AddIntAttrDatN(700, 700*2, attr2); Graph->AddIntAttrDatN(900, 900*2, attr2); EXPECT_EQ(3*2, Graph->GetNAIntI(attr2, 3).GetDat()); EXPECT_EQ(50*2, Graph->GetNAIntI(attr2, 50).GetDat()); int NodeId = 0; int DefNodes = 0; TVec<TInt> TAIntIV = TVec<TInt>(); for (TNEANet::TAIntI NI = Graph->BegNAIntI(attr2); NI < Graph->EndNAIntI(attr2); NI++) { if (NI.GetDat()() != 0) { TAIntIV.Add(NI.GetDat()); NodeId++; } else { DefNodes++; } } EXPECT_EQ(4, NodeId); EXPECT_EQ(NNodes - 4, DefNodes); TAIntIV.Sort(); EXPECT_EQ(3*2, TAIntIV[0]); EXPECT_EQ(50*2, TAIntIV[1]); EXPECT_EQ(700*2, TAIntIV[2]); EXPECT_EQ(900*2, TAIntIV[3]); // Test vertical flt iterator for node 3, 50, 700, 900 Graph->AddFltAttrDatN(5, 3.41, attr3); Graph->AddFltAttrDatN(50, 2.718, attr3); Graph->AddFltAttrDatN(300, 150.0, attr3); Graph->AddFltAttrDatN(653, 563, attr3); EXPECT_EQ(3.41, Graph->GetNAFltI(attr3, 5).GetDat()); EXPECT_EQ(2.718, Graph->GetNAFltI(attr3, 50).GetDat()); NodeId = 0; DefNodes = 0; TVec<TFlt> TAFltIV = TVec<TFlt>(); for (TNEANet::TAFltI NI = Graph->BegNAFltI(attr3); NI < Graph->EndNAFltI(attr3); NI++) { if (NI.GetDat() != TFlt::Mn) { NodeId++; TAFltIV.Add(NI.GetDat()); } else { DefNodes++; } } EXPECT_EQ(4, NodeId); EXPECT_EQ(NNodes - 4, DefNodes); TAFltIV.Sort(); EXPECT_EQ(2.718, TAFltIV[0]); EXPECT_EQ(3.41, TAFltIV[1]); EXPECT_EQ(150.0, TAFltIV[2]); EXPECT_EQ(563.0, TAFltIV[3]); // Test vertical str iterator for node 3, 50, 700, 900 Graph->AddStrAttrDatN(10, "abc", attr1); Graph->AddStrAttrDatN(20, "def", attr1); Graph->AddStrAttrDatN(400, "ghi", attr1); // this does not show since ""=null Graph->AddStrAttrDatN(455, "", attr1); EXPECT_EQ('c', Graph->GetNAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ('f', Graph->GetNAStrI(attr1, 20).GetDat().LastCh()); NodeId = 0; DefNodes = 0; TVec<TStr> TAStrIV = TVec<TStr>(); for (TNEANet::TAStrI NI = Graph->BegNAStrI(attr1); NI < Graph->EndNAStrI(attr1); NI++) { if (NI.GetDat() != TStr::GetNullStr()) { NodeId++; TAStrIV.Add(NI.GetDat()); } else { DefNodes++; } } EXPECT_EQ(3, NodeId); EXPECT_EQ(NNodes - 3, DefNodes); TAStrIV.Sort(); // TODO(nkhadke): Fix hack to compare strings properly. This works for now. EXPECT_EQ('c', TAStrIV[0].LastCh()); EXPECT_EQ('f', TAStrIV[1].LastCh()); EXPECT_EQ('i', TAStrIV[2].LastCh()); // Test vertical iterator over many types (must skip default/deleted attr) int NId = 55; Graph->AddStrAttrDatN(NId, "aaa", attr1); Graph->AddIntAttrDatN(NId, 3*2, attr2); Graph->AddFltAttrDatN(NId, 3.41, attr3); Graph->AddStrAttrDatN(80, "dont appear", attr4); // should not show up TStrV NIdAttrName; Graph->AttrNameNI(NId, NIdAttrName); int AttrLen = NIdAttrName.Len(); NodeId = 0; DefNodes = 0; EXPECT_EQ(3, AttrLen); Graph->DelAttrDatN(NId, attr2); Graph->AttrNameNI(NId, NIdAttrName); AttrLen = NIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("int") == NIdAttrName[i]()) { // FAIL EXPECT_EQ(1,2); } } EXPECT_EQ(2, AttrLen); Graph->AddIntAttrDatN(NId, 3*2, attr2); Graph->DelAttrN(attr1); Graph->AttrNameNI(NId, NIdAttrName); AttrLen = NIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == NIdAttrName[i]()) { // FAIL EXPECT_EQ(1,2); } } EXPECT_EQ(2, AttrLen); TStrV NIdAttrValue; Graph->AttrValueNI(NId, NIdAttrValue); AttrLen = NIdAttrValue.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == NIdAttrValue[i]()) { // FAIL EXPECT_EQ(1,2); } } int expectedTotal = 0; for (i = 0; i <NNodes; i++) { Graph->AddIntAttrDatN(i, NNodes+i, attr2); EXPECT_EQ(NNodes+i, Graph->GetIntAttrDatN(i, attr2)); expectedTotal += NNodes+i; } { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); } { TFIn FIn(FName); Graph1 = TNEANet::Load(FIn); } int total = 0; for (TNEANet::TAIntI NI = Graph1->BegNAIntI(attr2); NI < Graph1->EndNAIntI(attr2); NI++) { total += NI.GetDat(); } ASSERT_EQ(expectedTotal, total); Graph1->Clr(); // Test vertical int iterator for edge Graph->AddIntAttrDatE(3, 3*2, attr2); Graph->AddIntAttrDatE(55, 55*2, attr2); Graph->AddIntAttrDatE(705, 705*2, attr2); Graph->AddIntAttrDatE(905, 905*2, attr2); EXPECT_EQ(3*2, Graph->GetEAIntI(attr2, 3).GetDat()); EXPECT_EQ(55*2, Graph->GetEAIntI(attr2, 55).GetDat()); int EdgeId = 0; int DefEdges = 0; TAIntIV.Clr(); for (TNEANet::TAIntI EI = Graph->BegEAIntI(attr2); EI < Graph->EndEAIntI(attr2); EI++) { if (EI.GetDat() != TInt::Mn) { TAIntIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAIntIV.Sort(); EXPECT_EQ(3*2, TAIntIV[0]); EXPECT_EQ(55*2, TAIntIV[1]); EXPECT_EQ(705*2, TAIntIV[2]); EXPECT_EQ(905*2, TAIntIV[3]); // Test vertical flt iterator for edge Graph->AddFltAttrE(attr3, 0.00); Graph->AddFltAttrDatE(5, 4.41, attr3); Graph->AddFltAttrDatE(50, 3.718, attr3); Graph->AddFltAttrDatE(300, 151.0, attr3); Graph->AddFltAttrDatE(653, 654, attr3); EXPECT_EQ(4.41, Graph->GetEAFltI(attr3, 5).GetDat()); EXPECT_EQ(3.718, Graph->GetEAFltI(attr3, 50).GetDat()); EdgeId = 0; DefEdges = 0; TAFltIV.Clr(); for (TNEANet::TAFltI EI = Graph->BegEAFltI(attr3); EI < Graph->EndEAFltI(attr3); EI++) { // Check if defaults are set to 0. if (EI.GetDat() != 0.00) { TAFltIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(4, EdgeId); EXPECT_EQ(NEdges - 4, DefEdges); TAFltIV.Sort(); EXPECT_EQ(3.718, TAFltIV[0]); EXPECT_EQ(4.41, TAFltIV[1]); EXPECT_EQ(151.0, TAFltIV[2]); EXPECT_EQ(654.0, TAFltIV[3]); // Test vertical str iterator for edge Graph->AddStrAttrDatE(10, "abc", attr1); Graph->AddStrAttrDatE(20, "def", attr1); Graph->AddStrAttrDatE(400, "ghi", attr1); // this does not show since ""=null Graph->AddStrAttrDatE(455, "", attr1); EXPECT_EQ('c', Graph->GetEAStrI(attr1, 10).GetDat().LastCh()); EXPECT_EQ('f', Graph->GetEAStrI(attr1, 20).GetDat().LastCh()); EdgeId = 0; DefEdges = 0; TAStrIV.Clr(); for (TNEANet::TAStrI EI = Graph->BegEAStrI(attr1); EI < Graph->EndEAStrI(attr1); EI++) { if (EI.GetDat() != TStr::GetNullStr()) { TAStrIV.Add(EI.GetDat()); EdgeId++; } else { DefEdges++; } } EXPECT_EQ(3, EdgeId); EXPECT_EQ(NEdges - 3, DefEdges); TAStrIV.Sort(); // TODO(nkhadke): Fix hack to compare strings properly. This works for now. EXPECT_EQ('c', TAStrIV[0].LastCh()); EXPECT_EQ('f', TAStrIV[1].LastCh()); EXPECT_EQ('i', TAStrIV[2].LastCh()); // Test vertical iterator over many types (must skip default/deleted attr) int EId = 55; Graph->AddStrAttrDatE(EId, "aaa", attr1); Graph->AddIntAttrDatE(EId, 3*2, attr2); Graph->AddFltAttrDatE(EId, 3.41, attr3); Graph->AddStrAttrDatE(80, "dont appear", attr4); // should not show up TStrV EIdAttrName; Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); EXPECT_EQ(3, AttrLen); Graph->DelAttrDatE(EId, attr2); Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("int") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } Graph->AddIntAttrDatE(EId, 3*2, attr2); Graph->DelAttrE(attr1); Graph->AttrNameEI(EId, EIdAttrName); AttrLen = EIdAttrName.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("aaa") == EIdAttrName[i]()) { // FAIL EXPECT_EQ(2,3); } } TStrV EIdAttrValue; Graph->AttrValueEI(EId, EIdAttrValue); AttrLen = EIdAttrValue.Len(); for (i = 0; i < AttrLen; i++) { if (TStr("str") == EIdAttrValue[i]()) { // FAIL EXPECT_EQ(2,3); } } expectedTotal = 0; for (i = 0; i <NEdges; i++) { Graph->AddIntAttrDatE(i, NEdges+i, attr2); EXPECT_EQ(NEdges+i, Graph->GetIntAttrDatE(i, attr2)); expectedTotal += NEdges+i; } { TFOut FOut(FName); Graph->Save(FOut); FOut.Flush(); Graph->Clr(); } { TFIn FIn(FName); Graph1 = TNEANet::Load(FIn); } total = 0; for (TNEANet::TAIntI EI = Graph1->BegNAIntI(attr2); EI < Graph1->EndNAIntI(attr2); EI++) { total += EI.GetDat(); } EXPECT_EQ(expectedTotal, total); //Graph1->Dump(); Graph1->Clr(); }