SNAP Library , Developer Reference
2013-01-07 14:03:36
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 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 };