SNAP Library 6.0, Developer Reference  2020-12-09 16:24:20
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
alg.h
Go to the documentation of this file.
1 namespace TSnap {
2 
4 // Node Degrees
5 
7 template <class PGraph> int CntInDegNodes(const PGraph& Graph, const int& NodeInDeg);
9 template <class PGraph> int CntOutDegNodes(const PGraph& Graph, const int& NodeOutDeg);
11 template <class PGraph> int CntDegNodes(const PGraph& Graph, const int& NodeDeg);
13 template <class PGraph> int CntNonZNodes(const PGraph& Graph);
15 template <class PGraph> int CntEdgesToSet(const PGraph& Graph, const int& NId, const TIntSet& NodeSet);
16 
18 template <class PGraph> int GetMxDegNId(const PGraph& Graph);
20 template <class PGraph> int GetMxInDegNId(const PGraph& Graph);
22 template <class PGraph> int GetMxOutDegNId(const PGraph& Graph);
23 
24 // degree histograms
26 template <class PGraph> void GetInDegCnt(const PGraph& Graph, TIntPrV& DegToCntV);
28 template <class PGraph> void GetInDegCnt(const PGraph& Graph, TFltPrV& DegToCntV);
30 template <class PGraph> void GetOutDegCnt(const PGraph& Graph, TIntPrV& DegToCntV);
32 template <class PGraph> void GetOutDegCnt(const PGraph& Graph, TFltPrV& DegToCntV);
34 template <class PGraph> void GetDegCnt(const PGraph& Graph, TIntPrV& DegToCntV);
36 template <class PGraph> void GetDegCnt(const PGraph& Graph, TFltPrV& DegToCntV);
38 template <class PGraph> void GetDegSeqV(const PGraph& Graph, TIntV& DegV);
40 template <class PGraph> void GetDegSeqV(const PGraph& Graph, TIntV& InDegV, TIntV& OutDegV);
41 
43 template <class PGraph> void GetNodeInDegV(const PGraph& Graph, TIntPrV& NIdInDegV);
45 template <class PGraph> void GetNodeOutDegV(const PGraph& Graph, TIntPrV& NIdOutDegV);
46 
48 template <class PGraph> int CntUniqUndirEdges(const PGraph& Graph);
50 template <class PGraph> int CntUniqDirEdges(const PGraph& Graph);
52 template <class PGraph> int CntUniqBiDirEdges(const PGraph& Graph);
54 template <class PGraph> int CntSelfEdges(const PGraph& Graph);
55 
57 // Manipulation
59 template <class PGraph> PGraph GetUnDir(const PGraph& Graph);
61 template <class PGraph> void MakeUnDir(const PGraph& Graph);
63 template <class PGraph> void AddSelfEdges(const PGraph& Graph);
65 template <class PGraph> void DelSelfEdges(const PGraph& Graph);
66 
67 //TODO Implement:
68 //template <class PGraph> void DelBiDirEdges(const PGraph& Graph);
69 
71 template <class PGraph> void DelNodes(PGraph& Graph, const TIntV& NIdV);
73 template <class PGraph> void DelZeroDegNodes(PGraph& Graph);
75 template <class PGraph> void DelDegKNodes(PGraph& Graph, const int& OutDegK, const int& InDegK);
76 
78 // Tree Routines
79 template <class PGraph> bool IsTree(const PGraph& Graph, int& RootNIdX);
80 template <class PGraph> int GetTreeRootNId(const PGraph& Graph) { int RootNId; bool Tree; Tree = IsTree(Graph, RootNId); Assert(Tree); return RootNId; }
81 template <class PGraph> void GetTreeSig(const PGraph& Graph, const int& RootNId, TIntV& Sig);
82 template <class PGraph> void GetTreeSig(const PGraph& Graph, const int& RootNId, TIntV& Sig, TIntPrV& NodeMap);
83 
85 // Implementation
86 template <class PGraph>
87 int CntInDegNodes(const PGraph& Graph, const int& NodeInDeg) {
88  int Cnt = 0;
89  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
90  if (NI.GetInDeg() == NodeInDeg) Cnt++;
91  }
92  return Cnt;
93 }
94 
95 template <class PGraph>
96 int CntOutDegNodes(const PGraph& Graph, const int& NodeOutDeg) {
97  int Cnt = 0;
98  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
99  if (NI.GetOutDeg() == NodeOutDeg) Cnt++;
100  }
101  return Cnt;
102 }
103 
104 template <class PGraph>
105 int CntDegNodes(const PGraph& Graph, const int& NodeDeg) {
106  int Cnt = 0;
107  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
108  if (NI.GetDeg() == NodeDeg) Cnt++;
109  }
110  return Cnt;
111 }
112 
113 template <class PGraph>
114 int CntNonZNodes(const PGraph& Graph) {
115  int Cnt = 0;
116  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
117  if (NI.GetDeg() > 0) Cnt++;
118  }
119  return Cnt;
120 }
121 
122 template <class PGraph>
123 int CntEdgesToSet(const PGraph& Graph, const int& NId, const TIntSet& NodeSet) {
124  if (! Graph->IsNode(NId)) { return 0; }
125  const bool IsDir = Graph->HasFlag(gfDirected);
126  const typename PGraph::TObj::TNodeI NI = Graph->GetNI(NId);
127  if (! IsDir) {
128  int EdgesToSet = 0;
129  for (int e = 0; e < NI.GetOutDeg(); e++) {
130  if (NodeSet.IsKey(NI.GetOutNId(e))) { EdgesToSet++; } }
131  return EdgesToSet;
132  } else {
133  TIntSet Set(NI.GetDeg());
134  for (int e = 0; e < NI.GetOutDeg(); e++) {
135  if (NodeSet.IsKey(NI.GetOutNId(e))) { Set.AddKey(NI.GetOutNId(e)); } }
136  for (int e = 0; e < NI.GetInDeg(); e++) {
137  if (NodeSet.IsKey(NI.GetInNId(e))) { Set.AddKey(NI.GetInNId(e)); } }
138  return Set.Len();
139  }
140 }
141 
142 template <class PGraph>
143 int GetMxDegNId(const PGraph& Graph) {
144  TIntV MxDegV;
145  int MxDeg=-1;
146  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
147  if (MxDeg < NI.GetDeg()) { MxDegV.Clr(); MxDeg = NI.GetDeg(); }
148  if (MxDeg == NI.GetDeg()) { MxDegV.Add(NI.GetId()); }
149  }
150  EAssertR(! MxDegV.Empty(), "Input graph is empty!");
151  return MxDegV[TInt::Rnd.GetUniDevInt(MxDegV.Len())];
152 }
153 
154 template <class PGraph>
155 int GetMxInDegNId(const PGraph& Graph) {
156  TIntV MxDegV;
157  int MxDeg=-1;
158  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
159  if (MxDeg < NI.GetInDeg()) { MxDegV.Clr(); MxDeg = NI.GetInDeg(); }
160  if (MxDeg == NI.GetInDeg()) { MxDegV.Add(NI.GetId()); }
161  }
162  EAssertR(! MxDegV.Empty(), "Input graph is empty!");
163  return MxDegV[TInt::Rnd.GetUniDevInt(MxDegV.Len())];
164 }
165 
166 template <class PGraph>
167 int GetMxOutDegNId(const PGraph& Graph) {
168  TIntV MxDegV;
169  int MxDeg=-1;
170  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
171  if (MxDeg < NI.GetOutDeg()) { MxDegV.Clr(); MxDeg = NI.GetOutDeg(); }
172  if (MxDeg == NI.GetOutDeg()) { MxDegV.Add(NI.GetId()); }
173  }
174  EAssertR(! MxDegV.Empty(), "Input graph is empty!");
175  return MxDegV[TInt::Rnd.GetUniDevInt(MxDegV.Len())];
176 }
177 
178 template <class PGraph>
179 void GetInDegCnt(const PGraph& Graph, TIntPrV& DegToCntV) {
180  TIntH DegToCntH;
181  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
182  DegToCntH.AddDat(NI.GetInDeg())++; }
183  DegToCntV.Gen(DegToCntH.Len(), 0);
184  for (int i = 0; i < DegToCntH.Len(); i++) {
185  DegToCntV.Add(TIntPr(DegToCntH.GetKey(i), DegToCntH[i])); }
186  DegToCntV.Sort();
187 }
188 
189 template <class PGraph>
190 void GetInDegCnt(const PGraph& Graph, TFltPrV& DegToCntV) {
191  TIntH DegToCntH;
192  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
193  DegToCntH.AddDat(NI.GetInDeg())++; }
194  DegToCntV.Gen(DegToCntH.Len(), 0);
195  for (int i = 0; i < DegToCntH.Len(); i++) {
196  DegToCntV.Add(TFltPr(DegToCntH.GetKey(i).Val, DegToCntH[i].Val)); }
197  DegToCntV.Sort();
198 }
199 
200 template <class PGraph>
201 void GetOutDegCnt(const PGraph& Graph, TIntPrV& DegToCntV) {
202  TIntH DegToCntH;
203  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
204  DegToCntH.AddDat(NI.GetOutDeg())++; }
205  DegToCntV.Gen(DegToCntH.Len(), 0);
206  for (int i = 0; i < DegToCntH.Len(); i++) {
207  DegToCntV.Add(TIntPr(DegToCntH.GetKey(i), DegToCntH[i])); }
208  DegToCntV.Sort();
209 }
210 
211 template <class PGraph>
212 void GetOutDegCnt(const PGraph& Graph, TFltPrV& DegToCntV) {
213  TIntH DegToCntH;
214  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
215  DegToCntH.AddDat(NI.GetOutDeg())++; }
216  DegToCntV.Gen(DegToCntH.Len(), 0);
217  for (int i = 0; i < DegToCntH.Len(); i++) {
218  DegToCntV.Add(TFltPr(DegToCntH.GetKey(i).Val, DegToCntH[i].Val)); }
219  DegToCntV.Sort();
220 }
221 
222 template <class PGraph>
223 void GetDegCnt(const PGraph& Graph, TIntPrV& DegToCntV) {
224  TIntH DegToCntH;
225  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
226  DegToCntH.AddDat(NI.GetDeg())++; }
227  DegToCntV.Gen(DegToCntH.Len(), 0);
228  for (int i = 0; i < DegToCntH.Len(); i++) {
229  DegToCntV.Add(TIntPr(DegToCntH.GetKey(i), DegToCntH[i])); }
230  DegToCntV.Sort();
231 }
232 
233 template <class PGraph>
234 void GetDegCnt(const PGraph& Graph, TFltPrV& DegToCntV) {
235  TIntH DegToCntH;
236  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
237  DegToCntH.AddDat(NI.GetDeg())++; }
238  DegToCntV.Gen(DegToCntH.Len(), 0);
239  for (int i = 0; i < DegToCntH.Len(); i++) {
240  DegToCntV.Add(TFltPr(DegToCntH.GetKey(i).Val, DegToCntH[i].Val)); }
241  DegToCntV.Sort();
242 }
243 
244 template <class PGraph>
245 void GetDegSeqV(const PGraph& Graph, TIntV& DegV) {
246  DegV.Gen(Graph->GetNodes(), 0);
247  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
248  DegV.Add(NI.GetDeg());
249  }
250 }
251 
252 template <class PGraph>
253 void GetDegSeqV(const PGraph& Graph, TIntV& InDegV, TIntV& OutDegV) {
254  InDegV.Gen(Graph->GetNodes(), 0);
255  OutDegV.Gen(Graph->GetNodes(), 0);
256  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
257  InDegV.Add(NI.GetInDeg());
258  OutDegV.Add(NI.GetOutDeg());
259  }
260 }
261 
262 template <class PGraph>
263 void GetNodeInDegV(const PGraph& Graph, TIntPrV& NIdInDegV) {
264  NIdInDegV.Reserve(Graph->GetNodes(), 0);
265  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
266  NIdInDegV.Add(TIntPr(NI.GetId(), NI.GetInDeg()));
267  }
268 }
269 
270 template <class PGraph>
271 void GetNodeOutDegV(const PGraph& Graph, TIntPrV& NIdOutDegV) {
272  NIdOutDegV.Reserve(Graph->GetNodes(), 0);
273  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
274  NIdOutDegV.Add(TIntPr(NI.GetId(), NI.GetOutDeg()));
275  }
276 }
277 
278 template <class PGraph>
279 int CntUniqUndirEdges(const PGraph& Graph) {
280  TIntSet NbrSet;
281  TIntSet SelfNbrSet;
282  int Cnt = 0;
283  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
284  NbrSet.Clr(false);
285  for (int e = 0; e < NI.GetDeg(); e++) { // unique neighbors of a node
286  const int NbrId = NI.GetNbrNId(e);
287  if (NbrId == NI.GetId()) { // remember self-edges
288  SelfNbrSet.AddKey(NbrId);
289  } else {
290  NbrSet.AddKey(NbrId);
291  }
292  }
293  Cnt += NbrSet.Len();
294  }
295  // OP RS 2014/06/11 self-edges are currently not used
296  //return Cnt / 2 + SelfNbrSet.Len();
297  return Cnt / 2;
298 }
299 
300 template <class PGraph>
301 int CntUniqDirEdges(const PGraph& Graph) {
302  TIntSet NbrSet;
303  int Cnt = 0;
304  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
305  NbrSet.Clr(false);
306  for (int e = 0; e < NI.GetOutDeg(); e++) { // unique out-neighbors of a node
307  if (NI.GetOutNId(e) != NI.GetId()) { // skip self-edges
308  NbrSet.AddKey(NI.GetOutNId(e)); }
309  }
310  Cnt += NbrSet.Len();
311  }
312  return Cnt;
313 }
314 
315 template <class PGraph>
316 int CntUniqBiDirEdges(const PGraph& Graph) {
317  if (! Graph->HasFlag(gfDirected)) { // graph is undirected
318  return CntUniqUndirEdges(Graph); // then every edge is bi-directional
319  }
320  TIntSet NbrSet;
321  int Cnt = 0;
322  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
323  const int SrcId = NI.GetId();
324  for (int e = 0; e < NI.GetOutDeg(); e++) {
325  const int DstId = NI.GetOutNId(e);
326  if (DstId <= SrcId) { continue; } // count each un-dir edge only once
327  if (Graph->IsEdge(DstId, SrcId)) { Cnt++; }
328  }
329  }
330  return Cnt;
331 }
332 
333 template <class PGraph>
334 int CntSelfEdges(const PGraph& Graph) {
335  int Cnt = 0;
336  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
337  for (int e = 0; e < NI.GetOutDeg(); e++) {
338  if (NI.GetId() == NI.GetOutNId(e)) { Cnt++; }
339  }
340  }
341  return Cnt;
342 }
343 
344 template <class PGraph>
345 PGraph GetUnDir(const PGraph& Graph) {
346  PGraph NewGraphPt = PGraph::New();
347  *NewGraphPt = *Graph;
348  MakeUnDir(NewGraphPt);
349  return NewGraphPt;
350 }
351 
352 template <class PGraph>
353 void MakeUnDir(const PGraph& Graph) {
354  CAssert(HasGraphFlag(typename PGraph::TObj, gfDirected)); // graph has to be directed
355  TIntPrV EdgeV;
356  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
357  const int SrcNId = EI.GetSrcNId();
358  const int DstNId = EI.GetDstNId();
359  if (! Graph->IsEdge(DstNId, SrcNId)) {
360  EdgeV.Add(TIntPr(DstNId, SrcNId));
361  }
362  }
363  for (int i = 0; i < EdgeV.Len(); i++) {
364  Graph->AddEdge(EdgeV[i].Val1, EdgeV[i].Val2);
365  }
366 }
367 
368 template <class PGraph>
369 void AddSelfEdges(const PGraph& Graph) {
370  TIntV EdgeV;
371  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
372  const int NId = NI.GetId();
373  if (! Graph->IsEdge(NId, NId)) {
374  EdgeV.Add(NId);
375  }
376  }
377  for (int i = 0; i < EdgeV.Len(); i++) {
378  Graph->AddEdge(EdgeV[i], EdgeV[i]);
379  }
380 }
381 
382 namespace TSnapDetail {
383 
384 template <class PGraph, bool IsMultiGraph>
385 struct TDelSelfEdges { // not a multigraph graph
386  static void Do(const PGraph& Graph) {
387  TIntV EdgeV;
388  // node graph, no explicit edge ids
389  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
390  if (EI.GetSrcNId() == EI.GetDstNId()) {
391  EdgeV.Add(EI.GetSrcNId());
392  }
393  }
394  for (int i = 0; i < EdgeV.Len(); i++) {
395  Graph->DelEdge(EdgeV[i], EdgeV[i]);
396  }
397  }
398 };
399 
400 template <class PGraph>
401 struct TDelSelfEdges<PGraph, true> { // mutligraph specialization
402  static void Do(const PGraph& Graph) {
403  TIntV EdgeV;
404  for (typename PGraph::TObj::TEdgeI EI = Graph->BegEI(); EI < Graph->EndEI(); EI++) {
405  if (EI.GetSrcNId() == EI.GetDstNId()) {
406  IAssert(EI.GetId() >= 0); // real edge id
407  EdgeV.Add(EI.GetId());
408  }
409  }
410  for (int i = 0; i < EdgeV.Len(); i++) { // delete all edges between a pair of nodes
411  Graph->DelEdge(EdgeV[i]);
412  }
413  }
414 };
415 
416 } // namespace TSnapDetail
417 
418 template <class PGraph>
419 void DelSelfEdges(const PGraph& Graph) {
421  ::Do(Graph);
422 }
423 
424 template <class PGraph>
425 void DelNodes(PGraph& Graph, const TIntV& NIdV) {
426  for (int n = 0; n < NIdV.Len(); n++) {
427  Graph->DelNode(NIdV[n]);
428  }
429 }
430 
431 template <class PGraph>
432 void DelZeroDegNodes(PGraph& Graph) {
433  TIntV DelNIdV;
434  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
435  if (NI.GetDeg() == 0) {
436  DelNIdV.Add(NI.GetId());
437  }
438  }
439  for (int i = 0; i < DelNIdV.Len(); i++) {
440  Graph->DelNode(DelNIdV[i]);
441  }
442 }
443 
444 template <class PGraph>
445 void DelDegKNodes(PGraph& Graph, const int& OutDegK, const int& InDegK) {
446  TIntV DelNIdV;
447  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
448  if (NI.GetOutDeg() == OutDegK || NI.GetInDeg() == InDegK) {
449  DelNIdV.Add(NI.GetId());
450  }
451  }
452  for (int i = 0; i < DelNIdV.Len(); i++) {
453  Graph->DelNode(DelNIdV[i]);
454  }
455 }
456 
457 // tree has directed edges -- so root is a well-defined
458 // children point to a parent
459 template <class PGraph>
460 bool IsTree(const PGraph& Graph, int& RootNId) {
461  if (Graph->GetNodes() == 1 && Graph->GetEdges() == 0) {
462  RootNId = Graph->BegNI().GetId();
463  return true;
464  }
465  RootNId = -1;
466  if (Graph->GetNodes() != Graph->GetEdges()+1) { return false; }
467  int NZeroOutDeg = 0;
468  int ZeroOutDegN = -1;
469  for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
470  if (NI.GetOutDeg() == 0) {
471  ZeroOutDegN = NI.GetId(); NZeroOutDeg++;
472  }
473  if (NI.GetDeg() == 0) { return false; } // isolated nodes
474  }
475  if (NZeroOutDeg==1) {
476  if (! TSnap::IsConnected(Graph)) { return false; }
477  RootNId = ZeroOutDegN; return true;
478  }
479  return false;
480 }
481 
482 // tree signature -- for each level we sort the node in-degrees and concatenate them into a vector
483 template <class PGraph>
484 void GetTreeSig(const PGraph& Graph, const int& RootNId, TIntV& Sig) {
485  CAssert(HasGraphFlag(typename PGraph::TObj, gfDirected));
486  Sig.Gen(Graph->GetNodes(), 0);
487  TSnapQueue<int> NIdQ(Graph->GetNodes());
488  NIdQ.Push(RootNId);
489  int LastPos = 0, NodeCnt = 1;
490  while (! NIdQ.Empty()) {
491  const typename PGraph::TObj::TNodeI Node = Graph->GetNI(NIdQ.Top()); NIdQ.Pop();
492  IAssert(Node.GetInDeg()==0 || Node.GetOutDeg()==0); // child points or is-pointed to by the parent
493  if (Node.GetInDeg() != 0) {
494  for (int e = 0; e < Node.GetInDeg(); e++) {
495  NIdQ.Push(Node.GetInNId(e)); }
496  } else if (Node.GetOutDeg() != 0) {
497  for (int e = 0; e < Node.GetOutDeg(); e++) {
498  NIdQ.Push(Node.GetOutNId(e)); }
499  }
500  Sig.Add(Node.GetInDeg());
501  if (--NodeCnt == 0) {
502  for (int i = LastPos; i < Sig.Len(); i++) NodeCnt += Sig[i];
503  Sig.QSort(LastPos, Sig.Len()-1, false);
504  LastPos = Sig.Len();
505  }
506  }
507 }
508 
509 // tree signature -- for each level we sort the node in-degrees and concatenate them into a vector
510 template <class PGraph>
511 void GetTreeSig(const PGraph& Graph, const int& RootNId, TIntV& Sig, TIntPrV& NodeMap) {
512  CAssert(HasGraphFlag(typename PGraph::TObj, gfDirected));
513  NodeMap.Gen(Graph->GetNodes(), 0);
514  Sig.Gen(Graph->GetNodes(), 0);
515  TSnapQueue<int> NIdQ(Graph->GetNodes());
516  NIdQ.Push(RootNId);
517  int LastPos = 0, NodeCnt = 1;
518  while (! NIdQ.Empty()) {
519  const typename PGraph::TObj::TNodeI Node = Graph->GetNI(NIdQ.Top()); NIdQ.Pop();
520  IAssert(Node.GetInDeg()==0 || Node.GetOutDeg()==0); // child points or is-pointed to by the parent
521  if (Node.GetInDeg() != 0) {
522  for (int e = 0; e < Node.GetInDeg(); e++) {
523  NIdQ.Push(Node.GetInNId(e)); }
524  NodeMap.Add(TIntPr(Node.GetInDeg(), Node.GetId()));
525  } else if (Node.GetOutDeg() != 0) {
526  for (int e = 0; e < Node.GetOutDeg(); e++) {
527  NIdQ.Push(Node.GetOutNId(e)); }
528  NodeMap.Add(TIntPr(Node.GetOutDeg(), Node.GetId()));
529  }
530  if (--NodeCnt == 0) {
531  for (int i = LastPos; i < NodeMap.Len(); i++) {
532  NodeCnt += NodeMap[i].Val1; }
533  NodeMap.QSort(LastPos, NodeMap.Len()-1, false);
534  LastPos = NodeMap.Len();
535  }
536  }
537  for (int i = 0; i < NodeMap.Len(); i++) {
538  Sig.Add(NodeMap[i].Val1); // degree dignature
539  NodeMap[i].Val1 = NodeMap[i].Val2;
540  NodeMap[i].Val2 = i;
541  }
542 }
543 
544 }; // namespace TSnap
void Clr(const bool &DoDel=true, const int &NoDelLim=-1)
Definition: shash.h:1243
#define IAssert(Cond)
Definition: bd.h:262
TPair< TInt, TInt > TIntPr
Definition: ds.h:83
Main namespace for all the Snap global entities.
Definition: alg.h:1
void GetOutDegCnt(const PGraph &Graph, TIntPrV &DegToCntV)
Returns an out-degree histogram: a set of pairs (out-degree, number of nodes of such out-degree) ...
Definition: alg.h:201
int CntUniqUndirEdges(const PGraph &Graph)
Counts unique undirected edges in the graph Graph. Nodes (u,v) (where u!=v) are connected via an undi...
Definition: alg.h:279
void GetNodeOutDegV(const PGraph &Graph, TIntPrV &NIdOutDegV)
Returns a vector of pairs (node id, node out-degree)
Definition: alg.h:271
void GetDegCnt(const PGraph &Graph, TIntPrV &DegToCntV)
Returns a degree histogram: a set of pairs (degree, number of nodes of such degree) ...
Definition: alg.h:223
void QSort(const TSizeTy &MnLValN, const TSizeTy &MxRValN, const bool &Asc)
Quick sorts the values between positions MnLValN...MxLValN.
Definition: ds.h:1305
TSizeTy Len() const
Returns the number of elements in the vector.
Definition: ds.h:575
void GetNodeInDegV(const PGraph &Graph, TIntPrV &NIdInDegV)
Returns a vector of pairs (node id, node in-degree)
Definition: alg.h:263
int CntUniqDirEdges(const PGraph &Graph)
Counts unique directed edges in the graph Graph. Nodes (u,v) (where u!=v) are connected via a directe...
Definition: alg.h:301
static TRnd Rnd
Definition: dt.h:1146
bool IsKey(const TKey &Key) const
Definition: shash.h:1148
void MakeUnDir(const PGraph &Graph)
Makes the graph undirected. For every edge (u,v) an edge (v,u) is added (if it does not yet exist)...
Definition: alg.h:353
void GetTreeSig(const PGraph &Graph, const int &RootNId, TIntV &Sig)
Definition: alg.h:484
bool Empty() const
Tests whether the vector is empty.
Definition: ds.h:570
bool IsTree(const PGraph &Graph, int &RootNIdX)
Definition: alg.h:460
void DelZeroDegNodes(PGraph &Graph)
Removes all the zero-degree nodes, that isolated nodes, from the graph.
Definition: alg.h:432
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector.
Definition: ds.h:1022
void GetDegSeqV(const PGraph &Graph, TIntV &DegV)
Returns a degree sequence vector.
Definition: alg.h:245
void GetInDegCnt(const PGraph &Graph, TIntPrV &DegToCntV)
Returns an in-degree histogram: a set of pairs (in-degree, number of nodes of such in-degree) ...
Definition: alg.h:179
int CntSelfEdges(const PGraph &Graph)
Counts the number of self-edges in a graph. Edge (u,u) is a self-edge.
Definition: alg.h:334
int GetTreeRootNId(const PGraph &Graph)
Definition: alg.h:80
void Sort(const bool &Asc=true)
Sorts the elements of the vector.
Definition: ds.h:1318
#define HasGraphFlag(TGraph, Flag)
For quick testing of the properties of the graph/network object (see TGraphFlag). ...
Definition: gbase.h:41
int CntNonZNodes(const PGraph &Graph)
Returns the number of nodes with degree greater than 0.
Definition: alg.h:114
int GetMxOutDegNId(const PGraph &Graph)
Returns a randomly chosen node from all the nodes with the maximum out-degree.
Definition: alg.h:167
#define Assert(Cond)
Definition: bd.h:251
int AddKey(const TKey &Key)
Definition: shash.h:1254
static void Do(const PGraph &Graph)
Definition: alg.h:386
int CntEdgesToSet(const PGraph &Graph, const int &NId, const TIntSet &NodeSet)
Returns the number of nodes in NodeSet that have an edge to the node NId.
Definition: alg.h:123
int CntUniqBiDirEdges(const PGraph &Graph)
Counts unique bidirectional edges in the graph Graph. Edge is bidirectional if there exist directed e...
Definition: alg.h:316
TPair< TFlt, TFlt > TFltPr
Definition: ds.h:99
int CntInDegNodes(const PGraph &Graph, const int &NodeInDeg)
Returns the number of nodes with in-degree NodeInDeg.
Definition: alg.h:87
void AddSelfEdges(const PGraph &Graph)
Adds a self-edge to every node in the graph.
Definition: alg.h:369
directed graph (TNGraph, TNEGraph), else graph is undirected TUNGraph
Definition: gbase.h:13
#define CAssert(Cond)
Definition: bd.h:302
int Len() const
Definition: shash.h:1121
int GetMxDegNId(const PGraph &Graph)
Returns a randomly chosen node from all the nodes with the maximum degree.
Definition: alg.h:143
bool IsConnected(const PGraph &Graph)
Tests whether the Graph is (weakly) connected.
Definition: cncom.h:305
void Push(const TVal &Val)
Adds an element at the end of the queue.
Definition: gbase.h:214
Definition: hash.h:97
void DelNodes(PGraph &Graph, const TIntV &NIdV)
Removes nodes with ids stored in NIdV from the graph.
Definition: alg.h:425
#define EAssertR(Cond, MsgStr)
Definition: bd.h:283
static void Do(const PGraph &Graph)
Definition: alg.h:402
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements.
Definition: ds.h:523
int GetUniDevInt(const int &Range=0)
Definition: dt.cpp:39
void Reserve(const TSizeTy &_MxVals)
Reserves enough memory for the vector to store _MxVals elements.
Definition: ds.h:543
void DelDegKNodes(PGraph &Graph, const int &OutDegK, const int &InDegK)
Removes all the node of out-degree OutDegK and all the nodes of in-degree InDegK from the graph...
Definition: alg.h:445
int CntDegNodes(const PGraph &Graph, const int &NodeDeg)
Returns the number of nodes with degree NodeDeg.
Definition: alg.h:105
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element.
Definition: ds.h:602
void DelSelfEdges(const PGraph &Graph)
Removes all the self-edges from the graph.
Definition: alg.h:419
int Len() const
Definition: hash.h:228
TDat & AddDat(const TKey &Key)
Definition: hash.h:238
int GetMxInDegNId(const PGraph &Graph)
Returns a randomly chosen node from all the nodes with the maximum in-degree.
Definition: alg.h:155
PGraph GetUnDir(const PGraph &Graph)
Returs an undirected version of the graph. For every edge (u,v) an edge (v,u) is added (if it does no...
Definition: alg.h:345
const TKey & GetKey(const int &KeyId) const
Definition: hash.h:252
int CntOutDegNodes(const PGraph &Graph, const int &NodeOutDeg)
Returns the number of nodes with out-degree NodeOutDeg.
Definition: alg.h:96