#include #include #include #include #include #include #include #include #include #include #include using namespace std; typedef long long int64; typedef pair PII; typedef struct { int first, second, third; } TIII; struct PAIR { int a, b; PAIR(int a0, int b0) { a=min(a0,b0); b=max(a0,b0); } }; bool operator<(const PAIR &x, const PAIR &y) { if (x.a==y.a) return x.bb) swap(a,b); if (b>c) swap(b,c); if (a>b) swap(a,b); } }; bool operator<(const TRIPLE &x, const TRIPLE &y) { if (x.a==y.a) { if (x.b==y.b) return x.c common2; unordered_map common3; unordered_map::iterator common2_it; unordered_map::iterator common3_it; #define common3_get(x) (((common3_it=common3.find(x))!=common3.end())?(common3_it->second):0) #define common2_get(x) (((common2_it=common2.find(x))!=common2.end())?(common2_it->second):0) int n,m; // n = number of nodes, m = number of edges int *deg; // degrees of individual nodes PAIR *edges; // list of edges int **adj; // adj[x] - adjacency list of node x PII **inc; // inc[x] - incidence list of node x: (y, edge id) bool adjacent_list(int x, int y) { return binary_search(adj[x],adj[x]+deg[x],y); } int *adj_matrix; // compressed adjacency matrix const int adj_chunk = 8*sizeof(int); bool adjacent_matrix(int x, int y) { return adj_matrix[(x*n+y)/adj_chunk]&(1<<((x*n+y)%adj_chunk)); } bool (*adjacent)(int,int); int getEdgeId(int x, int y) { return inc[x][lower_bound(adj[x],adj[x]+deg[x],y)-adj[x]].second; } int64 **orbit; // orbit[x][o] - how many times does node x participate in orbit o int64 **eorbit; // eorbit[x][o] - how many times does node x participate in edge orbit o /** count graphlets on max 4 nodes */ void count4() { clock_t startTime, endTime; startTime = clock(); clock_t startTime_all, endTime_all; startTime_all = startTime; int frac,frac_prev; // precompute triangles that span over edges printf("stage 1 - precomputing common nodes\n"); int *tri = (int*)calloc(m,sizeof(int)); frac_prev=-1; for (int i=0;i= x) break; nn=0; for (int ny=0;ny= y) break; if (adjacent(x,z)==0) continue; neigh[nn++]=z; } for (int i=0;i= x) break; nn=0; for (int ny=0;ny= y) break; if (neighx[z]==-1) continue; int xz=neighx[z]; neigh[nn]=z; neigh_edges[nn]={xz, yz}; nn++; } for (int i=0;i=0;nx--) { int y=inc[x][nx].first, xy=inc[x][nx].second; if (y <= x) break; nn=0; for (int ny=deg[y]-1;ny>=0;ny--) { int z=adj[y][ny]; if (z <= y) break; if (adjacent(x,z)==0) continue; neigh[nn++]=z; } for (int i=0;i= x) break; nn=0; for (int ny=0;ny= y) break; if (adjacent(x,z)) { neigh[nn++]=z; } } for (int i=0;i2 && tri[xb]>2)?(common3_get(TRIPLE(x,a,b))-1):0; f_71 += (tri[xa]>2 && tri[xc]>2)?(common3_get(TRIPLE(x,a,c))-1):0; f_71 += (tri[xb]>2 && tri[xc]>2)?(common3_get(TRIPLE(x,b,c))-1):0; f_67 += tri[xa]-2+tri[xb]-2+tri[xc]-2; f_66 += common2_get(PAIR(a,b))-2; f_66 += common2_get(PAIR(a,c))-2; f_66 += common2_get(PAIR(b,c))-2; f_58 += deg[x]-3; f_57 += deg[a]-3+deg[b]-3+deg[c]-3; } } // x = orbit-13 (diamond) for (int nx2=0;nx21 && tri[xc]>1)?(common3_get(TRIPLE(x,b,c))-1):0; f_68 += common3_get(TRIPLE(a,b,c))-1; f_64 += common2_get(PAIR(b,c))-2; f_61 += tri[xb]-1+tri[xc]-1; f_60 += common2_get(PAIR(a,b))-1; f_60 += common2_get(PAIR(a,c))-1; f_55 += tri[xa]-2; f_48 += deg[b]-2+deg[c]-2; f_42 += deg[x]-3; f_41 += deg[a]-3; } } // x = orbit-12 (diamond) for (int nx2=nx1+1;nx21)?common3_get(TRIPLE(a,b,c)):0; f_63 += common_x[c]-2; f_59 += tri[ac]-1+common2_get(PAIR(b,c))-1; f_54 += common2_get(PAIR(a,b))-2; f_47 += deg[x]-2; f_46 += deg[c]-2; f_40 += deg[a]-3+deg[b]-3; } } // x = orbit-8 (cycle) for (int nx2=nx1+1;nx20)?common3_get(TRIPLE(a,b,c)):0; f_53 += tri[xa]+tri[xb]; f_51 += tri[ac]+common2_get(PAIR(c,b)); f_50 += common_x[c]-2; f_49 += common_a[b]-2; f_38 += deg[x]-2; f_37 += deg[a]-2+deg[b]-2; f_36 += deg[c]-2; } } // x = orbit-11 (paw) for (int nx2=nx1+1;nx21 && tri[ac]>1)?common3_get(TRIPLE(a,b,c)):0; f_45 += common2_get(PAIR(b,c))-1; f_39 += tri[ab]-1+tri[ac]-1; f_31 += deg[a]-3; f_28 += deg[x]-1; f_24 += deg[b]-2+deg[c]-2; } } // x = orbit-4 (path) for (int na=0;na= x) break; nn=0; for (int ny=0;ny= y) break; if (neighx[z]==-1) continue; int xz=neighx[z]; neigh[nn]=z; neigh_edges[nn]={xz, yz}; nn++; } for (int i=0;i=x) break; // common nodes of y and some other node for (int i=0;i> n >> m; int d_max=0; edges = (PAIR*)malloc(m*sizeof(PAIR)); deg = (int*)calloc(n,sizeof(int)); for (int i=0;i> a >> b; if (!(0<=a && a(edges,edges+m).size())!=m) { cerr << "Input file contains duplicate undirected edges." << endl; return 0; } // set up adjacency matrix if it's smaller than 100MB if ((int64)n*n < 100LL*1024*1024*8) { adjacent = adjacent_matrix; adj_matrix = (int*)calloc((n*n)/adj_chunk+1,sizeof(int)); for (int i=0;i