7   for (
int i = 0; i < LeftNodes; i++) { G->AddNode(i, 
true); }
 
    8   for (
int i = 0; i < RightNodes; i++) { G->AddNode(LeftNodes+i, 
false); }
 
    9   IAssertR(Edges <= LeftNodes*RightNodes, 
"Too many edges in the bipartite graph!");
 
   10   for (
int edges = 0; edges < Edges; ) {
 
   12     const int RNId = LeftNodes + Rnd.
GetUniDevInt(RightNodes);
 
   13     if (G->AddEdge(LNId, RNId) != -2) { edges++; } 
 
   22   for (
int i = 0; i < Nodes; i++) {
 
   37   for (
int n = 0; n < Nodes; n++) {
 
   39     if (! (Val >= 1 && Val < Nodes/2)) { n--; 
continue; } 
 
   43   printf(
"%d nodes, %u edges\n", Nodes, DegSum);
 
   44   if (DegSum % 2 == 1) { DegSeqV[0] += 1; }
 
   62   const int Nodes = DegSeqV.
Len();
 
   68   IAssertR(DegSeqV.
IsSorted(
false), 
"DegSeqV must be sorted in descending order.");
 
   70   for (
int node = 0; node < Nodes; node++) {
 
   72     DegH.AddDat(node, DegSeqV[node]);
 
   73     DegSum += DegSeqV[node];
 
   76   while (! DegH.Empty()) {
 
   78     const int NId1 = DegH.GetKey(DegH.GetRndKeyId(Rnd, 0.5));
 
   79     const int NId2 = DegH.GetKey(DegH.GetRndKeyId(Rnd, 0.5));
 
   80     IAssert(DegH.IsKey(NId1) && DegH.IsKey(NId2));
 
   82       if (DegH.GetDat(NId1) == 1) { 
continue; }
 
   85       if (Edge.
Val1==-1) { 
continue; }
 
   89       if (DegH.GetDat(NId1) == 2) { DegH.DelKey(NId1); }
 
   90       else { DegH.GetDat(NId1) -= 2; }
 
   92       if (! Graph.
IsEdge(NId1, NId2)) {
 
   97         if (Edge.
Val1==-1) { 
continue; }
 
  102       if (DegH.GetDat(NId1)==1) { DegH.DelKey(NId1); }
 
  103       else { DegH.GetDat(NId1) -= 1; }
 
  104       if (DegH.GetDat(NId2)==1) { DegH.DelKey(NId2); }
 
  105       else { DegH.GetDat(NId2) -= 1; }
 
  107     if (++
edge % 1000 == 0) {
 
  108       printf(
"\r %dk / %dk", 
edge/1000, DegSum/2000); }
 
  123   const int Nodes = DegSeqV.
Len();
 
  128   int DegSum=0, edges=0;
 
  129   for (
int node = 0; node < Nodes; node++) {
 
  131     for (
int d = 0; d < DegSeqV[node]; d++) { NIdDegV.Add(node); }
 
  132     DegSum += DegSeqV[node];
 
  134   NIdDegV.Shuffle(Rnd);
 
  136   if (DegSum % 2 != 0) {
 
  137     printf(
"Seg seq is odd [%d]: ", DegSeqV.
Len());
 
  138     for (
int d = 0; d < 
TMath::Mn(100, DegSeqV.
Len()); d++) { printf(
"  %d", (
int)DegSeqV[d]); }
 
  142   for (
int c = 0; NIdDegV.Len() > 1; c++) {
 
  145     if (u > v) { 
Swap(u, v); }
 
  146     const int E1 = NIdDegV[u];
 
  147     const int E2 = NIdDegV[v];
 
  148     if (v == NIdDegV.Len()-1) { NIdDegV.DelLast(); } 
 
  149     else { NIdDegV[v] = NIdDegV.Last();  NIdDegV.DelLast(); }
 
  150     if (u == NIdDegV.Len()-1) { NIdDegV.DelLast(); } 
 
  151     else { NIdDegV[u] = NIdDegV.Last();  NIdDegV.DelLast(); }
 
  152     if (E1 == E2 || EdgeH.
IsKey(
TIntPr(E1, E2))) { 
continue; }
 
  156     if (c % (DegSum/100+1) == 0) { printf(
"\r configuration model: iter %d: edges: %d, left: %d", c, edges, NIdDegV.Len()/2); }
 
  169   const int Nodes = OrigGraph->
GetNodes();
 
  170   const int Edges = OrigGraph->
GetEdges();
 
  176   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  179     const int NId = NI.GetId();
 
  180     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  181       if (NId <= NI.GetOutNId(e)) { 
continue; }
 
  188   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  191     if (keyId1 == keyId2) { skip++; 
continue; }
 
  192     const TIntPr& E1 = EdgeSet[keyId1];
 
  193     const TIntPr& E2 = EdgeSet[keyId2];
 
  195     if (NewE1.Val1 > NewE1.Val2) { 
Swap(NewE1.Val1, NewE1.Val2); }
 
  197     if (NewE1!=NewE2 && NewE1.
Val1!=NewE1.Val2 && NewE2.
Val1!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  202     if (swps % Edges == 0) {
 
  203       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  204       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  207   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  208   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  209     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  220   const int Nodes = OrigGraph->GetNodes();
 
  221   const int Edges = OrigGraph->GetEdges();
 
  227   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  229   for (
TNGraph::TNodeI NI = OrigGraph->BegNI(); NI < OrigGraph->EndNI(); NI++) {
 
  230     const int NId = NI.GetId();
 
  231     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  237   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  240     if (keyId1 == keyId2) { skip++; 
continue; }
 
  241     const TIntPr& E1 = EdgeSet[keyId1];
 
  242     const TIntPr& E2 = EdgeSet[keyId2];
 
  244     if (NewE1.Val1!=NewE1.Val2 && NewE2.
Val1!=NewE2.
Val2 && NewE1.Val1!=NewE2.
Val1 && NewE1.Val2!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  249     if (swps % Edges == 0) {
 
  250       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  251       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  254   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  255   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  256     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  267   const int Nodes = OrigGraph->GetNodes();
 
  268   const int Edges = OrigGraph->GetEdges();
 
  274   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  276   for (
TBPGraph::TNodeI NI = OrigGraph->BegLNI(); NI < OrigGraph->EndLNI(); NI++) {
 
  277     const int NId = NI.GetId();
 
  278     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  280     Graph.
AddNode(NI.GetId(), 
true); } 
 
  281   for (
TBPGraph::TNodeI NI = OrigGraph->BegRNI(); NI < OrigGraph->EndRNI(); NI++) {
 
  282     Graph.
AddNode(NI.GetId(), 
false); } 
 
  286   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  289     if (keyId1 == keyId2) { skip++; 
continue; }
 
  290     const TIntPr& E1 = EdgeSet[keyId1];
 
  291     const TIntPr& E2 = EdgeSet[keyId2];
 
  293     if (NewE1!=NewE2 && NewE1.
Val1!=NewE1.Val2 && NewE2.
Val1!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  298     if (swps % Edges == 0) {
 
  299       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  300       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  303   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  304   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  305     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  316   Graph.
Reserve(Nodes, NodeOutDeg*Nodes);
 
  317   TIntV NIdV(NodeOutDeg*Nodes, 0);
 
  323   for (
int node = 2; node < Nodes; node++) {
 
  325     while (NodeSet.
Len() < NodeOutDeg && NodeSet.
Len() < node) {
 
  329     for (
int i = 0; i < NodeSet.
Len(); i++) {
 
  332       NIdV.
Add(NodeSet[i]);
 
  344 namespace TSnapDetail {
 
  347   if (ValV.
Len() != Dim) { ValV.
Gen(Dim); }
 
  349   for (
int i = 0; i < Dim; i++) {
 
  352   Length = 1.0 / sqrt(Length);
 
  353   for (
int i = 0; i < Dim; i++) {
 
  370   for (
int i = 0; i < Nodes; i++) {
 
  372     PointV.
Add(
TFltTr(Rad*ValV[0], Rad*ValV[1], Rad*ValV[2]));
 
  374   const double R2 = 
TMath::Sqr(log((
double) Nodes) / (pow((
double) Nodes, 0.5-Beta)));
 
  377   for (
int t = 0; t < Nodes; t++) {
 
  379     const TFltTr& P1 = PointV[pid];
 
  383     DegV.
Clr(
false);  NIdV.
Clr(
false);  SumDeg=0;
 
  384     for (
int p = 0; p < t; p++) {
 
  385       const TFltTr& P2 = PointV[p];
 
  389         SumDeg += DegV.
Last();
 
  393     for (
int m = 0; m < OutDeg; m++) {
 
  395       int sum = 0, dst = -1;
 
  396       for (
int s = 0; s < DegV.
Len(); s++) {
 
  398         if (rnd < sum) { dst=s;  
break; }
 
  403         NIdV.
Del(dst);  DegV.
Del(dst);
 
  418   IAssertR(Nodes > NodeOutDeg, 
TStr::Fmt(
"Insufficient nodes for out degree, %d!", NodeOutDeg));
 
  419   for (
int node = 0; node < Nodes; node++) {
 
  420     const int src = node;
 
  422       int dst = (node+
edge) % Nodes;      
 
  425         while (dst == src || EdgeSet.
IsKey(
TIntPr(src, dst))) {
 
  435   for (node = 0; node < Nodes; node++) {
 
  460   const int startNId = Graph.
AddNode();
 
  461   Graph.
AddEdge(startNId, startNId);
 
  462   for (
int n = 1; n < Nodes; n++) {
 
  464     const int NId = Graph.
AddNode();
 
  481 PNGraph GenRMat(
const int& Nodes, 
const int& Edges, 
const double& A, 
const double& B, 
const double& C, 
TRnd& Rnd) {
 
  486   int rngX, rngY, offX, offY;
 
  487   int Depth=0, Collisions=0, Cnt=0, PctDone=0;
 
  488   const int EdgeGap = Edges / 100 + 1;
 
  490   TVec<double> sumA(128, 0), sumAB(128, 0), sumAC(128, 0), sumABC(128, 0);  
 
  491   for (
int i = 0; i < 128; i++) {
 
  492     const double a = A * (Rnd.
GetUniDev() + 0.5);
 
  493     const double b = B * (Rnd.
GetUniDev() + 0.5);
 
  494     const double c = C * (Rnd.
GetUniDev() + 0.5);
 
  495     const double d = (1.0 - (A+B+C)) * (Rnd.
GetUniDev() + 0.5);
 
  496     const double abcd = a+b+c+d;
 
  498     sumAB.Add((a+b) / abcd);
 
  499     sumAC.Add((a+c) / abcd);
 
  500     sumABC.
Add((a+b+c) / abcd);
 
  503   for (
int node = 0; node < Nodes; node++) {
 
  507   for (
int edge = 0; 
edge < Edges; ) {
 
  508     rngX = Nodes;  rngY = Nodes;  offX = 0;  offY = 0;
 
  511     while (rngX > 1 || rngY > 1) {
 
  513       if (rngX>1 && rngY>1) {
 
  514         if (RndProb < sumA[Depth]) { rngX/=2; rngY/=2; }
 
  515         else if (RndProb < sumAB[Depth]) { offX+=rngX/2;  rngX-=rngX/2;  rngY/=2; }
 
  516         else if (RndProb < sumABC[Depth]) { offY+=rngY/2;  rngX/=2;  rngY-=rngY/2; }
 
  517         else { offX+=rngX/2;  offY+=rngY/2;  rngX-=rngX/2;  rngY-=rngY/2; }
 
  520         if (RndProb < sumAC[Depth]) { rngX/=2; rngY/=2; }
 
  521         else { offX+=rngX/2;  rngX-=rngX/2;  rngY/=2; }
 
  524         if (RndProb < sumAB[Depth]) { rngX/=2; rngY/=2; }
 
  525         else { offY+=rngY/2;  rngX/=2;  rngY-=rngY/2; }
 
  530     const int NId1 = offX;
 
  531     const int NId2 = offY;
 
  532     if (NId1 != NId2 && ! Graph.
IsEdge(NId1, NId2)) {
 
  534       if (++Cnt > EdgeGap) {
 
  535         Cnt=0;  printf(
"\r  %d%% edges", ++PctDone); }
 
  540   printf(
"\r  RMat: nodes:%d, edges:%d, Iterations:%d, Collisions:%d (%.1f%%).\n", Nodes, Edges,
 
  541     Edges+Collisions, Collisions, 100*Collisions/
double(Edges+Collisions));
 
  551   return GenRMat(75888, 508837, 0.550, 0.228, 0.212);
 
void Clr(const bool &DoDel=true, const int &NoDelLim=-1)
 
static const T & Mn(const T &LVal, const T &RVal)
 
TPair< TInt, TInt > TIntPr
 
Main namespace for all the Snap global entities. 
 
void Reserve(const int &Nodes, const int &Edges)
Reserves memory for a biparite graph of Nodes nodes and Edges edges. 
 
#define IAssertR(Cond, Reason)
 
PNGraph GenRMatEpinions()
Generates a R-Mat graph, with a synthetic copy of the Epinions social network. 
 
void DelKeyId(const int &KeyId)
 
void Del(const TSizeTy &ValN)
Removes the element at position ValN. 
 
PUNGraph GenRewire(const PUNGraph &OrigGraph, const int &NSwitch, TRnd &Rnd)
Rewire a random undirected graph. Keeps node degrees the same, but randomly rewires the edges...
 
PNGraph GenRMat(const int &Nodes, const int &Edges, const double &A, const double &B, const double &C, TRnd &Rnd)
Generates a R-MAT graph using recursive descent into a 2x2 matrix [A,B; C, 1-(A+B+C)]. 
 
static PNGraph New()
Static constructor that returns a pointer to the graph. Call: PNGraph Graph = TNGraph::New(). 
 
TNodeI GetNI(const int &NId) const 
Returns an iterator referring to the node of ID NId in the graph. 
 
Node iterator. Only forward iteration (operator++) is supported. 
 
int AddNode(int NId=-1)
Adds a node of ID NId to the graph. 
 
int GetEdges() const 
Returns the number of edges in the graph. 
 
TSizeTy Len() const 
Returns the number of elements in the vector. 
 
Node iterator. Only forward iteration (operator++) is supported. 
 
int AddNode(int NId=-1, const bool &LeftNode=true)
Adds a node of ID NId to the graph. 
 
int AddNode(int NId=-1)
Adds a node of ID NId to the graph. 
 
PNGraph GenCopyModel(const int &Nodes, const double &Beta, TRnd &Rnd)
Generates a random scale-free network using the Copying Model. 
 
static double Sqr(const double &x)
 
PBPGraph GenRndBipart(const int &LeftNodes, const int &RightNodes, const int &Edges, TRnd &Rnd)
Generates a random bipartite graph. 
 
bool IsKey(const TKey &Key) const 
 
int GetNodes() const 
Returns the number of nodes in the graph. 
 
int GetDeg() const 
Returns degree of the current node. 
 
void GetSphereDev(const int &Dim, TRnd &Rnd, TFltV &ValV)
Sample random point from the surface of a Dim-dimensional unit sphere. 
 
PUNGraph GenDegSeq(const TIntV &DegSeqV, TRnd &Rnd)
Generates a random graph with exact degree sequence. 
 
TIntPr GetRndEdgeNonAdjNode(const PGraph &Graph, int NId1, int NId2)
Returns a random edge in a graph Graph where the edge does not touch nodes NId1 and NId2...
 
void Clr(const bool &DoDel=true, const TSizeTy &NoDelLim=-1)
Clears the contents of the vector. 
 
void GetDegSeqV(const PGraph &Graph, TIntV &DegV)
Returns a degree sequence vector. 
 
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. 
 
PUNGraph GenRndDegK(const int &Nodes, const int &NodeDeg, const int &NSwitch, TRnd &Rnd)
Generates a random graph where each node has degree exactly NodeDeg. 
 
bool IsEdge(const int &SrcNId, const int &DstNId, const bool &IsDir=true) const 
Tests whether an edge from node IDs SrcNId to DstNId exists in the graph. 
 
void Reserve(const int &Nodes, const int &Edges)
Reserves memory for a graph of Nodes nodes and Edges edges. 
 
int GetRndNId(TRnd &Rnd=TInt::Rnd)
Returns an ID of a random node in the graph. 
 
static double Round(const double &Val)
 
TNodeI GetNI(const int &NId) const 
Returns an iterator referring to the node of ID NId in the graph. 
 
static PUNGraph New()
Static constructor that returns a pointer to the graph. Call: PUNGraph Graph = TUNGraph::New(). 
 
int AddKey(const TKey &Key)
 
const TVal & Last() const 
Returns a reference to the last element of the vector. 
 
PNGraph GenForestFire(const int &Nodes, const double &FwdProb, const double &BckProb)
Generates a random Forest Fire, directed graph with given probabilities. 
 
void DelEdge(const int &SrcNId, const int &DstNId)
Deletes an edge between node IDs SrcNId and DstNId from the graph. 
 
TTriple< TFlt, TFlt, TFlt > TFltTr
 
PUNGraph GenConfModel(const TIntV &DegSeqV, TRnd &Rnd)
Generates a random undirect graph with a given degree sequence. 
 
PUNGraph GenPrefAttach(const int &Nodes, const int &NodeOutDeg, TRnd &Rnd)
Generates a power-law degree distribution using Barabasi-Albert model of scale-free graphs...
 
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph. 
 
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge between node IDs SrcNId and DstNId to the graph. 
 
int GetRndKeyId(TRnd &Rnd) const 
 
int AddEdge(const int &LeftNId, const int &RightNId)
Adds an edge between a node LeftNId on the left and a node RightNId on the right side of the bipartit...
 
int GetOutDeg() const 
Returns out-degree of the current node. 
 
PUNGraph GenSmallWorld(const int &Nodes, const int &NodeOutDeg, const double &RewireProb, TRnd &Rnd)
Generates a randomly small-world graph using the Watts-Strogatz model. 
 
static TStr Fmt(const char *FmtStr,...)
 
bool IsSorted(const bool &Asc=true) const 
Checks whether the vector is sorted in ascending (if Asc=true) or descending (if Asc=false) order...
 
Node iterator. Only forward iteration (operator++) is supported. 
 
void Defrag(const bool &OnlyNodeLinks=false)
Defragments the graph. 
 
TNodeI EndNI() const 
Returns an iterator referring to the past-the-end node in the graph. 
 
PUNGraph GenGeoPrefAttach(const int &Nodes, const int &OutDeg, const double &Beta, TRnd &Rnd)
Generates a random scale-free graph using the Geometric Preferential model. 
 
void Reserve(const int &Nodes, const int &Edges)
Reserves memory for a graph of Nodes nodes and Edges edges. 
 
static PBPGraph New()
Static constructor that returns a pointer to the graph. Call: PBPGraph BPGraph = TBPGraph::New();. 
 
bool IsNode(const int &NId) const 
Tests whether ID NId is a node. 
 
void Reverse()
Reverses the order of the elements in the vector. 
 
void Gen(const TSizeTy &_Vals)
Constructs a vector (an array) of _Vals elements. 
 
int GetUniDevInt(const int &Range=0)
 
PUNGraph GenRndPowerLaw(const int &Nodes, const double &PowerExp, const bool &ConfModel, TRnd &Rnd)
Generates a random scale-free graph with power-law degree distribution. 
 
const char * GetStr() const 
 
bool IsEdge(const int &SrcNId, const int &DstNId) const 
Tests whether an edge between node IDs SrcNId and DstNId exists in the graph. 
 
TSizeTy Add()
Adds a new element at the end of the vector, after its current last element. 
 
static PNGraph GenGraph(const int &Nodes, const double &FwdProb, const double &BckProb)
 
TNodeI BegNI() const 
Returns an iterator referring to the first node in the graph. 
 
int GetOutNId(const int &NodeN) const 
Returns ID of NodeN-th out-node (the node the current node points to). 
 
double GetPowerDev(const double &AlphaSlope)
 
void Swap(TRec &Rec1, TRec &Rec2)
 
Vector is a sequence TVal objects representing an array that can change in size.