SNAP Library, Developer Reference  2012-10-02 12:56:23
SNAP, a general purpose network analysis and graph mining library
 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);
00031 PUNGraph GenRndPowerLaw(const int& Nodes, const double& PowerExp, const bool& ConfModel=true, TRnd& Rnd=TInt::Rnd);
00032 PUNGraph GenDegSeq(const TIntV& DegSeqV, TRnd& Rnd=TInt::Rnd);
00033 PUNGraph GenPrefAttach(const int& Nodes, const int& NodeOutDeg, TRnd& Rnd=TInt::Rnd);
00034 PUNGraph GenGeoPrefAttach(const int& Nodes, const int& OutDeg, const double& Beta, TRnd& Rnd=TInt::Rnd);
00035 PUNGraph GenSmallWorld(const int& Nodes, const int& NodeOutDeg, const double& RewireProb, TRnd& Rnd=TInt::Rnd);
00036 
00037 PUNGraph GenConfModel(const TIntV& DegSeqV, TRnd& Rnd=TInt::Rnd);
00038 PUNGraph GenRewire(const PUNGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00039 PNGraph  GenRewire(const PNGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00040 PBPGraph GenRewire(const PBPGraph& Graph, const int& NSwitch=100, TRnd& Rnd=TInt::Rnd);
00041 
00042 PNGraph GenForestFire(const int& Nodes, const double& FwdProb, const double& BckProb);
00043 PNGraph GenCopyModel(const int& Nodes, const double& Beta, TRnd& Rnd=TInt::Rnd);
00044 PNGraph GenRMat(const int& Nodes, const int& Edges, const double& A, const double& B, const double& C, TRnd& Rnd=TInt::Rnd);
00045 PNGraph GenRMatEpinions();
00046 
00048 // Implementation
00049 template <class PGraph>
00050 PGraph GenGrid(const int& Rows, const int& Cols, const bool& IsDir) {
00051   PGraph GraphPt = PGraph::New();
00052   typename PGraph::TObj& Graph = *GraphPt;
00053   Graph.Reserve(Rows*Cols, 4*Rows*Cols);
00054   int node, r, c;
00055   for (node = 0; node < Rows * Cols; node++) {
00056     Graph.AddNode(node); }
00057   for (r = 0; r < Rows; r++) {
00058     for (c = 0; c < Cols; c++) {
00059       const int nodeId = Cols*r + c;
00060       if (r < Rows-1) { // bottom node
00061         Graph.AddEdge(nodeId, nodeId+Cols); 
00062         if (Graph.HasFlag(gfDirected) && ! IsDir) { 
00063           Graph.AddEdge(nodeId+Cols-1, nodeId); }
00064       }
00065       if (c < Cols-1) { // right node
00066         Graph.AddEdge(nodeId, nodeId+1); 
00067         if (Graph.HasFlag(gfDirected) && ! IsDir) { 
00068           Graph.AddEdge(nodeId+1, nodeId); }
00069       }
00070     }
00071   }
00072   return GraphPt;
00073 }
00074 
00075 template <class PGraph>
00076 PGraph GenStar(const int& Nodes, const bool& IsDir) {
00077   PGraph Graph = PGraph::TObj::New();
00078   Graph->Reserve(Nodes, Nodes);
00079   Graph->AddNode(0);
00080   for (int n = 1; n < Nodes; n++) {
00081     Graph->AddNode(n);
00082     Graph->AddEdge(0, n);
00083     if (Graph->HasFlag(gfDirected) && ! IsDir) { Graph->AddEdge(n, 0); }
00084   }
00085   return Graph;
00086 }
00087 
00088 template <class PGraph>
00089 PGraph GenCircle(const int& Nodes, const int& NodeOutDeg, const bool& IsDir) {
00090   PGraph Graph = PGraph::TObj::New();
00091   Graph->Reserve(Nodes, Nodes*NodeOutDeg);
00092   for (int n = 0; n < Nodes; n++) {
00093     Graph->AddNode(n); }
00094   for (int n = 0; n < Nodes; n++) {
00095     for (int x = 0; x < NodeOutDeg; x++) {
00096       Graph->AddEdge(n, (n+x) % Nodes);
00097       if (Graph->HasFlag(gfDirected) && ! IsDir) { Graph->AddEdge((n+x) % Nodes, n); }
00098     }
00099   }
00100   return Graph;
00101 }
00102 
00103 template <class PGraph>
00104 PGraph GenFull(const int& Nodes) {
00105   PGraph Graph = PGraph::TObj::New();
00106   Graph->Reserve(Nodes, Nodes*Nodes);
00107   for (int n = 0; n < Nodes; n++) {
00108     Graph->AddNode(n); }
00109   for (int n1 = 0; n1 < Nodes; n1++) {
00110     for (int n2 = 0; n2 < Nodes; n2++) {
00111       if (n1 != n2) { Graph->AddEdge(n1, n2); }
00112     }
00113   }
00114   return Graph;
00115 }
00116 
00117 template <class PGraph>
00118 PGraph GenTree(const int& Fanout, const int& Levels, const bool& IsDir, const bool& ChildPointsToParent) {
00119   const int Nodes = (int) (pow(double(Fanout), double(Levels+1)) - 1) / (Fanout - 1);
00120   const int Edges = Nodes - 1;
00121   PGraph GraphPt = PGraph::New();
00122   typename PGraph::TObj& Graph = *GraphPt;
00123   Graph.Reserve(Nodes, Edges);
00124   int node;
00125   for (node = 0; node < Nodes; node++) {
00126     Graph.AddNode(node); }
00127   // non-leaf nodes
00128   for (node = 0; node < (int) Nodes - (int) pow(double(Fanout), double(Levels)); node++) {
00129     for (int edge = 1; edge <= Fanout; edge++) {
00130       if (IsDir) {
00131         if (ChildPointsToParent) { Graph.AddEdge(Fanout*node+edge, node); }
00132         else { Graph.AddEdge(node, Fanout*node+edge); }
00133       } else {
00134         Graph.AddEdge(node, Fanout*node+edge); // link children
00135         Graph.AddEdge(Fanout*node+edge, node);
00136       }
00137     }
00138   }
00139   return GraphPt;
00140 }
00141 
00147 
00155 
00158 template <class PGraph>
00159 PGraph GenBaraHierar(const int& Levels, const bool& IsDir) {
00160   const int Nodes = (int) TMath::Round(TMath::Power(5, Levels));
00161   PGraph GraphPt = PGraph::New();
00162   typename PGraph::TObj& Graph = *GraphPt;
00163   Graph.Reserve(Nodes, -1);
00164   // base graph
00165   for (int i = 0; i < 5; i++) { Graph.AddNode(i); }
00166   Graph.AddEdge(1,2);  Graph.AddEdge(2,3);
00167   Graph.AddEdge(3,4);  Graph.AddEdge(4,1);
00168   Graph.AddEdge(1,0);  Graph.AddEdge(3,0);
00169   Graph.AddEdge(2,0);  Graph.AddEdge(4,0);
00170   // expansion
00171   const int CenterId = 0;
00172   for (int lev = 1; lev < Levels+1; lev++) {
00173     const int MxNId = Graph.GetNodes();
00174     // make 4 duplicate copies
00175     for (int d = 0; d < 4; d++) {
00176       for (int n = 0; n < MxNId; n++) { Graph.AddNode(); }
00177       for (int n = 0; n < MxNId; n++) {
00178         typename PGraph::TObj::TNodeI NI = Graph.GetNI(n);
00179         const int SrcId = n+MxNId*(d+1);
00180         for (int e = 0; e < NI.GetOutDeg(); e++) {
00181           Graph.AddEdge(SrcId, NI.GetOutNId(e)+MxNId*(d+1));
00182         }
00183       }
00184     }
00185     // add edges to the center
00186     const int LevPow = (int)TMath::Round(TMath::Power(5,lev-1));
00187     for (int n = MxNId; n < Graph.GetNodes(); n++) {
00188       typename PGraph::TObj::TNodeI NI = Graph.GetNI(n);
00189       const int SrcId = n;
00190       int Pow = 1;  bool Skip = false;
00191       for (int p = 1; p <= lev; p++) {
00192         if (SrcId % (5*Pow) < Pow) { Skip=true; break; }
00193         Pow *= 5;
00194       }
00195       if (Skip) { continue; }
00196       Graph.AddEdge(SrcId, CenterId);
00197     }
00198   }
00199   return GraphPt;
00200 }
00201 
00202 template <class PGraph>
00203 PGraph GenRndGnm(const int& Nodes, const int& Edges, const bool& IsDir, TRnd& Rnd) {
00204   PGraph GraphPt = PGraph::New();
00205   typename PGraph::TObj& Graph = *GraphPt;
00206   Graph.Reserve(Nodes, Edges);
00207   for (int node = 0; node < Nodes; node++) {
00208     IAssert(Graph.AddNode(node) == node);
00209   }
00210   for (int edge = 0; edge < Edges; ) {
00211     const int SrcNId = Rnd.GetUniDevInt(Nodes);
00212     const int DstNId = Rnd.GetUniDevInt(Nodes);
00213     if (SrcNId != DstNId && Graph.AddEdge(SrcNId, DstNId) != -2) { // is new edge
00214       if (! IsDir) { Graph.AddEdge(DstNId, SrcNId); }
00215       edge++;
00216     }
00217   }
00218   return GraphPt;
00219 }
00220 
00221 namespace TSnapDetail {
00223 template <class PGraph>
00224 TIntPr GetRndEdgeNonAdjNode(const PGraph& Graph, int NId1, int NId2) {
00225   typename PGraph::TObj::TNodeI NI1, NI2;
00226   int OutDeg = -1;
00227   do {
00228     NI1 = Graph->GetRndNI();
00229     OutDeg = NI1.GetOutDeg();
00230   } while (OutDeg == 0);
00231   NI2 = Graph->GetNI(NI1.GetOutNId(TInt::Rnd.GetUniDevInt(OutDeg)));
00232   int runs = 0;
00233   while (NI1.IsNbrNId(NId1) || NI1.IsNbrNId(NId2) || NI2.IsNbrNId(NId1) || NI2.IsNbrNId(NId2) || NI1.GetId()==NI2.GetId()) {
00234     do {
00235       NI1 = Graph->GetRndNI();
00236       OutDeg = NI1.GetOutDeg();
00237     } while (OutDeg == 0);
00238     NI2 = Graph->GetNI(NI1.GetOutNId(TInt::Rnd.GetUniDevInt(OutDeg)));
00239     if (runs++ == 1000) { return TIntPr(-1, -1); }
00240   }
00241   return TIntPr(NI1.GetId(), NI2.GetId());
00242 }
00243 
00244 } // namespace TSnapDetail
00245 
00246 }; // namespace TSnap