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
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 };