SNAP Library 2.1, Developer 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
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 TGraphFlag_ {
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 
00046 #if 0
00047 // RS 2013/08/19, commented out IsDerivedFrom, it is not called anywhere
00048 //  swig throws an error
00050 template<class TDerivClass, class TBaseClass>
00051 class IsDerivedFrom {
00052 private:
00053   struct Yes { char a[1]; };
00054   struct No { char a[10]; };
00055   static Yes Test(TBaseClass*);
00056   static No Test(...);         // undefined
00057 public:
00058   enum { Val = sizeof(Test(static_cast<TDerivClass*>(0))) == sizeof(Yes) ? 1 : 0 };
00059 };
00060 #endif
00061 
00063 // Graph Base
00064 
00066 TStr GetFlagStr(const TGraphFlag& GraphFlag);
00068 
00070 template <class PGraph> void PrintInfo(const PGraph& Graph, const TStr& Desc="", const TStr& OutFNm="", const bool& Fast=true);
00071 
00073 // Implementation
00074 
00075 // Forward declaration, definition in triad.h
00076 template <class PGraph> int64 GetTriads(const PGraph& Graph, int64& ClosedTriads, int64& OpenTriads, int SampleNodes=-1);
00077 template <class PGraph> double GetBfsEffDiam(const PGraph& Graph, const int& NTestNodes, const bool& IsDir, double& EffDiam, int& FullDiam);
00078 template <class PGraph> double GetMxWccSz(const PGraph& Graph);
00079 template <class PGraph> double GetMxSccSz(const PGraph& Graph);
00080 template<class PGraph> int GetKCoreNodes(const PGraph& Graph, TIntPrV& CoreIdSzV);
00081 template<class PGraph> int GetKCoreEdges(const PGraph& Graph, TIntPrV& CoreIdSzV);
00082 
00083 template <class PGraph>
00084 void PrintInfo(const PGraph& Graph, const TStr& Desc, const TStr& OutFNm, const bool& Fast) {
00085   int BiDirEdges=0, ZeroNodes=0, ZeroInNodes=0, ZeroOutNodes=0, SelfEdges=0, NonZIODegNodes=0;
00086   THash<TIntPr, TInt> UniqDirE, UniqUnDirE;
00087   FILE *F = stdout;
00088   if (! OutFNm.Empty()) F = fopen(OutFNm.CStr(), "wt");
00089   if (! Desc.Empty()) { fprintf(F, "%s:", Desc.CStr()); }
00090   else { fprintf(F, "Graph:"); }
00091   for (int f = gfUndef; f < gfMx; f++) {
00092     if (HasGraphFlag(typename PGraph::TObj, TGraphFlag(f))) {
00093       fprintf(F, " %s", TSnap::GetFlagStr(TGraphFlag(f)).CStr()); }
00094   }
00095   // calc stat
00096   for (typename PGraph::TObj::TNodeI NI = Graph->BegNI(); NI < Graph->EndNI(); NI++) {
00097     if (NI.GetDeg()==0) ZeroNodes++;
00098     if (NI.GetInDeg()==0) ZeroInNodes++;
00099     if (NI.GetOutDeg()==0) ZeroOutNodes++;
00100     if (NI.GetInDeg()!=0 && NI.GetOutDeg()!=0) NonZIODegNodes++;
00101     if (! Fast || Graph->GetNodes() < 1000) {
00102       const int NId = NI.GetId();
00103       for (int edge = 0; edge < NI.GetOutDeg(); edge++) {
00104         const int DstNId = NI.GetOutNId(edge);
00105         if (Graph->IsEdge(DstNId, NId)) BiDirEdges++;
00106         if (NId == DstNId) SelfEdges++;
00107         UniqDirE.AddKey(TIntPr(NId, DstNId));
00108         UniqUnDirE.AddKey(TIntPr(TInt::GetMn(NId, DstNId), TInt::GetMx(NId, DstNId)));
00109       }
00110     }
00111   }
00112   int64 Closed=0, Open=0;
00113   double WccSz=0, SccSz=0;
00114   double EffDiam=0;
00115   int FullDiam=0;
00116   if (! Fast) {
00117     TSnap::GetTriads(Graph, Closed, Open);
00118     WccSz = TSnap::GetMxWccSz(Graph);
00119     SccSz = TSnap::GetMxSccSz(Graph);
00120     TSnap::GetBfsEffDiam(Graph, 100, false, EffDiam, FullDiam);
00121   }
00122   // print info
00123   fprintf(F, "\n");
00124   fprintf(F, "  Nodes:                    %d\n", Graph->GetNodes());
00125   fprintf(F, "  Edges:                    %d\n", Graph->GetEdges());
00126   fprintf(F, "  Zero Deg Nodes:           %d\n", ZeroNodes);
00127   fprintf(F, "  Zero InDeg Nodes:         %d\n", ZeroInNodes);
00128   fprintf(F, "  Zero OutDeg Nodes:        %d\n", ZeroOutNodes);
00129   fprintf(F, "  NonZero In-Out Deg Nodes: %d\n", NonZIODegNodes);
00130   if (! Fast) {
00131     fprintf(F, "  Unique directed edges:    %d\n", UniqDirE.Len());
00132     fprintf(F, "  Unique undirected edges:  %d\n", UniqUnDirE.Len());
00133     fprintf(F, "  Self Edges:               %d\n", SelfEdges);
00134     fprintf(F, "  BiDir Edges:              %d\n", BiDirEdges);
00135     fprintf(F, "  Closed triangles:         %s\n", TUInt64::GetStr(Closed).CStr());
00136     fprintf(F, "  Open triangles:           %s\n", TUInt64::GetStr(Open).CStr());
00137     fprintf(F, "  Frac. of closed triads:   %f\n", Closed/double(Closed+Open));
00138     fprintf(F, "  Connected component size: %f\n", WccSz);
00139     fprintf(F, "  Strong conn. comp. size:  %f\n", SccSz);
00140     fprintf(F, "  Approx. full diameter:    %d\n", FullDiam);
00141     fprintf(F, "  90%% effective diameter:  %f\n", EffDiam);
00142     //fprintf(F, "  Core\tNodes\tEdges\n");
00143     //for (int i  = 0; i < CNodesV.Len(); i++) {
00144     //  printf("  %d\t%d\t%d\n", CNodesV[i].Val1(), CNodesV[i].Val2(), CEdgesV[i].Val2());
00145     //}
00146   }
00147   if (! OutFNm.Empty()) { fclose(F); }
00148 }
00149 
00150 }  // namespace TSnap
00151 
00152 //#//////////////////////////////////////////////
00154 template <class TVal>
00155 class TSnapQueue {
00156 private:
00157   TInt MxFirst; // how often we move the queue to the start of the array
00158   TInt First, Last;
00159   TVec<TVal> ValV;
00160 public:
00161   TSnapQueue() : MxFirst(1024), First(0), Last(0), ValV(MxFirst, 0) { }
00163   TSnapQueue(const int& MxVals) : MxFirst(1024+MxVals/10), First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00164   TSnapQueue(const int& MxVals, const int& MaxFirst) : MxFirst(MaxFirst),
00165     First(0), Last(0), ValV(TInt::GetMx(MxFirst, MxVals), 0) { }
00166   TSnapQueue(const TSnapQueue& Queue) : MxFirst(Queue.MxFirst), First(Queue.First), Last(Queue.Last), ValV(Queue.ValV) { }
00168   explicit TSnapQueue(TSIn& SIn): MxFirst(SIn), First(SIn), Last(SIn), ValV(SIn) { }
00170   void Save(TSOut& SOut) const { MxFirst.Save(SOut); First.Save(SOut); Last.Save(SOut); ValV.Save(SOut); }
00171 
00172   TSnapQueue& operator=(const TSnapQueue& Queue) { if (this != &Queue) { MxFirst=Queue.MxFirst;
00173     First=Queue.First; Last=Queue.Last; ValV=Queue.ValV; } return *this; }
00175   const TVal& operator[](const int& ValN) const { return ValV[First+ValN]; }
00176 
00178   void Clr(const bool& DoDel=true) { ValV.Clr(DoDel);  First=Last=0; }
00179   void Gen(const int& MxVals, const int& MaxFirst=1024) {
00180     MxFirst=MaxFirst; First=Last=0; ValV.Gen(MxVals, 0); }
00181 
00183   bool Empty() const {return First==Last;}
00185   int Len() const {return Last-First;}
00187   int GetFirst() const { return First; }
00189   int GetLast() const { return Last; }
00190   int Reserved() const { return ValV.Reserved(); }
00191 
00193   const TVal& Top() const { return ValV[First]; }
00195   void Pop() { First++;
00196     if (First==Last) { ValV.Clr(false); First=Last=0; } }
00198   void Push(const TVal& Val) {
00199     if (First>0 && (First > MxFirst || ValV.Len() == ValV.Reserved()) && ! ValV.Empty()) {
00200       //printf("[move cc queue.Len:%d-->%d]", ValV.Len(),Len()); TExeTm Tm;
00201       memmove(ValV.BegI(), ValV.GetI(First), sizeof(TVal)*Len());
00202       ValV.Del(Len(), ValV.Len()-1);  Last-=First;  First=0;
00203       //printf("[%s]\n", Tm.GetStr()); fflush(stdout);
00204     }
00205     //if (ValV.Len() == ValV.Reserved()){ printf("[resizeCCQ]"); fflush(stdout); }
00206     Last++;  ValV.Add(Val);
00207   }
00208 };
00209 
00210 //#//////////////////////////////////////////////
00212 
00214 class TUnionFind {
00215 private:
00216   THash<TInt, TIntPr> KIdSetH; // key id to (parent, rank)
00217 public:
00219   TInt& Parent(const int& Key) { return KIdSetH.GetDat(Key).Val1; }
00221   TInt& Rank(const int& Key) { return KIdSetH.GetDat(Key).Val2; }
00222 public:
00223   TUnionFind() : KIdSetH() { }
00225   TUnionFind(const int& ExpectKeys) : KIdSetH(ExpectKeys, true) { }
00226   TUnionFind(const TUnionFind& UnionFind) : KIdSetH(UnionFind.KIdSetH) { }
00227   TUnionFind& operator = (const TUnionFind& UF) { KIdSetH=UF.KIdSetH; return *this; }
00228 
00230   int Len() const { return KIdSetH.Len(); }
00232   bool IsKey(const int& Key) const { return KIdSetH.IsKey(Key); }
00234   int GetKeyI(const int& KeyN) const { return KIdSetH.GetKey(KeyN); }
00236   int Find(const int& Key);
00238   int Add(const int& Key) { KIdSetH.AddDat(Key, TIntPr(-1, 0));  return Key; }
00240   void Union(const int& Key1, const int& Key2);
00242   bool IsSameSet(const int& Key1, const int& Key2) {
00243     return Find(Key1) == Find(Key2); }
00245   void Dump();
00246 };
00247 
00248 //#//////////////////////////////////////////////
00250 
00252 template <class TVal, class TCmp = TLss<TVal> >
00253 class THeap {
00254 private:
00255   TCmp Cmp;
00256   TVec<TVal> HeapV;
00257 private:
00258   void PushHeap(const int& First, int HoleIdx, const int& Top, TVal Val);
00259   void AdjustHeap(const int& First, int HoleIdx, const int& Len, TVal Val);
00260   void MakeHeap(const int& First, const int& Len);
00261 public:
00262   THeap() : HeapV() { }
00263   THeap(const int& MxVals) : Cmp(), HeapV(MxVals, 0) { }
00264   THeap(const TCmp& _Cmp) : Cmp(_Cmp), HeapV() { }
00265   THeap(const TVec<TVal>& Vec) : Cmp(), HeapV(Vec) { MakeHeap(); }
00266   THeap(const TVec<TVal>& Vec, const TCmp& _Cmp) : Cmp(_Cmp), HeapV(Vec) { MakeHeap(); }
00267   THeap(const THeap& Heap) : Cmp(Heap.Cmp), HeapV(Heap.HeapV) { }
00268   THeap& operator = (const THeap& H) { Cmp=H.Cmp; HeapV=H.HeapV; return *this; }
00269 
00271   const TVal& TopHeap() const { return HeapV[0]; }
00273   void PushHeap(const TVal& Val);
00275   TVal PopHeap();
00277   int Len() const { return HeapV.Len(); }
00279   bool Empty() const { return HeapV.Empty(); }
00281   const TVec<TVal>& operator()() const { return HeapV; }
00283   TVec<TVal>& operator()() { return HeapV; }
00285   void Add(const TVal& Val) { HeapV.Add(Val); }
00287   void MakeHeap() { MakeHeap(0, Len()); }
00288 };
00289 
00290 template <class TVal, class TCmp>
00291 void THeap<TVal, TCmp>::PushHeap(const TVal& Val) {
00292   HeapV.Add(Val);
00293   PushHeap(0, HeapV.Len()-1, 0, Val);
00294 }
00295 
00296 template <class TVal, class TCmp>
00297 TVal THeap<TVal, TCmp>::PopHeap() {
00298   IAssert(! HeapV.Empty());
00299   const TVal Top = HeapV[0];
00300   HeapV[0] = HeapV.Last();
00301   HeapV.DelLast();
00302   if (! HeapV.Empty()) {
00303     AdjustHeap(0, 0, HeapV.Len(), HeapV[0]);
00304   }
00305   return Top;
00306 }
00307 
00308 template <class TVal, class TCmp>
00309 void THeap<TVal, TCmp>::PushHeap(const int& First, int HoleIdx, const int& Top, TVal Val) {
00310   int Parent = (HoleIdx-1)/2;
00311   while (HoleIdx > Top && Cmp(HeapV[First+Parent], Val)) {
00312     HeapV[First+HoleIdx] = HeapV[First+Parent];
00313     HoleIdx = Parent;  Parent = (HoleIdx-1)/2;
00314   }
00315   HeapV[First+HoleIdx] = Val;
00316 }
00317 
00318 template <class TVal, class TCmp>
00319 void THeap<TVal, TCmp>::AdjustHeap(const int& First, int HoleIdx, const int& Len, TVal Val) {
00320   const int Top = HoleIdx;
00321   int Right = 2*HoleIdx+2;
00322   while (Right < Len) {
00323     if (Cmp(HeapV[First+Right], HeapV[First+Right-1])) { Right--; }
00324     HeapV[First+HoleIdx] = HeapV[First+Right];
00325     HoleIdx = Right;  Right = 2*(Right+1); }
00326   if (Right == Len) {
00327     HeapV[First+HoleIdx] = HeapV[First+Right-1];
00328     HoleIdx = Right-1; }
00329   PushHeap(First, HoleIdx, Top, Val);
00330 }
00331 
00332 template <class TVal, class TCmp>
00333 void THeap<TVal, TCmp>::MakeHeap(const int& First, const int& Len) {
00334   if (Len < 2) { return; }
00335   int Parent = (Len-2)/2;
00336   while (true) {
00337     AdjustHeap(First, Parent, Len, HeapV[First+Parent]);
00338     if (Parent == 0) { return; }
00339     Parent--;
00340   }
00341 }
00342