SNAP Library 2.0, User Reference  2013-05-13 16:33:57
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 
00007 //#//////////////////////////////////////////////
00009 
00011 typedef enum {
00012   gfUndef=0,    
00013   gfDirected,   
00014   gfMultiGraph, 
00015   gfNodeDat,    
00016   gfEdgeDat,    
00017   gfSources,    
00018   gfBipart,     
00019   gfMx          
00020 } TGraphFlag;
00021 
00022 namespace TSnap {
00023 
00025 template <class TGraph> struct IsDirected   { enum { Val = 0 }; };
00027 template <class TGraph> struct IsMultiGraph { enum { Val = 0 }; };
00029 template <class TGraph> struct IsNodeDat    { enum { Val = 0 }; };
00031 template <class TGraph> struct IsEdgeDat    { enum { Val = 0 }; };
00033 template <class TGraph> struct IsSources    { enum { Val = 0 }; };
00035 template <class TGraph> struct IsBipart     { enum { Val = 0 }; };
00036 
00038 #define HasGraphFlag(TGraph, Flag) \
00039   ((Flag)==gfDirected ? TSnap::IsDirected<TGraph::TNet>::Val : \
00040   (Flag)==gfMultiGraph ? TSnap::IsMultiGraph<TGraph::TNet>::Val : \
00041   (Flag)==gfNodeDat ? TSnap::IsNodeDat<TGraph::TNet>::Val : \
00042   (Flag)==gfEdgeDat ? TSnap::IsEdgeDat<TGraph::TNet>::Val : \
00043   (Flag)==gfSources ? TSnap::IsSources<TGraph::TNet>::Val : \
00044   (Flag)==gfBipart ? TSnap::IsBipart<TGraph::TNet>::Val : 0)
00045 
00047 template<class TDerivClass, class TBaseClass>
00048 class IsDerivedFrom {
00049 private:
00050   struct Yes { char a[1]; };
00051   struct No { char a[10]; };
00052   static Yes Test(TBaseClass*);
00053   static No Test(...);         // undefined
00054 public:
00055   enum { Val = sizeof(Test(static_cast<TDerivClass*>(0))) == sizeof(Yes) ? 1 : 0 };
00056 };
00057 
00059 // Graph Base
00060 
00062 TStr GetFlagStr(const TGraphFlag& GraphFlag);
00064 
00066 template <class PGraph> void PrintInfo(const PGraph& Graph, const TStr& Desc="", const TStr& OutFNm="", const bool& Fast=true);
00067 
00069 // Implementation
00070 
00071 // Forward declaration, definition in triad.h
00072 template <class PGraph> int64 GetTriads(const PGraph& Graph, int64& ClosedTriads, int64& OpenTriads, int SampleNodes=-1);
00073 
00074 template <class PGraph>
00075 void PrintInfo(const PGraph& Graph, const TStr& Desc, const TStr& OutFNm, const bool& Fast) {
00076   int BiDirEdges=0, ZeroNodes=0, ZeroInNodes=0, ZeroOutNodes=0, SelfEdges=0, NonZIODegNodes=0;
00077   THash<TIntPr, TInt> UniqDirE, UniqUnDirE;
00078   FILE *F = stdout;
00079   if (! OutFNm.Empty()) F = fopen(OutFNm.CStr(), "wt");
00080   if (! Desc.Empty()) { fprintf(F, "%s:", Desc.CStr()); }
00081   else { fprintf(F, "Graph:"); }
00082   for (int f = gfUndef; f < gfMx; f++) {
00083     if (HasGraphFlag(typename PGraph::TObj, TGraphFlag(f))) {
00084       fprintf(F, " %s", TSnap::GetFlagStr(TGraphFlag(f)).CStr()); }
00085   }
00086   // calc stat
00087   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
00088     if (NI.GetDeg()==0) ZeroNodes++;
00089     if (NI.GetInDeg()==0) ZeroInNodes++;
00090     if (NI.GetOutDeg()==0) ZeroOutNodes++;
00091     if (NI.GetInDeg()!=0 && NI.GetOutDeg()!=0) NonZIODegNodes++;
00092     if (! Fast || Graph->GetNodes() < 1000) {
00093       const int NId = NI.GetId();
00094       for (int edge = 0; edge < NI.GetOutDeg(); edge++) {
00095         const int DstNId = NI.GetOutNId(edge);
00096         if (Graph->IsEdge(DstNId, NId)) BiDirEdges++;
00097         if (NId == DstNId) SelfEdges++;
00098         UniqDirE.AddKey(TIntPr(NId, DstNId));
00099         UniqUnDirE.AddKey(TIntPr(TInt::GetMn(NId, DstNId), TInt::GetMx(NId, DstNId)));
00100       }
00101     }
00102   }
00103   int64 Closed=0, Open=0;
00104   if (! Fast) { TSnap::GetTriads(Graph, Closed, Open); }
00105   // print info
00106   fprintf(F, "\n");
00107   fprintf(F, "  Nodes:                    %d\n", Graph->GetNodes());
00108   fprintf(F, "  Edges:                    %d\n", Graph->GetEdges());
00109   fprintf(F, "  Zero Deg Nodes:           %d\n", ZeroNodes);
00110   fprintf(F, "  Zero InDeg Nodes:         %d\n", ZeroInNodes);
00111   fprintf(F, "  Zero OutDeg Nodes:        %d\n", ZeroOutNodes);
00112   fprintf(F, "  NonZero In-Out Deg Nodes: %d\n", NonZIODegNodes);
00113   if (! Fast) {
00114     fprintf(F, "  Unique directed edges:    %d\n", UniqDirE.Len());
00115     fprintf(F, "  Unique undirected edges:  %d\n", UniqUnDirE.Len());
00116     fprintf(F, "  Self Edges:               %d\n", SelfEdges);
00117     fprintf(F, "  BiDir Edges:              %d\n", BiDirEdges);
00118     fprintf(F, "  Closed triangles          %s\n", TUInt64::GetStr(Closed).CStr());
00119     fprintf(F, "  Open triangles            %s\n", TUInt64::GetStr(Open).CStr());
00120     fprintf(F, "  Frac. of closed triads    %f\n", Closed/double(Closed+Open));
00121   }
00122   if (! OutFNm.Empty()) { fclose(F); }
00123 }
00124 
00125 }  // namespace TSnap
00126 
00127 //#//////////////////////////////////////////////
00129 template <class TVal>
00130 class TSnapQueue {
00131 private:
00132   TInt MxFirst; // how often we move the queue to the start of the array
00133   TInt First, Last;
00134   TVec<TVal> ValV;
00135 public:
00136   TSnapQueue() : MxFirst(1024), First(0), Last(0), ValV(MxFirst, 0) { }
00138   TSnapQueue(const int& MxVals) : MxFirst(1024+MxVals/10), First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00139   TSnapQueue(const int& MxVals, const int& MaxFirst) : MxFirst(MaxFirst),
00140     First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00141   TSnapQueue(const TSnapQueue& Queue) : MxFirst(Queue.MxFirst), First(Queue.First), Last(Queue.Last), ValV(Queue.ValV) { }
00143   explicit TSnapQueue(TSIn& SIn): MxFirst(SIn), First(SIn), Last(SIn), ValV(SIn) { }
00145   void Save(TSOut& SOut) const { MxFirst.Save(SOut); First.Save(SOut); Last.Save(SOut); ValV.Save(SOut); }
00146 
00147   TSnapQueue& operator=(const TSnapQueue& Queue) { if (this != &Queue) { MxFirst=Queue.MxFirst;
00148     First=Queue.First; Last=Queue.Last; ValV=Queue.ValV; } return *this; }
00150   const TVal& operator[](const int& ValN) const { return ValV[First+ValN]; }
00151 
00153   void Clr(const bool& DoDel=true) { ValV.Clr(DoDel);  First=Last=0; }
00154   void Gen(const int& MxVals, const int& MaxFirst=1024) {
00155     MxFirst=MaxFirst; First=Last=0; ValV.Gen(MxVals, 0); }
00156 
00158   bool Empty() const {return First==Last;}
00160   int Len() const {return Last-First;}
00162   int GetFirst() const { return First; }
00164   int GetLast() const { return Last; }
00165   int Reserved() const { return ValV.Reserved(); }
00166 
00168   const TVal& Top() const { return ValV[First]; }
00170   void Pop() { First++;
00171     if (First==Last) { ValV.Clr(false); First=Last=0; } }
00173   void Push(const TVal& Val) {
00174     if (First>0 && (First > MxFirst || ValV.Len() == ValV.Reserved()) && ! ValV.Empty()) {
00175       //printf("[move cc queue.Len:%d-->%d]", ValV.Len(),Len()); TExeTm Tm;
00176       memmove(ValV.BegI(), ValV.GetI(First), sizeof(TVal)*Len());
00177       ValV.Del(Len(), ValV.Len()-1);  Last-=First;  First=0;
00178       //printf("[%s]\n", Tm.GetStr()); fflush(stdout);
00179     }
00180     //if (ValV.Len() == ValV.Reserved()){ printf("[resizeCCQ]"); fflush(stdout); }
00181     Last++;  ValV.Add(Val);
00182   }
00183 };
00184 
00185 //#//////////////////////////////////////////////
00187 
00189 class TUnionFind {
00190 private:
00191   THash<TInt, TIntPr> KIdSetH; // key id to (parent, rank)
00192 public:
00194   TInt& Parent(const int& Key) { return KIdSetH.GetDat(Key).Val1; }
00196   TInt& Rank(const int& Key) { return KIdSetH.GetDat(Key).Val2; }
00197 public:
00198   TUnionFind() : KIdSetH() { }
00200   TUnionFind(const int& ExpectKeys) : KIdSetH(ExpectKeys, true) { }
00201   TUnionFind(const TUnionFind& UnionFind) : KIdSetH(UnionFind.KIdSetH) { }
00202   TUnionFind& operator = (const TUnionFind& UF) { KIdSetH=UF.KIdSetH; return *this; }
00203 
00205   int Len() const { return KIdSetH.Len(); }
00207   bool IsKey(const int& Key) const { return KIdSetH.IsKey(Key); }
00209   int GetKeyI(const int& KeyN) const { return KIdSetH.GetKey(KeyN); }
00211   int Find(const int& Key);
00213   int Add(const int& Key) { KIdSetH.AddDat(Key, TIntPr(-1, 0));  return Key; }
00215   void Union(const int& Key1, const int& Key2);
00217   bool IsSameSet(const int& Key1, const int& Key2) {
00218     return Find(Key1) == Find(Key2); }
00220   void Dump();
00221 };
00222 
00223 //#//////////////////////////////////////////////
00225 
00227 template <class TVal, class TCmp = TLss<TVal> >
00228 class THeap {
00229 private:
00230   TCmp Cmp;
00231   TVec<TVal> HeapV;
00232 private:
00233   void PushHeap(const int& First, int HoleIdx, const int& Top, TVal Val);
00234   void AdjustHeap(const int& First, int HoleIdx, const int& Len, TVal Val);
00235   void MakeHeap(const int& First, const int& Len);
00236 public:
00237   THeap() : HeapV() { }
00238   THeap(const int& MxVals) : Cmp(), HeapV(0, MxVals) { }
00239   THeap(const TCmp& _Cmp) : Cmp(_Cmp), HeapV() { }
00240   THeap(const TVec<TVal>& Vec) : Cmp(), HeapV(Vec) { MakeHeap(); }
00241   THeap(const TVec<TVal>& Vec, const TCmp& _Cmp) : Cmp(_Cmp), HeapV(Vec) { MakeHeap(); }
00242   THeap(const THeap& Heap) : Cmp(Heap.Cmp), HeapV(Heap.HeapV) { }
00243   THeap& operator = (const THeap& H) { Cmp=H.Cmp; HeapV=H.HeapV; return *this; }
00244 
00246   const TVal& TopHeap() const { return HeapV[0]; }
00248   void PushHeap(const TVal& Val);
00250   TVal PopHeap();
00252   int Len() const { return HeapV.Len(); }
00254   bool Empty() const { return HeapV.Empty(); }
00256   const TVec<TVal>& operator()() const { return HeapV; }
00258   TVec<TVal>& operator()() { return HeapV; }
00260   void Add(const TVal& Val) { HeapV.Add(Val); }
00262   void MakeHeap() { MakeHeap(0, Len()); }
00263 };
00264 
00265 template <class TVal, class TCmp>
00266 void THeap<TVal, TCmp>::PushHeap(const TVal& Val) {
00267   HeapV.Add(Val);
00268   PushHeap(0, HeapV.Len()-1, 0, Val);
00269 }
00270 
00271 template <class TVal, class TCmp>
00272 TVal THeap<TVal, TCmp>::PopHeap() {
00273   IAssert(! HeapV.Empty());
00274   const TVal Top = HeapV[0];
00275   HeapV[0] = HeapV.Last();
00276   HeapV.DelLast();
00277   if (! HeapV.Empty()) {
00278     AdjustHeap(0, 0, HeapV.Len(), HeapV[0]);
00279   }
00280   return Top;
00281 }
00282 
00283 template <class TVal, class TCmp>
00284 void THeap<TVal, TCmp>::PushHeap(const int& First, int HoleIdx, const int& Top, TVal Val) {
00285   int Parent = (HoleIdx-1)/2;
00286   while (HoleIdx > Top && Cmp(HeapV[First+Parent], Val)) {
00287     HeapV[First+HoleIdx] = HeapV[First+Parent];
00288     HoleIdx = Parent;  Parent = (HoleIdx-1)/2;
00289   }
00290   HeapV[First+HoleIdx] = Val;
00291 }
00292 
00293 template <class TVal, class TCmp>
00294 void THeap<TVal, TCmp>::AdjustHeap(const int& First, int HoleIdx, const int& Len, TVal Val) {
00295   const int Top = HoleIdx;
00296   int Right = 2*HoleIdx+2;
00297   while (Right < Len) {
00298     if (Cmp(HeapV[First+Right], HeapV[First+Right-1])) { Right--; }
00299     HeapV[First+HoleIdx] = HeapV[First+Right];
00300     HoleIdx = Right;  Right = 2*(Right+1); }
00301   if (Right == Len) {
00302     HeapV[First+HoleIdx] = HeapV[First+Right-1];
00303     HoleIdx = Right-1; }
00304   PushHeap(First, HoleIdx, Top, Val);
00305 }
00306 
00307 template <class TVal, class TCmp>
00308 void THeap<TVal, TCmp>::MakeHeap(const int& First, const int& Len) {
00309   if (Len < 2) { return; }
00310   int Parent = (Len-2)/2;
00311   while (true) {
00312     AdjustHeap(First, Parent, Len, HeapV[First+Parent]);
00313     if (Parent == 0) { return; }
00314     Parent--;
00315   }
00316 }
00317