SNAP Library 2.2, Developer Reference  2014-03-11 19:15:55
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
graphcounter.cpp
Go to the documentation of this file.
00001 #include "stdafx.h"
00002 #include "graphcounter.h"
00003 
00004 //Number of directed connected 5-node subgraphs = 9364
00005 
00007 // Directed 3 graph implementation
00008 int TD3Graph::m_numOfGraphs = 13;
00009 int TD3Graph::m_graphIds[] = {6,12,14,36,38,46,78,102,140,164,166,174,238};
00010 
00011 int TD3Graph::getId(const PNGraph &G, const TIntV &sg) {
00012         int id=0;
00013         //Node 0
00014         if(TGraphEnumUtils::IsEdge(G, sg[0], sg[1])) id+=2;
00015         if(TGraphEnumUtils::IsEdge(G, sg[0], sg[2])) id+=4;
00016         //Node 1
00017         if(TGraphEnumUtils::IsEdge(G, sg[1], sg[0])) id+=8;
00018         if(TGraphEnumUtils::IsEdge(G, sg[1], sg[2])) id+=32;
00019         //Node 2
00020         if(TGraphEnumUtils::IsEdge(G, sg[2], sg[0])) id+=64;
00021         if(TGraphEnumUtils::IsEdge(G, sg[2], sg[1])) id+=128;
00022         //
00023         return id;
00024 }
00026 // Directed 4 graph implementation
00027 int TD4Graph::m_numOfGraphs = 199;
00028 int TD4Graph::m_graphIds[] = {14, 28, 30, 74, 76, 78, 90, 92, 94, 204, 206, 222, 280, 282, 286, 
00029                                                                 328, 330, 332, 334, 344, 346, 348, 350, 390, 392, 394, 396, 398, 
00030                                                                 404, 406, 408, 410, 412, 414, 454, 456, 458, 460, 462, 468, 470, 
00031                                                                 472, 474, 476, 478, 856, 858, 862, 904, 906, 908, 910, 922, 924, 
00032                                                                 926, 972, 974, 990, 2184, 2186, 2190, 2202, 2204, 2206, 2252, 2254, 
00033                                                                 2270, 2458, 2462, 2506, 2510, 2524, 2526, 3038, 4370, 4374, 4382, 
00034                                                                 4418, 4420, 4422, 4424, 4426, 4428, 4430, 4434, 4436, 4438, 4440, 
00035                                                                 4442, 4444, 4446, 4546, 4548, 4550, 4556, 4558, 4562, 4564, 4566, 
00036                                                                 4572, 4574, 4678, 4682, 4686, 4692, 4694, 4698, 4700, 4702, 4740, 
00037                                                                 4742, 4748, 4750, 4758, 4764, 4766, 4812, 4814, 4830, 4946, 4950, 
00038                                                                 4952, 4954, 4958, 4994, 4998, 5002, 5004, 5006, 5010, 5012, 5014, 
00039                                                                 5016, 5018, 5020, 5022, 5058, 5062, 5064, 5066, 5068, 5070, 5074, 
00040                                                                 5076, 5078, 5080, 5082, 5084, 5086, 6342, 6348, 6350, 6356, 6358, 
00041                                                                 6364, 6366, 6550, 6552, 6554, 6558, 6598, 6602, 6604, 6606, 6614, 
00042                                                                 6616, 6618, 6620, 6622, 6854, 6858, 6862, 6870, 6874, 6876, 6878, 
00043                                                                 7126, 7128, 7130, 7134, 13142, 13146, 13148, 13150, 13260, 13262, 
00044                                                                 13278, 14678, 14686, 14790, 14798, 14810, 14812, 14814, 15258, 
00045                                                                 15262, 15310, 15326, 31710 };
00046 
00047 int TD4Graph::getId(const PNGraph &G, const TIntV &sg) {
00048         int id=0;
00049         //Node 0
00050         if(TGraphEnumUtils::IsEdge(G, sg[0], sg[1])) id+=2;
00051         if(TGraphEnumUtils::IsEdge(G, sg[0], sg[2])) id+=4;
00052         if(TGraphEnumUtils::IsEdge(G, sg[0], sg[3])) id+=8;
00053         //Node 1
00054         if(TGraphEnumUtils::IsEdge(G, sg[1], sg[0])) id+=16;
00055         if(TGraphEnumUtils::IsEdge(G, sg[1], sg[2])) id+=64;
00056         if(TGraphEnumUtils::IsEdge(G, sg[1], sg[3])) id+=128;
00057         //Node 2
00058         if(TGraphEnumUtils::IsEdge(G, sg[2], sg[0])) id+=256;
00059         if(TGraphEnumUtils::IsEdge(G, sg[2], sg[1])) id+=512;
00060         if(TGraphEnumUtils::IsEdge(G, sg[2], sg[3])) id+=2048;
00061         //Node 3
00062         if(TGraphEnumUtils::IsEdge(G, sg[3], sg[0])) id+=4096;
00063         if(TGraphEnumUtils::IsEdge(G, sg[3], sg[1])) id+=8192;
00064         if(TGraphEnumUtils::IsEdge(G, sg[3], sg[2])) id+=16384;
00065         //
00066         return id;
00067 }
00068 
00070 // Directed 3 or 4 graph counter implementation
00071 TD34GraphCounter::TD34GraphCounter(int GraphSz) {
00072         IAssert(GraphSz==3 || GraphSz==4);
00073         //
00074         m_subGraphSize = GraphSz;
00075         //
00076         int numOfGraphs = 0;
00077         if(GraphSz==3) numOfGraphs = TD3Graph::m_numOfGraphs;
00078         else if(GraphSz==4) numOfGraphs = TD4Graph::m_numOfGraphs;
00079         //
00080         for(int i=0; i<numOfGraphs; i++) {
00081                 int graphId = 0;
00082                 if(GraphSz==3) graphId = TD3Graph::m_graphIds[i];
00083                 else if(GraphSz==4) graphId = TD4Graph::m_graphIds[i];
00084                 //
00085                 TVec<PNGraph> isoG;
00086                 TGraphEnumUtils::GetIsoGraphs(graphId, GraphSz, isoG);
00087                 //
00088                 TVec<uint64> graphIds(isoG.Len());
00089                 uint64 minGraphId = TGraphEnumUtils::GetMinAndGraphIds(isoG, graphIds);
00090                 for(int j=0; j<graphIds.Len(); j++)
00091                         m_graphMaps.AddDat((int)graphIds[j], (int)minGraphId);
00092                 //
00093                 m_graphCounters.AddDat((int)minGraphId, 0);
00094         }
00095 }
00096 void TD34GraphCounter::operator()(const PNGraph &G, const TIntV &sg) {
00097         int graphId = 0;
00098         if(m_subGraphSize==3) graphId = TD3Graph::getId(G, sg);
00099         else if(m_subGraphSize==4) graphId = TD4Graph::getId(G, sg);
00100         //
00101         if(!m_graphMaps.IsKey(graphId)) { printf("This graph does not exist: %d\n", graphId); getchar(); return; }
00102         int minGraphId = m_graphMaps.GetDat(graphId);
00103         //
00104         m_graphCounters.GetDat(minGraphId)++;
00105 }
00106 
00107 PNGraph TD34GraphCounter::GetGraph(const int& GraphId) const {
00108   PNGraph G = TNGraph::New();
00109   TGraphEnumUtils::GetGraph(GraphId, m_subGraphSize, G);
00110   return G;
00111 }
00112 
00114 // Directed graph counter implementation
00115 void TDGraphCounter::operator()(const PNGraph &G, const TIntV &sg) {
00116         uint64 graphId = TGraphEnumUtils::GraphId(G, sg);
00117         //
00118         if(m_graphMaps.IsKey(graphId)) {
00119                 TUInt64 minGraphId = m_graphMaps.GetDat(graphId);
00120                 m_graphCounters.GetDat(minGraphId)++;
00121         }else{
00122                 TVec<PNGraph> isoG;
00123                 TGraphEnumUtils::GetIsoGraphs(graphId, sg.Len(), isoG);
00124                 //
00125                 TVec<uint64> graphIds(isoG.Len());
00126                 uint64 minGraphId = TGraphEnumUtils::GetMinAndGraphIds(isoG, graphIds);
00127                 for(int j=0; j<graphIds.Len(); j++)
00128                         m_graphMaps.AddDat(graphIds[j], minGraphId);
00129                 //
00130                 m_graphCounters.AddDat(minGraphId, 1);
00131         }
00132 }
00133 
00135 // Directed ghash graph counter implementation
00136 void TDGHashGraphCounter::operator()(const PNGraph &G, const TIntV &sg) {
00137         PNGraph indG = TNGraph::New();
00138         TGraphEnumUtils::GetIndGraph(G, sg, indG);
00139         //
00140         if(m_graphs.IsKey(indG))
00141                 m_graphs.GetDat(indG)++;
00142         else m_graphs.AddDat(indG, 1);
00143 }
00144 
00146 // TGraphEnumUtils implementation
00147 void TGraphEnumUtils::GetNormalizedMap(const PNGraph &G, THash<TInt,TInt> &map) {
00148         int nId=0;
00149         for(TNGraph::TNodeI it=G->BegNI(); it<G->EndNI(); it++) {
00150                 //printf("%d -> %d\n", it.GetId(), nId);
00151                 map.AddDat(it.GetId(), nId);
00152                 nId++;
00153         }
00154 }
00155 
00156 void TGraphEnumUtils::GetPermutations(TIntV &v, int start, TVec<TIntV> &perms) {
00157         int n = v.Len();
00158         if (start == n-1) perms.Add(v);
00159         else {
00160                 for (int i = start; i < n; i++) {
00161                         int tmp = v[i];
00162                         v[i] = v[start];
00163                         v[start] = tmp;
00164                         GetPermutations(v, start+1, perms);
00165                         //
00166                         v[start] = v[i];
00167                         v[i] = tmp;
00168                 }
00169         }
00170 }
00171 
00172 void TGraphEnumUtils::GetNormalizedGraph(const PNGraph &G, PNGraph &nG) {
00173         //Get bijective map from original node ids to normalized node ids(0,1,2,...)
00174         THash<TInt,TInt> map;
00175         GetNormalizedMap(G, map);
00176         //Add nodes
00177         for(int i=0; i<G->GetNodes(); i++) nG->AddNode(i);
00178         //Add edges
00179         for(TNGraph::TEdgeI eIt=G->BegEI(); eIt<G->EndEI(); eIt++) {
00180                 int srcId = eIt.GetSrcNId();
00181                 int dstId = eIt.GetDstNId();
00182                 //
00183                 int mSrcId = map.GetDat(srcId);
00184                 int mDstId = map.GetDat(dstId);
00185                 //
00186                 nG->AddEdge(mSrcId, mDstId);
00187         }
00188 }
00189 
00190 void TGraphEnumUtils::GetEdges(uint64 graphId, int nodes, TVec<TPair<int,int> > &edges) {
00191         for(int row=0; row<nodes; row++) {
00192                 for(int col=0; col<nodes; col++) {
00193                         int n = row*nodes+col;
00194                         //
00195                         uint64 bits = graphId >> n;
00196                         uint64 mask = 1;
00197                         if((bits & mask)==1) edges.Add(TPair<int,int>(row, col));
00198                 }
00199         }
00200 }
00201 
00202 void TGraphEnumUtils::GetIsoGraphs(uint64 graphId, int nodes, TVec<PNGraph> &isoG) {
00203         TIntV v(nodes); for(int i=0; i<nodes; i++) v[i]=i;
00204         TVec<TIntV> perms; GetPermutations(v, 0, perms);
00205         isoG.Gen(perms.Len());
00206         //
00207         TVec<TPair<int,int> > edges;
00208         GetEdges(graphId, nodes, edges);
00209         //
00210         for(int i=0; i<perms.Len(); i++) {
00211                 isoG[i] = TNGraph::New();
00212                 //Add nodes
00213                 for(int j=0; j<nodes; j++) isoG[i]->AddNode(j);
00214                 //Add edges
00215                 for(int j=0; j<edges.Len(); j++) {
00216                         int srcId = edges[j].Val1;
00217                         int dstId = edges[j].Val2;
00218                         //
00219                         int pSrcId = perms[i][srcId];
00220                         int pDstId = perms[i][dstId];
00221                         //
00222                         isoG[i]->AddEdge(pSrcId, pDstId);
00223                 }
00224         }
00225 }
00226 
00227 void TGraphEnumUtils::GetIsoGraphs(const PNGraph &G, TVec<PNGraph> &isoG) {
00228         int nodes = G->GetNodes();
00229         //
00230         TIntV v(nodes); for(int i=0; i<nodes; i++) v[i]=i;
00231         TVec<TIntV> perms; GetPermutations(v, 0, perms);
00232         isoG.Gen(perms.Len());
00233         //
00234         for(int i=0; i<perms.Len(); i++) {
00235                 isoG[i] = TNGraph::New();
00236                 //Add nodes
00237                 for(int j=0; j<nodes; j++) isoG[i]->AddNode(j);
00238                 //Add edges
00239                 for(TNGraph::TEdgeI eIt=G->BegEI(); eIt<G->EndEI(); eIt++) {
00240                         int srcId = eIt.GetSrcNId();
00241                         int dstId = eIt.GetDstNId();
00242                         //
00243                         int pSrcId = perms[i][srcId];
00244                         int pDstId = perms[i][dstId];
00245                         //
00246                         isoG[i]->AddEdge(pSrcId, pDstId);
00247                 }
00248         }
00249 }
00250 
00251 void TGraphEnumUtils::GetIndGraph(const PNGraph &G, const TIntV &sg, PNGraph &indG) {
00252         //Add nodes
00253         for(int i=0; i<sg.Len(); i++) indG->AddNode(sg[i]);
00254         //Add edges
00255         for(int i=0; i<sg.Len(); i++) {
00256                 int nId = sg[i];
00257                 TNGraph::TNodeI nIt = G->GetNI(nId);
00258                 //
00259                 int deg = nIt.GetOutDeg();
00260                 for(int j=0; j<deg; j++) {
00261                         int dstId = nIt.GetNbrNId(j);
00262                         if(nId == dstId) continue;
00263                         //
00264                         if(indG->IsNode(dstId)) indG->AddEdge(nId, dstId);
00265                 }
00266         }
00267 }
00268 
00269 void TGraphEnumUtils::GetGraph(uint64 graphId, int nodes, PNGraph &G) {
00270   G->Clr();
00271         //Add nodes;
00272         for(int i=0; i<nodes; i++) G->AddNode(i);
00273         //Add edges
00274         for(int row=0; row<nodes; row++) {
00275                 for(int col=0; col<nodes; col++) {
00276                         int n = row*nodes+col;
00277                         //
00278                         uint64 bits = graphId >> n;
00279                         uint64 mask = 1;
00280                         if((bits & mask)==1) G->AddEdge(row, col);
00281                 }
00282         }
00283 }
00284 
00285 uint64 TGraphEnumUtils::GraphId(const PNGraph &G) {
00286         int nodes = G->GetNodes();
00287         uint64 id=0;
00288         for(TNGraph::TEdgeI it=G->BegEI(); it<G->EndEI(); it++) {
00289                 int srcId = it.GetSrcNId();
00290                 int dstId = it.GetDstNId();
00291                 //
00292                 id += TMath::Pow2(srcId*nodes + dstId);
00293         }
00294         //
00295         return id;
00296 }
00297 
00298 uint64 TGraphEnumUtils::GraphId(const PNGraph &G, const TIntV &sg) {
00299         int nodes = sg.Len();
00300         uint64 graphId = 0;
00301         for(int i=0; i<nodes; i++) {
00302                 for(int j=0; j<nodes; j++) {
00303                         if(i==j) continue;
00304                         //
00305                         if(TGraphEnumUtils::IsEdge(G, sg[i], sg[j])) graphId+=TMath::Pow2(i*nodes + j);
00306                 }
00307         }
00308         return graphId;
00309 }
00310 
00311 uint64 TGraphEnumUtils::GetMinAndGraphIds(const TVec<PNGraph> &isoG, TVec<uint64> &graphIds) {
00312         IAssert(isoG.Len() > 0);
00313         //
00314         uint64 minGraphId = GraphId(isoG[0]);
00315         graphIds.Add(minGraphId);
00316         //
00317         for(int i=1; i<isoG.Len(); i++) {
00318                 uint64 curGraphId = GraphId(isoG[i]);
00319                 if(minGraphId > curGraphId) minGraphId=curGraphId;
00320                 //
00321                 graphIds.Add(curGraphId);
00322         }
00323         //
00324         return minGraphId;
00325 }