10 template <
class PGraph>
void GetAnf(
const PGraph& Graph,
const int& SrcNId,
TIntFltKdV& DistNbrsV,
const int& MxDist,
const bool& IsDir,
const int& NApprox=32);
17 template <
class PGraph>
void GetAnf(
const PGraph& Graph,
TIntFltKdV& DistNbrsV,
const int& MxDist,
const bool& IsDir,
const int& NApprox=32);
20 template <
class PGraph>
double GetAnfEffDiam(
const PGraph& Graph,
const bool& IsDir,
const double& Percentile,
const int& NApprox);
23 template <
class PGraph>
double GetAnfEffDiam(
const PGraph& Graph,
const int NRuns=1,
int NApprox=-1);
32 template <
class PGraph>
44 TGraphAnf(
const PGraph& GraphPt,
const int& Approx=32,
const int& moreBits=5,
const int& RndSeed=0) :
45 NApprox(Approx), MoreBits(moreBits), Graph(GraphPt), Rnd(RndSeed) {
IAssert(NApprox%8==0);
IAssert(
sizeof(
uint)==4); }
48 void Union(TAnfBitV& BitV1,
const uint64& NId1Offset, TAnfBitV& BitV2,
const uint64& NId2Offset)
const;
51 return pow(2.0,
AvgLstZero(BitV, NIdOffset)) / 0.77351; }
66 template <
class PGraph>
68 const int NNodes = Graph->GetNodes();
69 const int LogNodes = int(ceil(
TMath::Log2(NNodes)));
70 ApproxBytes = NApprox / 8;
71 NBits = LogNodes + MoreBits;
72 const int BytesPerNd = ApproxBytes * NBits;
73 int64 VSize = ((
static_cast<int64>(NNodes) * static_cast<int64>(BytesPerNd))/
sizeof(
uint)) + 1;
75 TStr::Fmt(
"Your graph is too large for Approximate Neighborhood Function, %s is larger than %d",
84 for (
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI != Graph->EndNI(); NI++) {
85 NIdToBitPosH.AddDat(NI.GetId(), NodeOff);
87 for (
int approx = 0; approx < NApprox; approx++) {
88 const int RndNum = Rnd.GetUniDevInt();
89 for (SetBit = 0; (RndNum & (1<<SetBit))==0 && SetBit < NBits; SetBit++) { }
90 if (SetBit >= NBits) SetBit = NBits-1;
91 const int BitPos = ApproxBytes * SetBit + approx / 8;
92 *(BitVPt + NodeOff + BitPos) |= (1<<(approx % 8));
94 NodeOff += BytesPerNd;
98 template <
class PGraph>
102 for (
int b=0; b < ApproxBytes*NBits; b++, DstI++, SrcI++) { *DstI |= *SrcI; }
106 template <
class PGraph>
108 int approx, bit, AvgBitPos = 0;
110 for (approx = 0; approx < NApprox; approx++) {
111 for (bit = 0; bit < NBits; bit++) {
112 if ((*(BitVPt+NIdOffset + ApproxBytes*bit + approx/8) & (1<<(approx%8))) == 0)
break; }
113 if (bit > NBits) bit = NBits;
116 return AvgBitPos/double(NApprox) ;
119 template <
class PGraph>
123 InitAnfBits(CurBitsV);
IAssert(CurBitsV.
BegI() != NULL);
126 DistNbrsV.
Add(
TIntFltKd(1, Graph->GetNI(SrcNId).GetOutDeg()));
127 for (
int dist = 1; dist < (MxDist==-1 ?
TInt::Mx : MxDist); dist++) {
128 memcpy(LastBitsV.
BegI(), CurBitsV.
BegI(),
sizeof(
uint)*CurBitsV.
Len());
129 for (
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
130 const uint64 NIdOffset = GetNIdOffset(NI.GetId());
131 for (
int e = 0; e < NI.GetOutDeg(); e++) {
132 const uint64 NId2Offset = GetNIdOffset(NI.GetOutNId(e));
133 Union(CurBitsV, NIdOffset, LastBitsV, NId2Offset);
136 for (
int e = 0; e < NI.GetInDeg(); e++) {
137 const uint64 NId2Offset = GetNIdOffset(NI.GetInNId(e));
138 Union(CurBitsV, NIdOffset, LastBitsV, NId2Offset);
142 DistNbrsV.
Add(
TIntFltKd(dist, GetCount(CurBitsV, GetNIdOffset(SrcNId))));
143 if (DistNbrsV.
Len() > 1 && DistNbrsV.
Last().Dat < 1.001*DistNbrsV[DistNbrsV.
Len()-2].Dat)
break;
147 template <
class PGraph>
150 InitAnfBits(CurBitsV);
IAssert(CurBitsV.
BegI() != NULL);
157 for (
int dist = 1; dist < (MxDist==-1 ?
TInt::Mx : MxDist); dist++) {
159 memcpy(LastBitsV.
BegI(), CurBitsV.
BegI(),
sizeof(
uint)*CurBitsV.
Len());
160 for (
typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
161 const uint64 NIdOffset = GetNIdOffset(NI.GetId());
162 for (e = 0; e < NI.GetOutDeg(); e++) {
163 const uint64 NId2Offset = GetNIdOffset(NI.GetOutNId(e));
164 Union(CurBitsV, NIdOffset, LastBitsV, NId2Offset);
167 for (e = 0; e < NI.GetInDeg(); e++) {
168 const uint64 NId2Offset = GetNIdOffset(NI.GetInNId(e));
169 Union(CurBitsV, NIdOffset, LastBitsV, NId2Offset);
174 for (v = NIdToBitPosH.FFirstKeyId(); NIdToBitPosH.FNextKeyId(v); ) {
175 NPairs += GetCount(CurBitsV, NIdToBitPosH[v]);
179 if (NPairs == 0) {
break; }
180 if (DistNbrsV.
Len() > 1 && NPairs < 1.001*DistNbrsV.
LastLast().Dat) {
break; }
188 namespace TSnapDetail {
203 template <
class PGraph>
204 void GetAnf(
const PGraph& Graph,
const int& SrcNId,
TIntFltKdV& DistNbrsV,
const int& MxDist,
const bool& IsDir,
const int& NApprox) {
206 Anf.
GetNodeAnf(SrcNId, DistNbrsV, MxDist, IsDir);
209 template <
class PGraph>
210 void GetAnf(
const PGraph& Graph,
TIntFltKdV& DistNbrsV,
const int& MxDist,
const bool& IsDir,
const int& NApprox) {
215 template <
class PGraph>
216 double GetAnfEffDiam(
const PGraph& Graph,
const bool& IsDir,
const double& Percentile,
const int& NApprox) {
223 template<
class PGraph>
228 if (Graph->GetNodes() < 100000) { NApprox = 64; }
229 else if (Graph->GetNodes() < 1000000) { NApprox = 32; }
230 else { NApprox = 16; }
232 const bool IsDir =
false;
233 for (
int r = 0; r < NRuns; r++) {
241 PGraph Graph = PGraph::TObj::New();
248 for (
int v = 0; v < 6; v++) { Graph->AddNode(v); }
249 Graph->AddEdge(2, 3);
250 Graph->AddEdge(3, 4);
251 Graph->AddEdge(4, 5);
252 Graph->AddEdge(5, 2);
254 for (
int t = 0; t < 10; t++) {
258 printf(
"\n--seed: %d---------------------\n", t+1);
259 for (
int i = 0; i < DistToNbrsV.
Len(); i++) {
260 printf(
"dist: %d\t hops:%f\n", DistToNbrsV[i].Key(), DistToNbrsV[i].Dat());
262 AnfV.
Add(DistToNbrsV.
Last().Dat);
265 printf(
"-----------\nAvgAnf: %f StDev: %f\n", Mom.
GetMean(), Mom.
GetSDev());
void GetGraphAnf(TIntFltKdV &DistNbrsV, const int &MxDist, const bool &IsDir)
Main namespace for all the Snap global entities.
#define IAssertR(Cond, Reason)
TSizeTy Len() const
Returns the number of elements in the vector.
TKeyDat< TInt, TFlt > TIntFltKd
void GetAnf(const PGraph &Graph, const int &SrcNId, TIntFltKdV &DistNbrsV, const int &MxDist, const bool &IsDir, const int &NApprox=32)
double GetAnfEffDiam(const PGraph &Graph, const bool &IsDir, const double &Percentile, const int &NApprox)
void Union(TAnfBitV &BitV1, const uint64 &NId1Offset, TAnfBitV &BitV2, const uint64 &NId2Offset) const
const TDat & GetDat(const TKey &Key) const
TGraphAnf(const PGraph &GraphPt, const int &Approx=32, const int &moreBits=5, const int &RndSeed=0)
double AvgLstZero(const TAnfBitV &BitV, const uint64 &NIdOffset) const
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
void Add(const TFlt &Val, const TFlt &Wgt=1)
void PutAll(const TVal &Val)
Sets all elements of the vector to value Val.
unsigned long long uint64
const TVal & LastLast() const
Returns a reference to the one before last element of the vector.
double CalcEffDiamPdf(const TIntFltKdV &DistNbrsPdfV, const double &Percentile)
Helper function for computing a given Percentile of a (unnormalized) probability distribution functio...
void InitAnfBits(TAnfBitV &BitV)
void GetNodeAnf(const int &SrcNId, TIntFltKdV &DistNbrsV, const int &MxDist, const bool &IsDir)
const TVal & Last() const
Returns a reference to the last element of the vector.
double CalcAvgDiamPdf(const TIntFltKdV &DistNbrsPdfV)
Helper function for computing the mean of a (unnormalized) probability distribution function...
UndefDefaultCopyAssign(TGraphAnf)
double CalcEffDiam(const TIntFltKdV &DistNbrsCdfV, const double &Percentile)
Helper function for computing a given Percentile of a (unnormalized) cumulative distribution function...
uint64 GetNIdOffset(const int &NId) const
TIter BegI() const
Returns an iterator pointing to the first element in the vector.
static TStr Fmt(const char *FmtStr,...)
static double Log2(const double &Val)
THash< TInt, uint64 > NIdToBitPosH
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Vector is a sequence TVal objects representing an array that can change in size.
double GetCount(const TAnfBitV &BitV, const uint64 &NIdOffset) const