9 template <
class PGraph>
PNGraph GetBfsTree(
const PGraph& Graph,
const int& StartNId,
const bool& FollowOut,
const bool& FollowIn);
11 template <
class PGraph>
int GetSubTreeSz(
const PGraph& Graph,
const int& StartNId,
const bool& FollowOut,
const bool& FollowIn,
int& TreeSzX,
int& TreeDepthX);
15 template <
class PGraph>
int GetNodesAtHop(
const PGraph& Graph,
const int& StartNId,
const int& Hop,
TIntV& NIdV,
const bool& IsDir=
false);
19 template <
class PGraph>
int GetNodesAtHops(
const PGraph& Graph,
const int& StartNId,
TIntPrV& HopCntV,
const bool& IsDir=
false);
26 template <
class PGraph>
int GetShortPath(
const PGraph& Graph,
const int& SrcNId,
const int& DstNId,
const bool& IsDir=
false);
32 template <
class PGraph>
int GetShortPath(
const PGraph& Graph,
const int& SrcNId,
TIntH& NIdToDistH,
const bool& IsDir=
false,
const int& MaxDist=
TInt::Mx);
40 template <
class PGraph>
int GetBfsFullDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir=
false);
44 template <
class PGraph>
double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir=
false);
48 template <
class PGraph>
double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiamX,
int& FullDiamX);
52 template <
class PGraph>
double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiamX,
int& FullDiamX,
double& AvgSPLX);
57 template <
class PGraph>
double GetBfsEffDiamAll(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiamX,
int& FullDiamX,
double& AvgSPLX);
61 template <
class PGraph>
double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const TIntV& SubGraphNIdV,
const bool& IsDir,
double& EffDiamX,
int& FullDiamX);
82 template<
class PGraph>
90 TBreathFS(
const PGraph& GraphPt,
const bool& InitBigQ=
true) :
93 void SetGraph(
const PGraph& GraphPt);
95 int DoBfs(
const int& StartNode,
const bool& FollowOut,
const bool& FollowIn,
const int& TargetNId=-1,
const int& MxDist=
TInt::Mx);
97 int DoBfsHybrid(
const int& StartNode,
const bool& FollowOut,
const bool& FollowIn,
const int& TargetNId=-1,
const int& MxDist=
TInt::Mx);
104 int GetHops(
const int& SrcNId,
const int& DstNId)
const;
107 int GetRndPath(
const int& SrcNId,
const int& DstNId,
TIntV& PathNIdV)
const;
112 static const unsigned int alpha = 100;
113 static const unsigned int beta = 20;
115 bool TopDownStep(
TIntV &NIdDistV,
TIntV *Frontier,
TIntV *NextFrontier,
int& MaxDist,
const int& TargetNId,
const bool& FollowOut,
const bool& FollowIn);
116 bool BottomUpStep(
TIntV &NIdDistV,
TIntV *Frontier,
TIntV *NextFrontier,
int& MaxDist,
const int& TargetNId,
const bool& FollowOut,
const bool& FollowIn);
119 template<
class PGraph>
122 const int N=GraphPt->GetNodes();
123 if (Queue.Reserved() < N) { Queue.Gen(N); }
124 if (NIdDistH.GetReservedKeyIds() < N) { NIdDistH.Gen(N); }
127 template<
class PGraph>
128 int TBreathFS<PGraph>::DoBfs(
const int& StartNode,
const bool& FollowOut,
const bool& FollowIn,
const int& TargetNId,
const int& MxDist) {
129 StartNId = StartNode;
130 IAssert(Graph->IsNode(StartNId));
133 NIdDistH.Clr(
false); NIdDistH.AddDat(StartNId, 0);
134 Queue.Clr(
false); Queue.Push(StartNId);
136 while (! Queue.Empty()) {
137 const int NId = Queue.Top(); Queue.Pop();
138 const int Dist = NIdDistH.GetDat(NId);
139 if (Dist == MxDist) {
break; }
140 const typename PGraph::TObj::TNodeI NodeI = Graph->GetNI(NId);
142 for (v = 0; v < NodeI.GetOutDeg(); v++) {
143 const int DstNId = NodeI.GetOutNId(v);
144 if (! NIdDistH.IsKey(DstNId)) {
145 NIdDistH.AddDat(DstNId, Dist+1);
147 if (DstNId == TargetNId) {
return MaxDist; }
153 for (v = 0; v < NodeI.GetInDeg(); v++) {
154 const int DstNId = NodeI.GetInNId(v);
155 if (! NIdDistH.IsKey(DstNId)) {
156 NIdDistH.AddDat(DstNId, Dist+1);
158 if (DstNId == TargetNId) {
return MaxDist; }
167 template<
class PGraph>
169 StartNId = StartNode;
170 IAssert(Graph->IsNode(StartNId));
171 if (TargetNId == StartNode)
return 0;
172 const typename PGraph::TObj::TNodeI StartNodeI = Graph->GetNI(StartNode);
175 TIntV NIdDistV(Graph->GetMxNId() + 1);
176 for (
int i = 0; i < NIdDistV.Len(); i++) {
179 TIntV *Frontier =
new TIntV(Graph->GetNodes(), 0);
180 TIntV *NextFrontier =
new TIntV(Graph->GetNodes(), 0);
182 NIdDistV.
SetVal(StartNId, 0);
183 Frontier->
Add(StartNId);
186 const unsigned int TotalNodes = Graph->GetNodes();
187 unsigned int UnvisitedNodes = Graph->GetNodes();
188 while (! Frontier->
Empty()) {
190 NextFrontier->Clr(
false);
191 if (MaxDist == MxDist) {
break; }
193 UnvisitedNodes -= Frontier->
Len();
194 if (Stage == 0 && UnvisitedNodes / Frontier->
Len() < alpha) {
196 }
else if (Stage == 1 && TotalNodes / Frontier->
Len() > beta) {
201 bool targetFound =
false;
202 if (Stage == 0 || Stage == 2) {
203 targetFound = TopDownStep(NIdDistV, Frontier, NextFrontier, MaxDist, TargetNId, FollowOut, FollowIn);
205 targetFound = BottomUpStep(NIdDistV, Frontier, NextFrontier, MaxDist, TargetNId, FollowOut, FollowIn);
208 MaxDist = NIdDistV[TargetNId];
213 TIntV *temp = Frontier;
214 Frontier = NextFrontier;
222 for (
int NId = 0; NId < NIdDistV.Len(); NId++) {
223 if (NIdDistV[NId] != -1) {
224 NIdDistH.AddDat(NId, NIdDistV[NId]);
230 template<
class PGraph>
234 const int Dist = NIdDistV[NId];
236 const typename PGraph::TObj::TNodeI NodeI = Graph->GetNI(NId);
238 for (
int v = 0; v < NodeI.GetOutDeg(); v++) {
239 const int NeighborNId = NodeI.GetOutNId(v);
240 if (NIdDistV[NeighborNId] == -1) {
241 NIdDistV.
SetVal(NeighborNId, Dist+1);
242 if (NeighborNId == TargetNId)
return true;
243 NextFrontier->
Add(NeighborNId);
248 for (
int v = 0; v < NodeI.GetInDeg(); v++) {
249 const int NeighborNId = NodeI.GetInNId(v);
250 if (NIdDistV[NeighborNId] == -1) {
251 NIdDistV.
SetVal(NeighborNId, Dist+1);
252 if (NeighborNId == TargetNId)
return true;
253 NextFrontier->
Add(NeighborNId);
261 template<
class PGraph>
263 for (
typename PGraph::TObj::TNodeI NodeI = Graph->BegNI(); NodeI < Graph->EndNI(); NodeI++) {
264 const int NId = NodeI.GetId();
265 if (NIdDistV[NId] == -1) {
267 for (
int v = 0; v < NodeI.GetInDeg(); v++) {
268 const int ParentNId = NodeI.GetInNId(v);
269 if (NIdDistV[ParentNId] == MaxDist) {
270 NIdDistV[NId] = MaxDist + 1;
271 if (NId == TargetNId)
return true;
272 NextFrontier->
Add(NId);
277 if (FollowIn && NIdDistV[NId] == -1) {
278 for (
int v = 0; v < NodeI.GetOutDeg(); v++) {
279 const int ParentNId = NodeI.GetOutNId(v);
280 if (NIdDistV[ParentNId] == MaxDist) {
281 NIdDistV[NId] = MaxDist + 1;
282 if (NId == TargetNId)
return true;
283 NextFrontier->
Add(NId);
293 template<
class PGraph>
296 if (SrcNId!=StartNId) {
return -1; }
297 if (! NIdDistH.IsKeyGetDat(DstNId, Dist)) {
return -1; }
301 template<
class PGraph>
304 if (SrcNId!=StartNId || ! NIdDistH.IsKey(DstNId)) {
return -1; }
305 PathNIdV.
Add(DstNId);
308 TInt CurDist, NextDist;
309 while (CurNId != SrcNId) {
310 typename PGraph::TObj::TNodeI NI = Graph->GetNI(CurNId);
311 IAssert(NIdDistH.IsKeyGetDat(CurNId, CurDist));
312 CloserNIdV.
Clr(
false);
313 for (
int e = 0; e < NI.GetDeg(); e++) {
314 const int Next = NI.GetNbrNId(e);
315 if (NIdDistH.IsKeyGetDat(Next, NextDist)) {
316 if (NextDist == CurDist-1) { CloserNIdV.
Add(Next); }
321 PathNIdV.
Add(CurNId);
324 return PathNIdV.
Len()-1;
331 template <
class PGraph>
332 PNGraph GetBfsTree(
const PGraph& Graph,
const int& StartNId,
const bool& FollowOut,
const bool& FollowIn) {
340 typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
345 for (
int e = 0; e < NI.GetInDeg(); e++) {
346 const int Prev = NI.GetInNId(e);
352 for (
int e = 0; e < NI.GetOutDeg(); e++) {
353 const int Prev = NI.GetOutNId(e);
362 template <
class PGraph>
363 int GetSubTreeSz(
const PGraph& Graph,
const int& StartNId,
const bool& FollowOut,
const bool& FollowIn,
int& TreeSz,
int& TreeDepth) {
374 template <
class PGraph>
375 int GetNodesAtHop(
const PGraph& Graph,
const int& StartNId,
const int& Hop,
TIntV& NIdV,
const bool& IsDir) {
377 BFS.
DoBfs(StartNId,
true, !IsDir, -1, Hop);
386 template <
class PGraph>
396 return HopCntV.
Len();
399 template <
class PGraph>
400 int GetShortPath(
const PGraph& Graph,
const int& SrcNId,
TIntH& NIdToDistH,
const bool& IsDir,
const int& MaxDist) {
402 BFS.
DoBfs(SrcNId,
true, ! IsDir, -1, MaxDist);
405 return NIdToDistH[NIdToDistH.
Len()-1];
408 template <
class PGraph>
409 int GetShortPath(
const PGraph& Graph,
const int& SrcNId,
const int& DstNId,
const bool& IsDir) {
412 return BFS.
GetHops(SrcNId, DstNId);
415 template <
class PGraph>
416 int GetBfsFullDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir) {
423 template <
class PGraph>
424 double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir) {
431 template <
class PGraph>
432 double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiam,
int& FullDiam) {
434 EffDiam = -1; FullDiam = -1;
435 return GetBfsEffDiam(Graph, NTestNodes, IsDir, EffDiam, FullDiam, AvgDiam);
438 template <
class PGraph>
439 double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiam,
int& FullDiam,
double& AvgSPL) {
440 EffDiam = -1; FullDiam = -1; AvgSPL = -1;
446 for (
int tries = 0; tries <
TMath::Mn(NTestNodes, Graph->GetNodes()); tries++) {
447 const int NId = NodeIdV[tries];
453 double SumPathL=0, PathCnt=0;
454 for (
int i = 0; i < DistToCntH.
Len(); i++) {
456 SumPathL += DistToCntH.
GetKey(i) * DistToCntH[i];
457 PathCnt += DistToCntH[i];
461 FullDiam = DistNbrsPdfV.
Last().Key;
462 AvgSPL = SumPathL/PathCnt;
466 template <
class PGraph>
467 double GetBfsEffDiamAll(
const PGraph& Graph,
const int& NTestNodes,
const bool& IsDir,
double& EffDiam,
int& FullDiam,
double& AvgSPL) {
468 return GetBfsEffDiam(Graph, NTestNodes, IsDir, EffDiam, FullDiam, AvgSPL);
471 template <
class PGraph>
472 double GetBfsEffDiam(
const PGraph& Graph,
const int& NTestNodes,
const TIntV& SubGraphNIdV,
const bool& IsDir,
double& EffDiam,
int& FullDiam) {
481 for (
int tries = 0; tries <
TMath::Mn(NTestNodes, SubGraphNIdV.
Len()); tries++) {
482 const int NId = NodeIdV[tries];
484 for (
int i = 0; i < SubGraphNIdV.
Len(); i++) {
486 DistToCntH.
AddDat(Dist) += 1;
491 for (
int i = 0; i < DistToCntH.
Len(); i++) {
496 FullDiam = DistNbrsPdfV.
Last().Key;
500 template <
class PGraph>
503 int MxNId = Graph->GetMxNId();
504 int NonNodeDepth = 2147483647;
505 int InfDepth = 2147483646;
506 ShortestDists.
Gen(MxNId);
507 for (
int NId = 0; NId < MxNId; NId++) {
508 if (Graph->IsNode(NId)) { ShortestDists[NId] = InfDepth; }
509 else { ShortestDists[NId] = NonNodeDepth; }
512 TIntV Vec1(MxNId, 0);
513 TIntV Vec2(MxNId, 0);
515 ShortestDists[StartNId] = 0;
516 TIntV* PCurV = &Vec1;
517 PCurV->
Add(StartNId);
518 TIntV* PNextV = &Vec2;
520 while (!PCurV->
Empty()) {
522 for (
int i = 0; i < PCurV->
Len(); i++) {
523 int NId = PCurV->
GetVal(i);
524 typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
525 for (
int e = 0; e < NI.GetOutDeg(); e++) {
526 const int OutNId = NI.GetOutNId(e);
527 if (ShortestDists[OutNId].Val == InfDepth) {
528 ShortestDists[OutNId] = Depth;
544 template <
class PGraph>
546 int MxNId = Graph->GetMxNId();
547 int NonNodeDepth = 2147483647;
548 int InfDepth = 2147483646;
549 ShortestDists.
Gen(MxNId);
550 #pragma omp parallel for schedule(dynamic,10000)
551 for (
int NId = 0; NId < MxNId; NId++) {
552 if (Graph->IsNode(NId)) { ShortestDists[NId] = InfDepth; }
553 else { ShortestDists[NId] = NonNodeDepth; }
556 TIntV Vec1(MxNId, 0);
557 TIntV Vec2(MxNId, 0);
559 ShortestDists[StartNId] = 0;
560 TIntV* PCurV = &Vec1;
561 PCurV->
Add(StartNId);
562 TIntV* PNextV = &Vec2;
565 while (!PCurV->
Empty()) {
567 #pragma omp parallel for schedule(dynamic,10000)
568 for (
int i = 0; i < PCurV->
Len(); i++) {
569 int NId = PCurV->
GetVal(i);
570 typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
571 for (
int e = 0; e < NI.GetOutDeg(); e++) {
572 const int OutNId = NI.GetOutNId(e);
573 if (__sync_bool_compare_and_swap(&(ShortestDists[OutNId].Val), InfDepth, Depth)) {
574 PNextV->
AddMP(OutNId);
static const T & Mn(const T &LVal, const T &RVal)
bool BottomUpStep(TIntV &NIdDistV, TIntV *Frontier, TIntV *NextFrontier, int &MaxDist, const int &TargetNId, const bool &FollowOut, const bool &FollowIn)
TIter EndI() const
Returns an iterator referring to the past-the-end element in the vector.
int GetHops(const int &SrcNId, const int &DstNId) const
static const unsigned int beta
int GetShortestDistances(const PGraph &Graph, const int &StartNId, const bool &FollowOut, const bool &FollowIn, TIntV &ShortestDists)
int GetBfsFullDiam(const PGraph &Graph, const int &NTestNodes, const bool &IsDir=false)
Returns the (approximation of the) Diameter (maximum shortest path length) of a graph (by performing ...
bool TopDownStep(TIntV &NIdDistV, TIntV *Frontier, TIntV *NextFrontier, int &MaxDist, const int &TargetNId, const bool &FollowOut, const bool &FollowIn)
double GetBfsEffDiam(const PGraph &Graph, const int &NTestNodes, const bool &IsDir=false)
Returns the (approximation of the) Effective Diameter (90-th percentile of the distribution of shorte...
double GetBfsEffDiamAll(const PGraph &Graph, const int &NTestNodes, const bool &IsDir, double &EffDiamX, int &FullDiamX, double &AvgSPLX)
Returns the (approximation of the) Effective Diameter, the Diameter and the Average Shortest Path len...
static const T & Mx(const T &LVal, const T &RVal)
static PNGraph New()
Static constructor that returns a pointer to the graph. Call: PNGraph Graph = TNGraph::New().
int DoBfs(const int &StartNode, const bool &FollowOut, const bool &FollowIn, const int &TargetNId=-1, const int &MxDist=TInt::Mx)
Performs BFS from node id StartNode for at maps MxDist steps by only following in-links (parameter Fo...
TSizeTy Len() const
Returns the number of elements in the vector.
TKeyDat< TInt, TFlt > TIntFltKd
static const unsigned int alpha
TBreathFS(const PGraph &GraphPt, const bool &InitBigQ=true)
int GetNodesAtHops(const PGraph &Graph, const int &StartNId, TIntPrV &HopCntV, const bool &IsDir=false)
Returns the number of nodes at each hop distance from the starting node StartNId. ...
static TPt< TSOut > New()
TSizeTy AddMP(const TVal &Val)
Adds element Val at the end of the vector in a thread safe manner, returns the element index in the v...
int AddNode(int NId=-1)
Adds a node of ID NId to the graph.
const TDat & GetDat(const TKey &Key) const
void Reduce(const TSizeTy &_Vals=-1)
Reduces the vector's length to _Vals elements, which must be less than the current length...
void SetGraph(const PGraph &GraphPt)
Sets the graph to be used by the BFS to GraphPt and resets the data structures.
PNGraph GetBfsTree(const PGraph &Graph, const int &StartNId, const bool &FollowOut, const bool &FollowIn)
Returns a directed Breadth-First-Search tree rooted at StartNId.
bool Empty() const
Tests whether the vector is empty.
int GetRndPath(const int &SrcNId, const int &DstNId, TIntV &PathNIdV) const
const TVal & GetVal(const TSizeTy &ValN) const
Returns a reference to the element at position ValN in the vector.
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
int GetNodesAtHop(const PGraph &Graph, const int &StartNId, const int &Hop, TIntV &NIdV, const bool &IsDir=false)
Finds IDs of all nodes that are at distance Hop from node StartNId.
void Sort(const bool &Asc=true)
Sorts the elements of the vector.
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge from node SrcNId to node DstNId to the graph.
double CalcEffDiamPdf(const TIntFltKdV &DistNbrsPdfV, const double &Percentile)
Helper function for computing a given Percentile of a (unnormalized) probability distribution functio...
bool IsNode(const int &NId) const
Tests whether ID NId is a node.
bool IsKeyGetDat(const TKey &Key, TDat &Dat) const
const TVal & Last() const
Returns a reference to the last element of the vector.
int GetSubTreeSz(const PGraph &Graph, const int &StartNId, const bool &FollowOut, const bool &FollowIn, int &TreeSzX, int &TreeDepthX)
Returns the BFS tree size (number of nodes) and depth (number of levels) by following in-links (param...
void SetVal(const TSizeTy &ValN, const TVal &Val)
Sets the value of element at position ValN to Val.
int GetShortestDistancesMP2(const PGraph &Graph, const int &StartNId, const bool &FollowOut, const bool &FollowIn, TIntV &ShortestDists)
void GetKeyV(TVec< TKey > &KeyV) const
TIter BegI() const
Returns an iterator pointing to the first element in the vector.
void Shuffle(TRnd &Rnd)
Randomly shuffles the elements of the vector.
int GetNVisited() const
Returns the number of nodes visited/reached by the BFS.
void GetKeyDatPrV(TVec< TPair< TKey, TDat > > &KeyDatPrV) const
void GetVisitedNIdV(TIntV &NIdV) const
Returns the IDs of the nodes visited/reached by the BFS.
void Clr(const bool &DoDel=true, const int &NoDelLim=-1, const bool &ResetDat=true)
void Reverse()
Reverses the order of the elements in the vector.
int DoBfsHybrid(const int &StartNode, const bool &FollowOut, const bool &FollowIn, const int &TargetNId=-1, const int &MxDist=TInt::Mx)
Same functionality as DoBfs with better performance.
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
int GetUniDevInt(const int &Range=0)
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
int GetShortPath(const PGraph &Graph, const int &SrcNId, const int &DstNId, const bool &IsDir=false)
Returns the length of the shortest path from node SrcNId to node DstNId.
TDat & AddDat(const TKey &Key)
const TKey & GetKey(const int &KeyId) const
void SortByDat(const bool &Asc=true)