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