SNAP Library , Developer Reference  2013-01-07 14:03:36
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
gbase.h
Go to the documentation of this file.
00001 
00002 // Defines
00003 #define Kilo(n) (1000*(n))
00004 #define Mega(n) (1000*1000*(n))
00005 #define Giga(n) (1000*1000*1000*(n))
00006 
00010 typedef enum {
00011   gfUndef=0,    
00012   gfDirected,   
00013   gfMultiGraph, 
00014   gfNodeDat,    
00015   gfEdgeDat,    
00016   gfSources,    
00017   gfBipart,     
00018   gfMx          
00019 } TGraphFlag;
00020 
00021 namespace TSnap {
00022 
00024 template <class TGraph> struct IsDirected   { enum { Val = 0 }; };
00026 template <class TGraph> struct IsMultiGraph { enum { Val = 0 }; };
00028 template <class TGraph> struct IsNodeDat    { enum { Val = 0 }; };
00030 template <class TGraph> struct IsEdgeDat    { enum { Val = 0 }; };
00032 template <class TGraph> struct IsSources    { enum { Val = 0 }; };
00034 template <class TGraph> struct IsBipart     { enum { Val = 0 }; };
00035 
00037 #define HasGraphFlag(TGraph, Flag) \
00038   ((Flag)==gfDirected ? TSnap::IsDirected<TGraph::TNet>::Val : \
00039   (Flag)==gfMultiGraph ? TSnap::IsMultiGraph<TGraph::TNet>::Val : \
00040   (Flag)==gfNodeDat ? TSnap::IsNodeDat<TGraph::TNet>::Val : \
00041   (Flag)==gfEdgeDat ? TSnap::IsEdgeDat<TGraph::TNet>::Val : \
00042   (Flag)==gfSources ? TSnap::IsSources<TGraph::TNet>::Val : \
00043   (Flag)==gfBipart ? TSnap::IsBipart<TGraph::TNet>::Val : 0)
00044 
00046 template<class TDerivClass, class TBaseClass>
00047 class IsDerivedFrom {
00048 private:
00049   struct Yes { char a[1]; };
00050   struct No { char a[10]; };
00051   static Yes Test(TBaseClass*);
00052   static No Test(...);         // undefined
00053 public:
00054   enum { Val = sizeof(Test(static_cast<TDerivClass*>(0))) == sizeof(Yes) ? 1 : 0 };
00055 };
00056 
00058 // Graph Base
00059 
00061 TStr GetFlagStr(const TGraphFlag& GraphFlag);
00064 template <class PGraph> void PrintInfo(const PGraph& Graph, const TStr& Desc="", const TStr& OutFNm="", const bool& Fast=true);
00065 
00067 // Implementation
00068 
00069 // Forward declaration, definition in triad.h
00070 template <class PGraph> int GetTriads(const PGraph& Graph, int& ClosedTriads, int& OpenTriads, int SampleNodes=-1);
00071 
00072 template <class PGraph>
00073 void PrintInfo(const PGraph& Graph, const TStr& Desc, const TStr& OutFNm, const bool& Fast) {
00074   int BiDirEdges=0, ZeroNodes=0, ZeroInNodes=0, ZeroOutNodes=0, SelfEdges=0, NonZIODegNodes=0;
00075   THash<TIntPr, TInt> UniqDirE, UniqUnDirE;
00076   FILE *F = stdout;
00077   if (! OutFNm.Empty()) F = fopen(OutFNm.CStr(), "wt");
00078   if (! Desc.Empty()) { fprintf(F, "%s:", Desc.CStr()); }
00079   else { fprintf(F, "Graph:"); }
00080   for (int f = gfUndef; f < gfMx; f++) {
00081     if (HasGraphFlag(typename PGraph::TObj, TGraphFlag(f))) {
00082       fprintf(F, " %s", TSnap::GetFlagStr(TGraphFlag(f)).CStr()); }
00083   }
00084   // calc stat
00085   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
00086     if (NI.GetDeg()==0) ZeroNodes++;
00087     if (NI.GetInDeg()==0) ZeroInNodes++;
00088     if (NI.GetOutDeg()==0) ZeroOutNodes++;
00089     if (NI.GetInDeg()!=0 && NI.GetOutDeg()!=0) NonZIODegNodes++;
00090     if (! Fast || Graph->GetNodes() < 1000) {
00091       const int NId = NI.GetId();
00092       for (int edge = 0; edge < NI.GetOutDeg(); edge++) {
00093         const int DstNId = NI.GetOutNId(edge);
00094         if (Graph->IsEdge(DstNId, NId)) BiDirEdges++;
00095         if (NId == DstNId) SelfEdges++;
00096         UniqDirE.AddKey(TIntPr(NId, DstNId));
00097         UniqUnDirE.AddKey(TIntPr(TInt::GetMn(NId, DstNId), TInt::GetMx(NId, DstNId)));
00098       }
00099     }
00100   }
00101   int Closed=0, Open=0;
00102   if (! Fast) { TSnap::GetTriads(Graph, Closed, Open); }
00103   // print info
00104   fprintf(F, "\n");
00105   fprintf(F, "  Nodes:                    %d\n", Graph->GetNodes());
00106   fprintf(F, "  Edges:                    %d\n", Graph->GetEdges());
00107   fprintf(F, "  Zero Deg Nodes:           %d\n", ZeroNodes);
00108   fprintf(F, "  Zero InDeg Nodes:         %d\n", ZeroInNodes);
00109   fprintf(F, "  Zero OutDeg Nodes:        %d\n", ZeroOutNodes);
00110   fprintf(F, "  NonZero In-Out Deg Nodes: %d\n", NonZIODegNodes);
00111   if (! Fast) {
00112     fprintf(F, "  Unique directed edges:    %d\n", UniqDirE.Len());
00113     fprintf(F, "  Unique undirected edges:  %d\n", UniqUnDirE.Len());
00114     fprintf(F, "  Self Edges:               %d\n", SelfEdges);
00115     fprintf(F, "  BiDir Edges:              %d\n", BiDirEdges);
00116     fprintf(F, "  Closed triangles          %d\n", Closed);
00117     fprintf(F, "  Open triangles            %d\n", Open);
00118     fprintf(F, "  Frac. of closed triads    %f\n", Closed/double(Closed+Open));
00119   }
00120   if (! OutFNm.Empty()) { fclose(F); }
00121 }
00122 
00123 }  // namespace TSnap
00124 
00127 template <class TVal>
00128 class TSnapQueue {
00129 private:
00130   TInt MxFirst; // how often we move the queue to the start of the array
00131   TInt First, Last;
00132   TVec<TVal> ValV;
00133 public:
00134   TSnapQueue() : MxFirst(1024), First(0), Last(0), ValV(MxFirst, 0) { }
00136   TSnapQueue(const int& MxVals) : MxFirst(1024+MxVals/10), First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00137   TSnapQueue(const int& MxVals, const int& MaxFirst) : MxFirst(MaxFirst),
00138     First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00139   TSnapQueue(const TSnapQueue& Queue) : MxFirst(Queue.MxFirst), First(Queue.First), Last(Queue.Last), ValV(Queue.ValV) { }
00141   explicit TSnapQueue(TSIn& SIn): MxFirst(SIn), First(SIn), Last(SIn), ValV(SIn) { }
00143   void Save(TSOut& SOut) const { MxFirst.Save(SOut); First.Save(SOut); Last.Save(SOut); ValV.Save(SOut); }
00144 
00145   TSnapQueue& operator=(const TSnapQueue& Queue) { if (this != &Queue) { MxFirst=Queue.MxFirst;
00146     First=Queue.First; Last=Queue.Last; ValV=Queue.ValV; } return *this; }
00148   const TVal& operator[](const int& ValN) const { return ValV[First+ValN]; }
00149 
00151   void Clr(const bool& DoDel=true) { ValV.Clr(DoDel);  First=Last=0; }
00152   void Gen(const int& MxVals, const int& MaxFirst=1024) {
00153     MxFirst=MaxFirst; First=Last=0; ValV.Gen(MxVals, 0); }
00154 
00156   bool Empty() const {return First==Last;}
00158   int Len() const {return Last-First;}
00160   int GetFirst() const { return First; }
00162   int GetLast() const { return Last; }
00163   int Reserved() const { return ValV.Reserved(); }
00164 
00166   const TVal& Top() const { return ValV[First]; }
00168   void Pop() { First++;
00169     if (First==Last) { ValV.Clr(false); First=Last=0; } }
00171   void Push(const TVal& Val) {
00172     if (First>0 && (First > MxFirst || ValV.Len() == ValV.Reserved()) && ! ValV.Empty()) {
00173       //printf("[move cc queue.Len:%d-->%d]", ValV.Len(),Len()); TExeTm Tm;
00174       memmove(ValV.BegI(), ValV.GetI(First), sizeof(TVal)*Len());
00175       ValV.Del(Len(), ValV.Len()-1);  Last-=First;  First=0;
00176       //printf("[%s]\n", Tm.GetStr()); fflush(stdout);
00177     }
00178     //if (ValV.Len() == ValV.Reserved()){ printf("[resizeCCQ]"); fflush(stdout); }
00179     Last++;  ValV.Add(Val);
00180   }
00181 };
00182 
00186 class TUnionFind {
00187 private:
00188   THash<TInt, TIntPr> KIdSetH; // key id to (parent, rank)
00189 public:
00191   TInt& Parent(const int& Key) { return KIdSetH.GetDat(Key).Val1; }
00193   TInt& Rank(const int& Key) { return KIdSetH.GetDat(Key).Val2; }
00194 public:
00195   TUnionFind() : KIdSetH() { }
00197   TUnionFind(const int& ExpectKeys) : KIdSetH(ExpectKeys, true) { }
00198   TUnionFind(const TUnionFind& UnionFind) : KIdSetH(UnionFind.KIdSetH) { }
00199   TUnionFind& operator = (const TUnionFind& UF) { KIdSetH=UF.KIdSetH; return *this; }
00200 
00202   int Len() const { return KIdSetH.Len(); }
00204   bool IsKey(const int& Key) const { return KIdSetH.IsKey(Key); }
00206   int GetKeyI(const int& KeyN) const { return KIdSetH.GetKey(KeyN); }
00208   int Find(const int& Key);
00210   int Add(const int& Key) { KIdSetH.AddDat(Key, TIntPr(-1, 0));  return Key; }
00212   void Union(const int& Key1, const int& Key2);
00214   bool IsSameSet(const int& Key1, const int& Key2) {
00215     return Find(Key1) == Find(Key2); }
00217   void Dump();
00218 };