SNAP Library 2.1, User Reference  2013-09-25 10:47:25
SNAP, a general purpose, high performance system for analysis and manipulation of large networks
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
ggen.h
Go to the documentation of this file.
00001 // TODO ROK, Jure included basic documentation, finalize reference doc
00002 
00004 // Graph Generators
00005 namespace TSnap {
00006 
00008 // Deterministic graphs
00010 template <class PGraph> PGraph GenGrid(const int& Rows, const int& Cols, const bool& IsDir=true);
00012 template <class PGraph> PGraph GenStar(const int& Nodes, const bool& IsDir=true);
00014 template <class PGraph> PGraph GenCircle(const int& Nodes, const int& NodeOutDeg=1, const bool& IsDir=true);
00016 template <class PGraph> PGraph GenFull(const int& Nodes);
00018 template <class PGraph> PGraph GenTree(const int& Fanout, const int& Levels, const bool& IsDir=true, const bool& ChildPointsToParent=true);
00020 template <class PGraph> PGraph GenBaraHierar(const int& Levels, const bool& IsDir=true);
00021 
00023 // Random graphs
00024 
00026 template <class PGraph> PGraph GenRndGnm(const int& Nodes, const int& Edges, const bool& IsDir=true, TRnd& Rnd=TInt::Rnd);
00028 PBPGraph GenRndBipart(const int& LeftNodes, const int& RightNodes, const int& Edges, TRnd& Rnd=TInt::Rnd);
00030 PUNGraph GenRndDegK(const int& Nodes, const int& NodeDeg, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00032 PUNGraph GenRndPowerLaw(const int& Nodes, const double& PowerExp, const bool& ConfModel=true, TRnd& Rnd=TInt::Rnd);
00034 PUNGraph GenDegSeq(const TIntV& DegSeqV, TRnd& Rnd=TInt::Rnd);
00036 PUNGraph GenPrefAttach(const int& Nodes, const int& NodeOutDeg, TRnd& Rnd=TInt::Rnd);
00038 PUNGraph GenGeoPrefAttach(const int& Nodes, const int& OutDeg, const double& Beta, TRnd& Rnd=TInt::Rnd);
00040 PUNGraph GenSmallWorld(const int& Nodes, const int& NodeOutDeg, const double& RewireProb, TRnd& Rnd=TInt::Rnd);
00042 PUNGraph GenConfModel(const TIntV& DegSeqV, TRnd& Rnd=TInt::Rnd);
00044 PNGraph GenForestFire(const int& Nodes, const double& FwdProb, const double& BckProb);
00046 PNGraph GenCopyModel(const int& Nodes, const double& Beta, TRnd& Rnd=TInt::Rnd);
00048 PNGraph GenRMat(const int& Nodes, const int& Edges, const double& A, const double& B, const double& C, TRnd& Rnd=TInt::Rnd);
00050 PNGraph GenRMatEpinions();
00051 
00052   
00054 PUNGraph GenRewire(const PUNGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00056 PNGraph  GenRewire(const PNGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00058 PBPGraph GenRewire(const PBPGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00060 PUNGraph GenConfModel(const PUNGraph& G);
00061   
00063 // Implementation
00064 template <class PGraph>
00065 PGraph GenGrid(const int& Rows, const int& Cols, const bool& IsDir) {
00066   PGraph GraphPt = PGraph::New();
00067   typename PGraph::TObj& Graph = *GraphPt;
00068   Graph.Reserve(Rows*Cols, 4*Rows*Cols);
00069   int node, r, c;
00070   for (node = 0; node < Rows * Cols; node++) {
00071     Graph.AddNode(node); }
00072   for (r = 0; r < Rows; r++) {
00073     for (c = 0; c < Cols; c++) {
00074       const int nodeId = Cols*r + c;
00075       if (r < Rows-1) { // bottom node
00076         Graph.AddEdge(nodeId, nodeId+Cols); 
00077         if (Graph.HasFlag(gfDirected) && ! IsDir) { 
00078           Graph.AddEdge(nodeId+Cols-1, nodeId); }
00079       }
00080       if (c < Cols-1) { // right node
00081         Graph.AddEdge(nodeId, nodeId+1); 
00082         if (Graph.HasFlag(gfDirected) && ! IsDir) { 
00083           Graph.AddEdge(nodeId+1, nodeId); }
00084       }
00085     }
00086   }
00087   return GraphPt;
00088 }
00089 
00090 template <class PGraph>
00091 PGraph GenStar(const int& Nodes, const bool& IsDir) {
00092   PGraph Graph = PGraph::TObj::New();
00093   Graph->Reserve(Nodes, Nodes);
00094   Graph->AddNode(0);
00095   for (int n = 1; n < Nodes; n++) {
00096     Graph->AddNode(n);
00097     Graph->AddEdge(0, n);
00098     if (Graph->HasFlag(gfDirected) && ! IsDir) { Graph->AddEdge(n, 0); }
00099   }
00100   return Graph;
00101 }
00102 
00103 template <class PGraph>
00104 PGraph GenCircle(const int& Nodes, const int& NodeOutDeg, const bool& IsDir) {
00105   PGraph Graph = PGraph::TObj::New();
00106   Graph->Reserve(Nodes, Nodes*NodeOutDeg);
00107   for (int n = 0; n < Nodes; n++) {
00108     Graph->AddNode(n); }
00109   for (int n = 0; n < Nodes; n++) {
00110     for (int x = 0; x < NodeOutDeg; x++) {
00111       Graph->AddEdge(n, (n+x+1) % Nodes);
00112       if (Graph->HasFlag(gfDirected) && ! IsDir) { Graph->AddEdge((n+x) % Nodes, n); }
00113     }
00114   }
00115   return Graph;
00116 }
00117 
00118 template <class PGraph>
00119 PGraph GenFull(const int& Nodes) {
00120   PGraph Graph = PGraph::TObj::New();
00121   Graph->Reserve(Nodes, Nodes*Nodes);
00122   for (int n = 0; n < Nodes; n++) {
00123     Graph->AddNode(n); }
00124   for (int n1 = 0; n1 < Nodes; n1++) {
00125     for (int n2 = 0; n2 < Nodes; n2++) {
00126       if (n1 != n2) { Graph->AddEdge(n1, n2); }
00127     }
00128   }
00129   return Graph;
00130 }
00131 
00132 template <class PGraph>
00133 PGraph GenTree(const int& Fanout, const int& Levels, const bool& IsDir, const bool& ChildPointsToParent) {
00134   const int Nodes = (int) (pow(double(Fanout), double(Levels+1)) - 1) / (Fanout - 1);
00135   const int Edges = Nodes - 1;
00136   PGraph GraphPt = PGraph::New();
00137   typename PGraph::TObj& Graph = *GraphPt;
00138   Graph.Reserve(Nodes, Edges);
00139   int node;
00140   for (node = 0; node < Nodes; node++) {
00141     Graph.AddNode(node); }
00142   // non-leaf nodes
00143   for (node = 0; node < (int) Nodes - (int) pow(double(Fanout), double(Levels)); node++) {
00144     for (int edge = 1; edge <= Fanout; edge++) {
00145       if (IsDir) {
00146         if (ChildPointsToParent) { Graph.AddEdge(Fanout*node+edge, node); }
00147         else { Graph.AddEdge(node, Fanout*node+edge); }
00148       } else {
00149         Graph.AddEdge(node, Fanout*node+edge); // link children
00150         Graph.AddEdge(Fanout*node+edge, node);
00151       }
00152     }
00153   }
00154   return GraphPt;
00155 }
00156 
00162 
00170 
00173 template <class PGraph>
00174 PGraph GenBaraHierar(const int& Levels, const bool& IsDir) {
00175   const int Nodes = (int) TMath::Round(TMath::Power(5, Levels));
00176   PGraph GraphPt = PGraph::New();
00177   typename PGraph::TObj& Graph = *GraphPt;
00178   Graph.Reserve(Nodes, -1);
00179   // base graph
00180   for (int i = 0; i < 5; i++) { Graph.AddNode(i); }
00181   Graph.AddEdge(1,2);  Graph.AddEdge(2,3);
00182   Graph.AddEdge(3,4);  Graph.AddEdge(4,1);
00183   Graph.AddEdge(1,0);  Graph.AddEdge(3,0);
00184   Graph.AddEdge(2,0);  Graph.AddEdge(4,0);
00185   // expansion
00186   const int CenterId = 0;
00187   for (int lev = 1; lev < Levels+1; lev++) {
00188     const int MxNId = Graph.GetNodes();
00189     // make 4 duplicate copies
00190     for (int d = 0; d < 4; d++) {
00191       for (int n = 0; n < MxNId; n++) { Graph.AddNode(); }
00192       for (int n = 0; n < MxNId; n++) {
00193         typename PGraph::TObj::TNodeI NI = Graph.GetNI(n);
00194         const int SrcId = n+MxNId*(d+1);
00195         for (int e = 0; e < NI.GetOutDeg(); e++) {
00196           Graph.AddEdge(SrcId, NI.GetOutNId(e)+MxNId*(d+1));
00197         }
00198       }
00199     }
00200     // add edges to the center
00201     //const int LevPow = (int)TMath::Round(TMath::Power(5,lev-1));
00202     for (int n = MxNId; n < Graph.GetNodes(); n++) {
00203       typename PGraph::TObj::TNodeI NI = Graph.GetNI(n);
00204       const int SrcId = n;
00205       int Pow = 1;  bool Skip = false;
00206       for (int p = 1; p <= lev; p++) {
00207         if (SrcId % (5*Pow) < Pow) { Skip=true; break; }
00208         Pow *= 5;
00209       }
00210       if (Skip) { continue; }
00211       Graph.AddEdge(SrcId, CenterId);
00212     }
00213   }
00214   return GraphPt;
00215 }
00216 
00217 template <class PGraph>
00218 PGraph GenRndGnm(const int& Nodes, const int& Edges, const bool& IsDir, TRnd& Rnd) {
00219   PGraph GraphPt = PGraph::New();
00220   typename PGraph::TObj& Graph = *GraphPt;
00221   Graph.Reserve(Nodes, Edges);
00222   IAssertR((1.0 * (Nodes-1) / 2 * (IsDir ? 2 : 1)) >= (1.0 * Edges / Nodes), TStr::Fmt("Not enough nodes (%d), for edges (%d).", Nodes, Edges));
00223   for (int node = 0; node < Nodes; node++) {
00224     IAssert(Graph.AddNode(node) == node);
00225   }
00226   for (int edge = 0; edge < Edges; ) {
00227     const int SrcNId = Rnd.GetUniDevInt(Nodes);
00228     const int DstNId = Rnd.GetUniDevInt(Nodes);
00229     if (SrcNId != DstNId && Graph.AddEdge(SrcNId, DstNId) != -2) { // is new edge
00230       if (! IsDir) { Graph.AddEdge(DstNId, SrcNId); }
00231       edge++;
00232     }
00233   }
00234   return GraphPt;
00235 }
00236 
00237 namespace TSnapDetail {
00239 template <class PGraph>
00240 TIntPr GetRndEdgeNonAdjNode(const PGraph& Graph, int NId1, int NId2) {
00241   typename PGraph::TObj::TNodeI NI1, NI2;
00242   int OutDeg = -1;
00243   do {
00244     NI1 = Graph->GetRndNI();
00245     OutDeg = NI1.GetOutDeg();
00246   } while (OutDeg == 0);
00247   NI2 = Graph->GetNI(NI1.GetOutNId(TInt::Rnd.GetUniDevInt(OutDeg)));
00248   int runs = 0;
00249   while (NI1.IsNbrNId(NId1) || NI1.IsNbrNId(NId2) || NI2.IsNbrNId(NId1) || NI2.IsNbrNId(NId2) || NI1.GetId()==NI2.GetId()) {
00250     do {
00251       NI1 = Graph->GetRndNI();
00252       OutDeg = NI1.GetOutDeg();
00253     } while (OutDeg == 0);
00254     NI2 = Graph->GetNI(NI1.GetOutNId(TInt::Rnd.GetUniDevInt(OutDeg)));
00255     if (runs++ == 1000) { return TIntPr(-1, -1); }
00256   }
00257   return TIntPr(NI1.GetId(), NI2.GetId());
00258 }
00259 
00260 } // namespace TSnapDetail
00261 
00262 }; // namespace TSnap