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(); }
// Table manipulations TEST(TIntIntH, ManipulateTable) { const int64 NElems = 1000000; int DDist = 10; const char *FName = "test.hashint.dat"; TIntIntH TableInt; TIntIntH TableInt1; TIntIntH TableInt2; int i; int d; int n; int Id; int Key; int64 KeySumVal; int64 DatSumVal; int64 KeySum; int64 DatSum; int64 KeySumDel; int64 DatSumDel; int DelCount; int Count; // add table elements d = Prime(NElems); n = d; KeySumVal = 0; DatSumVal = 0; for (i = 0; i < NElems; i++) { TableInt.AddDat(n,n+1); KeySumVal += n; DatSumVal += (n+1); //printf("add %d %d\n", n, n+1); n = (n + d) % NElems; } EXPECT_EQ(0,TableInt.Empty()); EXPECT_EQ(NElems,TableInt.Len()); EXPECT_EQ(0,(NElems-1)*(NElems)/2 - KeySumVal); EXPECT_EQ(0,(NElems)*(NElems+1)/2 - DatSumVal); // verify elements by successive keys KeySum = 0; DatSum = 0; for (i = 0; i < NElems; i++) { Id = TableInt.GetKeyId(i); EXPECT_EQ(1,Id >= 0); Key = TableInt.GetKey(Id); EXPECT_EQ(0,TableInt.GetDat(Key)-Key-1); KeySum += Key; DatSum += TableInt.GetDat(Key); } EXPECT_EQ(0,KeySumVal - KeySum); EXPECT_EQ(0,DatSumVal - DatSum); // verify elements by distant keys KeySum = 0; DatSum = 0; n = Prime(d); for (i = 0; i < NElems; i++) { Id = TableInt.GetKeyId(n); EXPECT_EQ(1,Id >= 0); Key = TableInt.GetKey(Id); EXPECT_EQ(0,TableInt.GetDat(Key)-Key-1); KeySum += Key; DatSum += TableInt.GetDat(Key); n = (n + d) % NElems; } EXPECT_EQ(0,KeySumVal - KeySum); EXPECT_EQ(0,DatSumVal - DatSum); // verify elements by iterator KeySum = 0; DatSum = 0; for (TIntIntH::TIter It = TableInt.BegI(); It < TableInt.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); KeySum += It.GetKey(); DatSum += It.GetDat(); } EXPECT_EQ(0,KeySumVal - KeySum); EXPECT_EQ(0,DatSumVal - DatSum); // verify elements by key index KeySum = 0; DatSum = 0; Id = TableInt.FFirstKeyId(); while (TableInt.FNextKeyId(Id)) { EXPECT_EQ(1,Id >= 0); Key = TableInt.GetKey(Id); EXPECT_EQ(0,TableInt.GetDat(Key)-Key-1); KeySum += Key; DatSum += TableInt.GetDat(Key); } EXPECT_EQ(0,KeySumVal - KeySum); EXPECT_EQ(0,DatSumVal - DatSum); // delete elements DelCount = 0; KeySumDel = 0; DatSumDel = 0; for (n = 0; n < NElems; n += DDist) { Id = TableInt.GetKeyId(n); //printf("del %d %d %d\n", n, Id, (int) TableInt[Id]); KeySumDel += n; DatSumDel += TableInt[Id]; TableInt.DelKeyId(Id); DelCount++; } EXPECT_EQ(0,TableInt.Empty()); EXPECT_EQ(NElems-DelCount,TableInt.Len()); // verify elements by iterator KeySum = 0; DatSum = 0; Count = 0; for (TIntIntH::TIter It = TableInt.BegI(); It < TableInt.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); //printf("get %d %d\n", (int) It.GetKey(), (int) It.GetDat()); KeySum += It.GetKey(); DatSum += It.GetDat(); Count++; } EXPECT_EQ(NElems-DelCount,Count); EXPECT_EQ(0,KeySumVal - KeySumDel - KeySum); EXPECT_EQ(0,DatSumVal - DatSumDel - DatSum); // assignment TableInt1 = TableInt; EXPECT_EQ(0,TableInt1.Empty()); EXPECT_EQ(NElems-DelCount,TableInt1.Len()); // verify elements by iterator KeySum = 0; DatSum = 0; Count = 0; for (TIntIntH::TIter It = TableInt1.BegI(); It < TableInt1.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); //printf("get %d %d\n", (int) It.GetKey(), (int) It.GetDat()); KeySum += It.GetKey(); DatSum += It.GetDat(); Count++; } EXPECT_EQ(NElems-DelCount,Count); EXPECT_EQ(0,KeySumVal - KeySumDel - KeySum); EXPECT_EQ(0,DatSumVal - DatSumDel - DatSum); // saving and loading { TFOut FOut(FName); TableInt.Save(FOut); FOut.Flush(); } { TFIn FIn(FName); TableInt2.Load(FIn); } EXPECT_EQ(NElems-DelCount,TableInt2.Len()); // verify elements by iterator KeySum = 0; DatSum = 0; Count = 0; for (TIntIntH::TIter It = TableInt2.BegI(); It < TableInt2.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); //printf("get %d %d\n", (int) It.GetKey(), (int) It.GetDat()); KeySum += It.GetKey(); DatSum += It.GetDat(); Count++; } EXPECT_EQ(NElems-DelCount,Count); EXPECT_EQ(0,KeySumVal - KeySumDel - KeySum); EXPECT_EQ(0,DatSumVal - DatSumDel - DatSum); // remove all elements for (i = 0; i < Count; i++) { Id = TableInt.GetRndKeyId(TInt::Rnd, 0.5); TableInt.DelKeyId(Id); } EXPECT_EQ(0,TableInt.Len()); EXPECT_EQ(1,TableInt.Empty()); // verify elements by iterator KeySum = 0; DatSum = 0; Count = 0; for (TIntIntH::TIter It = TableInt.BegI(); It < TableInt.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); //printf("get %d %d\n", (int) It.GetKey(), (int) It.GetDat()); KeySum += It.GetKey(); DatSum += It.GetDat(); Count++; } EXPECT_EQ(0,Count); EXPECT_EQ(0,KeySum); EXPECT_EQ(0,DatSum); // clear the table TableInt1.Clr(); EXPECT_EQ(0,TableInt1.Len()); EXPECT_EQ(1,TableInt1.Empty()); // verify elements by iterator KeySum = 0; DatSum = 0; Count = 0; for (TIntIntH::TIter It = TableInt1.BegI(); It < TableInt1.EndI(); It++) { EXPECT_EQ(0,It.GetDat()-It.GetKey()-1); //printf("get %d %d\n", (int) It.GetKey(), (int) It.GetDat()); KeySum += It.GetKey(); DatSum += It.GetDat(); Count++; } EXPECT_EQ(0,Count); EXPECT_EQ(0,KeySum); EXPECT_EQ(0,DatSum); }