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; }
 
   59   const int Nodes = DegSeqV.
Len();
 
   65   IAssertR(DegSeqV.
IsSorted(
false), 
"DegSeqV must be sorted in descending order.");
 
   67   for (
int node = 0; node < Nodes; node++) {
 
   69     DegH.AddDat(node, DegSeqV[node]);
 
   70     DegSum += DegSeqV[node];
 
   73   while (! DegH.Empty()) {
 
   75     const int NId1 = DegH.GetKey(DegH.GetRndKeyId(
TInt::Rnd, 0.5));
 
   76     const int NId2 = DegH.GetKey(DegH.GetRndKeyId(
TInt::Rnd, 0.5));
 
   77     IAssert(DegH.IsKey(NId1) && DegH.IsKey(NId2));
 
   79       if (DegH.GetDat(NId1) == 1) { 
continue; }
 
   82       if (Edge.
Val1==-1) { 
continue; }
 
   86       if (DegH.GetDat(NId1) == 2) { DegH.DelKey(NId1); }
 
   87       else { DegH.GetDat(NId1) -= 2; }
 
   89       if (! Graph.
IsEdge(NId1, NId2)) {
 
   94         if (Edge.
Val1==-1) {
continue; }
 
   99       if (DegH.GetDat(NId1)==1) { DegH.DelKey(NId1); }
 
  100       else { DegH.GetDat(NId1) -= 1; }
 
  101       if (DegH.GetDat(NId2)==1) { DegH.DelKey(NId2); }
 
  102       else { DegH.GetDat(NId2) -= 1; }
 
  104     if (++edge % 1000 == 0) {
 
  105       printf(
"\r %dk / %dk", edge/1000, DegSum/2000); }
 
  120   const int Nodes = DegSeqV.
Len();
 
  125   int DegSum=0, edges=0;
 
  126   for (
int node = 0; node < Nodes; node++) {
 
  128     for (
int d = 0; d < DegSeqV[node]; d++) { NIdDegV.Add(node); }
 
  129     DegSum += DegSeqV[node];
 
  131   NIdDegV.Shuffle(Rnd);
 
  133   if (DegSum % 2 != 0) {
 
  134     printf(
"Seg seq is odd [%d]: ", DegSeqV.
Len());
 
  135     for (
int d = 0; d < 
TMath::Mn(100, DegSeqV.
Len()); d++) { printf(
"  %d", (
int)DegSeqV[d]); }
 
  139   for (
int c = 0; NIdDegV.Len() > 1; c++) {
 
  142     if (u > v) { 
Swap(u, v); }
 
  143     const int E1 = NIdDegV[u];
 
  144     const int E2 = NIdDegV[v];
 
  145     if (v == NIdDegV.Len()-1) { NIdDegV.DelLast(); } 
 
  146     else { NIdDegV[v] = NIdDegV.Last();  NIdDegV.DelLast(); }
 
  147     if (u == NIdDegV.Len()-1) { NIdDegV.DelLast(); } 
 
  148     else { NIdDegV[u] = NIdDegV.Last();  NIdDegV.DelLast(); }
 
  149     if (E1 == E2 || EdgeH.
IsKey(
TIntPr(E1, E2))) { 
continue; }
 
  153     if (c % (DegSum/100+1) == 0) { printf(
"\r configuration model: iter %d: edges: %d, left: %d", c, edges, NIdDegV.Len()/2); }
 
  166   const int Nodes = OrigGraph->GetNodes();
 
  167   const int Edges = OrigGraph->GetEdges();
 
  173   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  175   for (
TUNGraph::TNodeI NI = OrigGraph->BegNI(); NI < OrigGraph->EndNI(); NI++) {
 
  176     const int NId = NI.GetId();
 
  177     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  178       if (NId <= NI.GetOutNId(e)) { 
continue; }
 
  185   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  188     if (keyId1 == keyId2) { skip++; 
continue; }
 
  189     const TIntPr& E1 = EdgeSet[keyId1];
 
  190     const TIntPr& E2 = EdgeSet[keyId2];
 
  192     if (NewE1.Val1 > NewE1.Val2) { 
Swap(NewE1.Val1, NewE1.Val2); }
 
  194     if (NewE1!=NewE2 && NewE1.
Val1!=NewE1.Val2 && NewE2.
Val1!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  199     if (swps % Edges == 0) {
 
  200       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  201       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  204   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  205   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  206     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  217   const int Nodes = OrigGraph->
GetNodes();
 
  218   const int Edges = OrigGraph->
GetEdges();
 
  224   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  227     const int NId = NI.GetId();
 
  228     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  234   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  237     if (keyId1 == keyId2) { skip++; 
continue; }
 
  238     const TIntPr& E1 = EdgeSet[keyId1];
 
  239     const TIntPr& E2 = EdgeSet[keyId2];
 
  241     if (NewE1.Val1!=NewE2.
Val1 && NewE1.Val2!=NewE2.
Val1 && NewE1.Val2!=NewE2.
Val1 && NewE1.Val2!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  246     if (swps % Edges == 0) {
 
  247       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  248       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  251   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  252   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  253     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  264   const int Nodes = OrigGraph->GetNodes();
 
  265   const int Edges = OrigGraph->GetEdges();
 
  271   printf(
"Randomizing edges (%d, %d)...\n", Nodes, Edges);
 
  273   for (
TBPGraph::TNodeI NI = OrigGraph->BegLNI(); NI < OrigGraph->EndLNI(); NI++) {
 
  274     const int NId = NI.GetId();
 
  275     for (
int e = 0; e < NI.GetOutDeg(); e++) {
 
  277     Graph.
AddNode(NI.GetId(), 
true); } 
 
  278   for (
TBPGraph::TNodeI NI = OrigGraph->BegRNI(); NI < OrigGraph->EndRNI(); NI++) {
 
  279     Graph.
AddNode(NI.GetId(), 
false); } 
 
  283   for (
uint swps = 0; swps < 2*
uint(Edges)*
uint(NSwitch); swps++) {
 
  286     if (keyId1 == keyId2) { skip++; 
continue; }
 
  287     const TIntPr& E1 = EdgeSet[keyId1];
 
  288     const TIntPr& E2 = EdgeSet[keyId2];
 
  290     if (NewE1!=NewE2 && NewE1.
Val1!=NewE1.Val2 && NewE2.
Val1!=NewE2.
Val2 && ! EdgeSet.
IsKey(NewE1) && ! EdgeSet.
IsKey(NewE2)) {
 
  295     if (swps % Edges == 0) {
 
  296       printf(
"\r  %uk/%uk: %uk skip [%s]", swps/1000u, 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  297       if (ExeTm.
GetSecs() > 2*3600) { printf(
" *** Time limit!\n"); 
break; } 
 
  300   printf(
"\r  total %uk switchings attempted, %uk skiped  [%s]\n", 2*
uint(Edges)*
uint(NSwitch)/1000u, skip/1000u, ExeTm.
GetStr());
 
  301   for (
int e = 0; e < EdgeSet.
Len(); e++) {
 
  302     Graph.
AddEdge(EdgeSet[e].Val1, EdgeSet[e].Val2); }
 
  313   Graph.
Reserve(Nodes, NodeOutDeg*Nodes);
 
  314   TIntV NIdV(NodeOutDeg*Nodes, 0);
 
  320   for (
int node = 2; node < Nodes; node++) {
 
  322     while (NodeSet.
Len() < NodeOutDeg && NodeSet.
Len() < node) {
 
  326     for (
int i = 0; i < NodeSet.
Len(); i++) {
 
  329       NIdV.
Add(NodeSet[i]);
 
  336   TIntV DegSeqV(G->GetNodes(), 0);
 
  341 namespace TSnapDetail {
 
  344   if (ValV.
Len() != Dim) { ValV.
Gen(Dim); }
 
  346   for (
int i = 0; i < Dim; i++) {
 
  349   Length = 1.0 / sqrt(Length);
 
  350   for (
int i = 0; i < Dim; i++) {
 
  367   for (
int i = 0; i < Nodes; i++) {
 
  369     PointV.
Add(
TFltTr(Rad*ValV[0], Rad*ValV[1], Rad*ValV[2]));
 
  371   const double R2 = 
TMath::Sqr(log((
double) Nodes) / (pow((
double) Nodes, 0.5-Beta)));
 
  374   for (
int t = 0; t < Nodes; t++) {
 
  376     const TFltTr& P1 = PointV[pid];
 
  378     if (! G->IsNode(pid)) { G->AddNode(pid); }
 
  380     DegV.
Clr(
false);  NIdV.
Clr(
false);  SumDeg=0;
 
  381     for (
int p = 0; p < t; p++) {
 
  382       const TFltTr& P2 = PointV[p];
 
  385         DegV.
Add(G->GetNI(p).GetDeg()+1);
 
  386         SumDeg += DegV.
Last();
 
  390     for (
int m = 0; m < OutDeg; m++) {
 
  392       int sum = 0, dst = -1;
 
  393       for (
int s = 0; s < DegV.
Len(); s++) {
 
  395         if (rnd < sum) { dst=s;  
break; }
 
  398         G->AddEdge(pid, NIdV[dst]);
 
  400         NIdV.
Del(dst);  DegV.
Del(dst);
 
  415   IAssertR(Nodes > NodeOutDeg, 
TStr::Fmt(
"Insufficient nodes for out degree, %d!", NodeOutDeg));
 
  416   for (
int node = 0; node < Nodes; node++) {
 
  417     const int src = node;
 
  418     for (
int edge = 1; edge <= NodeOutDeg; edge++) {
 
  419       int dst = (node+edge) % Nodes;      
 
  422         while (dst == src || EdgeSet.
IsKey(
TIntPr(src, dst))) {
 
  432   for (node = 0; node < Nodes; node++) {
 
  435   for (
int edge = 0; edge < EdgeSet.
Len(); edge++) {
 
  436     Graph.
AddEdge(EdgeSet[edge].Val1, EdgeSet[edge].Val2);
 
  457   const int startNId = Graph.
AddNode();
 
  458   Graph.
AddEdge(startNId, startNId);
 
  459   for (
int n = 1; n < Nodes; n++) {
 
  461     const int NId = Graph.
AddNode();
 
  478 PNGraph GenRMat(
const int& Nodes, 
const int& Edges, 
const double& A, 
const double& B, 
const double& C, 
TRnd& Rnd) {
 
  483   int rngX, rngY, offX, offY;
 
  484   int Depth=0, Collisions=0, Cnt=0, PctDone=0;
 
  485   const int EdgeGap = Edges / 100 + 1;
 
  487   TVec<double> sumA(128, 0), sumAB(128, 0), sumAC(128, 0), sumABC(128, 0);  
 
  488   for (
int i = 0; i < 128; i++) {
 
  489     const double a = A * (Rnd.
GetUniDev() + 0.5);
 
  490     const double b = B * (Rnd.
GetUniDev() + 0.5);
 
  491     const double c = C * (Rnd.
GetUniDev() + 0.5);
 
  492     const double d = (1.0 - (A+B+C)) * (Rnd.
GetUniDev() + 0.5);
 
  493     const double abcd = a+b+c+d;
 
  495     sumAB.Add((a+b) / abcd);
 
  496     sumAC.Add((a+c) / abcd);
 
  497     sumABC.
Add((a+b+c) / abcd);
 
  500   for (
int node = 0; node < Nodes; node++) {
 
  504   for (
int edge = 0; edge < Edges; ) {
 
  505     rngX = Nodes;  rngY = Nodes;  offX = 0;  offY = 0;
 
  508     while (rngX > 1 || rngY > 1) {
 
  510       if (rngX>1 && rngY>1) {
 
  511         if (RndProb < sumA[Depth]) { rngX/=2; rngY/=2; }
 
  512         else if (RndProb < sumAB[Depth]) { offX+=rngX/2;  rngX-=rngX/2;  rngY/=2; }
 
  513         else if (RndProb < sumABC[Depth]) { offY+=rngY/2;  rngX/=2;  rngY-=rngY/2; }
 
  514         else { offX+=rngX/2;  offY+=rngY/2;  rngX-=rngX/2;  rngY-=rngY/2; }
 
  517         if (RndProb < sumAC[Depth]) { rngX/=2; rngY/=2; }
 
  518         else { offX+=rngX/2;  rngX-=rngX/2;  rngY/=2; }
 
  521         if (RndProb < sumAB[Depth]) { rngX/=2; rngY/=2; }
 
  522         else { offY+=rngY/2;  rngX/=2;  rngY-=rngY/2; }
 
  527     const int NId1 = offX;
 
  528     const int NId2 = offY;
 
  529     if (NId1 != NId2 && ! Graph.
IsEdge(NId1, NId2)) {
 
  531       if (++Cnt > EdgeGap) {
 
  532         Cnt=0;  printf(
"\r  %d%% edges", ++PctDone); }
 
  537   printf(
"\r  RMat: nodes:%d, edges:%d, Iterations:%d, Collisions:%d (%.1f%%).\n", Nodes, Edges,
 
  538     Edges+Collisions, Collisions, 100*Collisions/
double(Edges+Collisions));
 
  548   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
 
void Reserve(const int &Nodes, const int &Edges)
Reserves memory for a biparite graph of Nodes nodes and Edges edges. 
 
#define IAssertR(Cond, Reason)
 
TNodeI BegNI() const 
Returns an iterator referring to the first node in the graph. 
 
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. 
 
int GetEdges() const 
Returns the number of edges 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. 
 
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 GetNodes() const 
Returns the number of nodes in 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 
 
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. 
 
int AddEdge(const int &SrcNId, const int &DstNId)
Adds an edge from node IDs 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)
 
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...
 
TNodeI EndNI() const 
Returns an iterator referring to the past-the-end node in the graph. 
 
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. 
 
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();. 
 
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)
 
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)