You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

orca.cpp 61KB

4 years ago
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532
  1. #include <cstdio>
  2. #include <cstdlib>
  3. #include <cstring>
  4. #include <cassert>
  5. #include <ctime>
  6. #include <iostream>
  7. #include <fstream>
  8. #include <set>
  9. #include <sstream>
  10. #include <unordered_map>
  11. #include <algorithm>
  12. using namespace std;
  13. typedef long long int64;
  14. typedef pair<int,int> PII;
  15. typedef struct { int first, second, third; } TIII;
  16. struct PAIR {
  17. int a, b;
  18. PAIR(int a0, int b0) { a=min(a0,b0); b=max(a0,b0); }
  19. };
  20. bool operator<(const PAIR &x, const PAIR &y) {
  21. if (x.a==y.a) return x.b<y.b;
  22. else return x.a<y.a;
  23. }
  24. bool operator==(const PAIR &x, const PAIR &y) {
  25. return x.a==y.a && x.b==y.b;
  26. }
  27. struct hash_PAIR {
  28. size_t operator()(const PAIR &x) const {
  29. return (x.a<<8) ^ (x.b<<0);
  30. }
  31. };
  32. struct TRIPLE {
  33. int a, b, c;
  34. TRIPLE(int a0, int b0, int c0) {
  35. a=a0; b=b0; c=c0;
  36. if (a>b) swap(a,b);
  37. if (b>c) swap(b,c);
  38. if (a>b) swap(a,b);
  39. }
  40. };
  41. bool operator<(const TRIPLE &x, const TRIPLE &y) {
  42. if (x.a==y.a) {
  43. if (x.b==y.b) return x.c<y.c;
  44. else return x.b<y.b;
  45. } else return x.a<y.a;
  46. }
  47. bool operator==(const TRIPLE &x, const TRIPLE &y) {
  48. return x.a==y.a && x.b==y.b && x.c==y.c;
  49. }
  50. struct hash_TRIPLE {
  51. size_t operator()(const TRIPLE &x) const {
  52. return (x.a<<16) ^ (x.b<<8) ^ (x.c<<0);
  53. }
  54. };
  55. unordered_map<PAIR, int, hash_PAIR> common2;
  56. unordered_map<TRIPLE, int, hash_TRIPLE> common3;
  57. unordered_map<PAIR, int, hash_PAIR>::iterator common2_it;
  58. unordered_map<TRIPLE, int, hash_TRIPLE>::iterator common3_it;
  59. #define common3_get(x) (((common3_it=common3.find(x))!=common3.end())?(common3_it->second):0)
  60. #define common2_get(x) (((common2_it=common2.find(x))!=common2.end())?(common2_it->second):0)
  61. int n,m; // n = number of nodes, m = number of edges
  62. int *deg; // degrees of individual nodes
  63. PAIR *edges; // list of edges
  64. int **adj; // adj[x] - adjacency list of node x
  65. PII **inc; // inc[x] - incidence list of node x: (y, edge id)
  66. bool adjacent_list(int x, int y) { return binary_search(adj[x],adj[x]+deg[x],y); }
  67. int *adj_matrix; // compressed adjacency matrix
  68. const int adj_chunk = 8*sizeof(int);
  69. bool adjacent_matrix(int x, int y) { return adj_matrix[(x*n+y)/adj_chunk]&(1<<((x*n+y)%adj_chunk)); }
  70. bool (*adjacent)(int,int);
  71. int getEdgeId(int x, int y) { return inc[x][lower_bound(adj[x],adj[x]+deg[x],y)-adj[x]].second; }
  72. int64 **orbit; // orbit[x][o] - how many times does node x participate in orbit o
  73. int64 **eorbit; // eorbit[x][o] - how many times does node x participate in edge orbit o
  74. /** count graphlets on max 4 nodes */
  75. void count4() {
  76. clock_t startTime, endTime;
  77. startTime = clock();
  78. clock_t startTime_all, endTime_all;
  79. startTime_all = startTime;
  80. int frac,frac_prev;
  81. // precompute triangles that span over edges
  82. printf("stage 1 - precomputing common nodes\n");
  83. int *tri = (int*)calloc(m,sizeof(int));
  84. frac_prev=-1;
  85. for (int i=0;i<m;i++) {
  86. frac = 100LL*i/m;
  87. if (frac!=frac_prev) {
  88. printf("%d%%\r",frac);
  89. frac_prev=frac;
  90. }
  91. int x=edges[i].a, y=edges[i].b;
  92. for (int xi=0,yi=0; xi<deg[x] && yi<deg[y]; ) {
  93. if (adj[x][xi]==adj[y][yi]) { tri[i]++; xi++; yi++; }
  94. else if (adj[x][xi]<adj[y][yi]) { xi++; }
  95. else { yi++; }
  96. }
  97. }
  98. endTime = clock();
  99. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  100. startTime = endTime;
  101. // count full graphlets
  102. printf("stage 2 - counting full graphlets\n");
  103. int64 *C4 = (int64*)calloc(n,sizeof(int64));
  104. int *neigh = (int*)malloc(n*sizeof(int)), nn;
  105. frac_prev=-1;
  106. for (int x=0;x<n;x++) {
  107. frac = 100LL*x/n;
  108. if (frac!=frac_prev) {
  109. printf("%d%%\r",frac);
  110. frac_prev=frac;
  111. }
  112. for (int nx=0;nx<deg[x];nx++) {
  113. int y=adj[x][nx];
  114. if (y >= x) break;
  115. nn=0;
  116. for (int ny=0;ny<deg[y];ny++) {
  117. int z=adj[y][ny];
  118. if (z >= y) break;
  119. if (adjacent(x,z)==0) continue;
  120. neigh[nn++]=z;
  121. }
  122. for (int i=0;i<nn;i++) {
  123. int z = neigh[i];
  124. for (int j=i+1;j<nn;j++) {
  125. int zz = neigh[j];
  126. if (adjacent(z,zz)) {
  127. C4[x]++; C4[y]++; C4[z]++; C4[zz]++;
  128. }
  129. }
  130. }
  131. }
  132. }
  133. endTime = clock();
  134. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  135. startTime = endTime;
  136. // set up a system of equations relating orbits for every node
  137. printf("stage 3 - building systems of equations\n");
  138. int *common = (int*)calloc(n,sizeof(int));
  139. int *common_list = (int*)malloc(n*sizeof(int)), nc=0;
  140. frac_prev=-1;
  141. for (int x=0;x<n;x++) {
  142. frac = 100LL*x/n;
  143. if (frac!=frac_prev) {
  144. printf("%d%%\r",frac);
  145. frac_prev=frac;
  146. }
  147. int64 f_12_14=0, f_10_13=0;
  148. int64 f_13_14=0, f_11_13=0;
  149. int64 f_7_11=0, f_5_8=0;
  150. int64 f_6_9=0, f_9_12=0, f_4_8=0, f_8_12=0;
  151. int64 f_14=C4[x];
  152. for (int i=0;i<nc;i++) common[common_list[i]]=0;
  153. nc=0;
  154. orbit[x][0]=deg[x];
  155. // x - middle node
  156. for (int nx1=0;nx1<deg[x];nx1++) {
  157. int y=inc[x][nx1].first, ey=inc[x][nx1].second;
  158. for (int ny=0;ny<deg[y];ny++) {
  159. int z=inc[y][ny].first, ez=inc[y][ny].second;
  160. if (adjacent(x,z)) { // triangle
  161. if (z<y) {
  162. f_12_14 += tri[ez]-1;
  163. f_10_13 += (deg[y]-1-tri[ez])+(deg[z]-1-tri[ez]);
  164. }
  165. } else {
  166. if (common[z]==0) common_list[nc++]=z;
  167. common[z]++;
  168. }
  169. }
  170. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  171. int z=inc[x][nx2].first, ez=inc[x][nx2].second;
  172. if (adjacent(y,z)) { // triangle
  173. orbit[x][3]++;
  174. f_13_14 += (tri[ey]-1)+(tri[ez]-1);
  175. f_11_13 += (deg[x]-1-tri[ey])+(deg[x]-1-tri[ez]);
  176. } else { // path
  177. orbit[x][2]++;
  178. f_7_11 += (deg[x]-1-tri[ey]-1)+(deg[x]-1-tri[ez]-1);
  179. f_5_8 += (deg[y]-1-tri[ey])+(deg[z]-1-tri[ez]);
  180. }
  181. }
  182. }
  183. // x - side node
  184. for (int nx1=0;nx1<deg[x];nx1++) {
  185. int y=inc[x][nx1].first, ey=inc[x][nx1].second;
  186. for (int ny=0;ny<deg[y];ny++) {
  187. int z=inc[y][ny].first, ez=inc[y][ny].second;
  188. if (x==z) continue;
  189. if (!adjacent(x,z)) { // path
  190. orbit[x][1]++;
  191. f_6_9 += (deg[y]-1-tri[ey]-1);
  192. f_9_12 += tri[ez];
  193. f_4_8 += (deg[z]-1-tri[ez]);
  194. f_8_12 += (common[z]-1);
  195. }
  196. }
  197. }
  198. // solve system of equations
  199. orbit[x][14]=(f_14);
  200. orbit[x][13]=(f_13_14-6*f_14)/2;
  201. orbit[x][12]=(f_12_14-3*f_14);
  202. orbit[x][11]=(f_11_13-f_13_14+6*f_14)/2;
  203. orbit[x][10]=(f_10_13-f_13_14+6*f_14);
  204. orbit[x][9]=(f_9_12-2*f_12_14+6*f_14)/2;
  205. orbit[x][8]=(f_8_12-2*f_12_14+6*f_14)/2;
  206. orbit[x][7]=(f_13_14+f_7_11-f_11_13-6*f_14)/6;
  207. orbit[x][6]=(2*f_12_14+f_6_9-f_9_12-6*f_14)/2;
  208. orbit[x][5]=(2*f_12_14+f_5_8-f_8_12-6*f_14);
  209. orbit[x][4]=(2*f_12_14+f_4_8-f_8_12-6*f_14);
  210. }
  211. endTime = clock();
  212. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  213. endTime_all = endTime;
  214. printf("total: %.2f\n", (double)(endTime_all-startTime_all)/CLOCKS_PER_SEC);
  215. }
  216. /** count edge orbits of graphlets on max 4 nodes */
  217. void ecount4() {
  218. clock_t startTime, endTime;
  219. startTime = clock();
  220. clock_t startTime_all, endTime_all;
  221. startTime_all = startTime;
  222. int frac,frac_prev;
  223. // precompute triangles that span over edges
  224. printf("stage 1 - precomputing common nodes\n");
  225. int *tri = (int*)calloc(m,sizeof(int));
  226. frac_prev=-1;
  227. for (int i=0;i<m;i++) {
  228. frac = 100LL*i/m;
  229. if (frac!=frac_prev) {
  230. printf("%d%%\r",frac);
  231. frac_prev=frac;
  232. }
  233. int x=edges[i].a, y=edges[i].b;
  234. for (int xi=0,yi=0; xi<deg[x] && yi<deg[y]; ) {
  235. if (adj[x][xi]==adj[y][yi]) { tri[i]++; xi++; yi++; }
  236. else if (adj[x][xi]<adj[y][yi]) { xi++; }
  237. else { yi++; }
  238. }
  239. }
  240. endTime = clock();
  241. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  242. startTime = endTime;
  243. // count full graphlets
  244. printf("stage 2 - counting full graphlets\n");
  245. int64 *C4 = (int64*)calloc(m,sizeof(int64));
  246. int *neighx = (int*)malloc(n*sizeof(int)); // lookup table - edges to neighbors of x
  247. memset(neighx,-1,n*sizeof(int));
  248. int *neigh = (int*)malloc(n*sizeof(int)), nn; // lookup table - common neighbors of x and y
  249. PII *neigh_edges = (PII*)malloc(n*sizeof(PII)); // list of common neighbors of x and y
  250. frac_prev=-1;
  251. for (int x=0;x<n;x++) {
  252. frac = 100LL*x/n;
  253. if (frac!=frac_prev) {
  254. printf("%d%%\r",frac);
  255. frac_prev=frac;
  256. }
  257. for (int nx=0;nx<deg[x];nx++) {
  258. int y=inc[x][nx].first, xy=inc[x][nx].second;
  259. neighx[y]=xy;
  260. }
  261. for (int nx=0;nx<deg[x];nx++) {
  262. int y=inc[x][nx].first, xy=inc[x][nx].second;
  263. if (y >= x) break;
  264. nn=0;
  265. for (int ny=0;ny<deg[y];ny++) {
  266. int z=inc[y][ny].first, yz=inc[y][ny].second;
  267. if (z >= y) break;
  268. if (neighx[z]==-1) continue;
  269. int xz=neighx[z];
  270. neigh[nn]=z;
  271. neigh_edges[nn]={xz, yz};
  272. nn++;
  273. }
  274. for (int i=0;i<nn;i++) {
  275. int z = neigh[i], xz = neigh_edges[i].first, yz = neigh_edges[i].second;
  276. for (int j=i+1;j<nn;j++) {
  277. int w = neigh[j], xw = neigh_edges[j].first, yw = neigh_edges[j].second;
  278. if (adjacent(z,w)) {
  279. C4[xy]++;
  280. C4[xz]++; C4[yz]++;
  281. C4[xw]++; C4[yw]++;
  282. // another iteration to count this last(smallest) edge instead of calling getEdgeId
  283. //int zw=getEdgeId(z,w); C4[zw]++;
  284. }
  285. }
  286. }
  287. }
  288. for (int nx=0;nx<deg[x];nx++) {
  289. int y=inc[x][nx].first, xy=inc[x][nx].second;
  290. neighx[y]=-1;
  291. }
  292. }
  293. endTime = clock();
  294. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  295. startTime = endTime;
  296. // count full graphlets for the smallest edge
  297. for (int x=0;x<n;x++) {
  298. frac = 100LL*x/n;
  299. if (frac!=frac_prev) {
  300. printf("%d%%\r",frac);
  301. frac_prev=frac;
  302. }
  303. for (int nx=deg[x]-1;nx>=0;nx--) {
  304. int y=inc[x][nx].first, xy=inc[x][nx].second;
  305. if (y <= x) break;
  306. nn=0;
  307. for (int ny=deg[y]-1;ny>=0;ny--) {
  308. int z=adj[y][ny];
  309. if (z <= y) break;
  310. if (adjacent(x,z)==0) continue;
  311. neigh[nn++]=z;
  312. }
  313. for (int i=0;i<nn;i++) {
  314. int z = neigh[i];
  315. for (int j=i+1;j<nn;j++) {
  316. int zz = neigh[j];
  317. if (adjacent(z,zz)) {
  318. C4[xy]++;
  319. }
  320. }
  321. }
  322. }
  323. }
  324. endTime = clock();
  325. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  326. startTime = endTime;
  327. // set up a system of equations relating orbits for every node
  328. printf("stage 3 - building systems of equations\n");
  329. int *common = (int*)calloc(n,sizeof(int));
  330. int *common_list = (int*)malloc(n*sizeof(int)), nc=0;
  331. frac_prev=-1;
  332. for (int x=0;x<n;x++) {
  333. frac = 100LL*x/n;
  334. if (frac!=frac_prev) {
  335. printf("%d%%\r",frac);
  336. frac_prev=frac;
  337. }
  338. // common nodes of x and some other node
  339. for (int i=0;i<nc;i++) common[common_list[i]]=0;
  340. nc=0;
  341. for (int nx=0;nx<deg[x];nx++) {
  342. int y=adj[x][nx];
  343. for (int ny=0;ny<deg[y];ny++) {
  344. int z=adj[y][ny];
  345. if (z==x) continue;
  346. if (common[z]==0) common_list[nc++]=z;
  347. common[z]++;
  348. }
  349. }
  350. for (int nx=0;nx<deg[x];nx++) {
  351. int y=inc[x][nx].first, xy=inc[x][nx].second;
  352. int e=xy;
  353. for (int n1=0;n1<deg[x];n1++) {
  354. int z=inc[x][n1].first, xz=inc[x][n1].second;
  355. if (z==y) continue;
  356. if (adjacent(y,z)) { // triangle
  357. if (x<y) {
  358. eorbit[e][1]++;
  359. eorbit[e][10] += tri[xy]-1;
  360. eorbit[e][7] += deg[z]-2;
  361. }
  362. eorbit[e][9] += tri[xz]-1;
  363. eorbit[e][8] += deg[x]-2;
  364. }
  365. }
  366. for (int n1=0;n1<deg[y];n1++) {
  367. int z=inc[y][n1].first, yz=inc[y][n1].second;
  368. if (z==x) continue;
  369. if (!adjacent(x,z)) { // path x-y-z
  370. eorbit[e][0]++;
  371. eorbit[e][6] += tri[yz];
  372. eorbit[e][5] += common[z]-1;
  373. eorbit[e][4] += deg[y]-2;
  374. eorbit[e][3] += deg[x]-1;
  375. eorbit[e][2] += deg[z]-1;
  376. }
  377. }
  378. }
  379. }
  380. // solve system of equations
  381. for (int e=0;e<m;e++) {
  382. eorbit[e][11]=C4[e];
  383. eorbit[e][10]=(eorbit[e][10]-2*eorbit[e][11])/2;
  384. eorbit[e][9]=(eorbit[e][9]-4*eorbit[e][11]);
  385. eorbit[e][8]=(eorbit[e][8]-eorbit[e][9]-4*eorbit[e][10]-4*eorbit[e][11]);
  386. eorbit[e][7]=(eorbit[e][7]-eorbit[e][9]-2*eorbit[e][11]);
  387. eorbit[e][6]=(eorbit[e][6]-eorbit[e][9])/2;
  388. eorbit[e][5]=(eorbit[e][5]-eorbit[e][9])/2;
  389. eorbit[e][4]=(eorbit[e][4]-2*eorbit[e][6]-eorbit[e][8]-eorbit[e][9])/2;
  390. eorbit[e][3]=(eorbit[e][3]-2*eorbit[e][5]-eorbit[e][8]-eorbit[e][9])/2;
  391. eorbit[e][2]=(eorbit[e][2]-2*eorbit[e][5]-2*eorbit[e][6]-eorbit[e][9]);
  392. }
  393. endTime = clock();
  394. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  395. endTime_all = endTime;
  396. printf("total: %.2f\n", (double)(endTime_all-startTime_all)/CLOCKS_PER_SEC);
  397. }
  398. /** count graphlets on max 5 nodes */
  399. void count5() {
  400. clock_t startTime, endTime;
  401. startTime = clock();
  402. clock_t startTime_all, endTime_all;
  403. startTime_all = startTime;
  404. int frac,frac_prev;
  405. // precompute common nodes
  406. printf("stage 1 - precomputing common nodes\n");
  407. frac_prev=-1;
  408. for (int x=0;x<n;x++) {
  409. frac = 100LL*x/n;
  410. if (frac!=frac_prev) {
  411. printf("%d%%\r",frac);
  412. frac_prev=frac;
  413. }
  414. for (int n1=0;n1<deg[x];n1++) {
  415. int a=adj[x][n1];
  416. for (int n2=n1+1;n2<deg[x];n2++) {
  417. int b=adj[x][n2];
  418. PAIR ab=PAIR(a,b);
  419. common2[ab]++;
  420. for (int n3=n2+1;n3<deg[x];n3++) {
  421. int c=adj[x][n3];
  422. int st = adjacent(a,b)+adjacent(a,c)+adjacent(b,c);
  423. if (st<2) continue;
  424. TRIPLE abc=TRIPLE(a,b,c);
  425. common3[abc]++;
  426. }
  427. }
  428. }
  429. }
  430. // precompute triangles that span over edges
  431. int *tri = (int*)calloc(m,sizeof(int));
  432. for (int i=0;i<m;i++) {
  433. int x=edges[i].a, y=edges[i].b;
  434. for (int xi=0,yi=0; xi<deg[x] && yi<deg[y]; ) {
  435. if (adj[x][xi]==adj[y][yi]) { tri[i]++; xi++; yi++; }
  436. else if (adj[x][xi]<adj[y][yi]) { xi++; }
  437. else { yi++; }
  438. }
  439. }
  440. endTime = clock();
  441. printf("%.2f sec\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  442. startTime = endTime;
  443. // count full graphlets
  444. printf("stage 2 - counting full graphlets\n");
  445. int64 *C5 = (int64*)calloc(n,sizeof(int64));
  446. int *neigh = (int*)malloc(n*sizeof(int)), nn;
  447. int *neigh2 = (int*)malloc(n*sizeof(int)), nn2;
  448. frac_prev=-1;
  449. for (int x=0;x<n;x++) {
  450. frac = 100LL*x/n;
  451. if (frac!=frac_prev) {
  452. printf("%d%%\r",frac);
  453. frac_prev=frac;
  454. }
  455. for (int nx=0;nx<deg[x];nx++) {
  456. int y=adj[x][nx];
  457. if (y >= x) break;
  458. nn=0;
  459. for (int ny=0;ny<deg[y];ny++) {
  460. int z=adj[y][ny];
  461. if (z >= y) break;
  462. if (adjacent(x,z)) {
  463. neigh[nn++]=z;
  464. }
  465. }
  466. for (int i=0;i<nn;i++) {
  467. int z = neigh[i];
  468. nn2=0;
  469. for (int j=i+1;j<nn;j++) {
  470. int zz = neigh[j];
  471. if (adjacent(z,zz)) {
  472. neigh2[nn2++]=zz;
  473. }
  474. }
  475. for (int i2=0;i2<nn2;i2++) {
  476. int zz = neigh2[i2];
  477. for (int j2=i2+1;j2<nn2;j2++) {
  478. int zzz = neigh2[j2];
  479. if (adjacent(zz,zzz)) {
  480. C5[x]++; C5[y]++; C5[z]++; C5[zz]++; C5[zzz]++;
  481. }
  482. }
  483. }
  484. }
  485. }
  486. }
  487. endTime = clock();
  488. printf("%.2f sec\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  489. startTime = endTime;
  490. int *common_x = (int*)calloc(n,sizeof(int));
  491. int *common_x_list = (int*)malloc(n*sizeof(int)), ncx=0;
  492. int *common_a = (int*)calloc(n,sizeof(int));
  493. int *common_a_list = (int*)malloc(n*sizeof(int)), nca=0;
  494. // set up a system of equations relating orbit counts
  495. printf("stage 3 - building systems of equations\n");
  496. frac_prev=-1;
  497. for (int x=0;x<n;x++) {
  498. frac = 100LL*x/n;
  499. if (frac!=frac_prev) {
  500. printf("%d%%\r",frac);
  501. frac_prev=frac;
  502. }
  503. for (int i=0;i<ncx;i++) common_x[common_x_list[i]]=0;
  504. ncx=0;
  505. // smaller graphlets
  506. orbit[x][0] = deg[x];
  507. for (int nx1=0;nx1<deg[x];nx1++) {
  508. int a=adj[x][nx1];
  509. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  510. int b=adj[x][nx2];
  511. if (adjacent(a,b)) orbit[x][3]++;
  512. else orbit[x][2]++;
  513. }
  514. for (int na=0;na<deg[a];na++) {
  515. int b=adj[a][na];
  516. if (b!=x && !adjacent(x,b)) {
  517. orbit[x][1]++;
  518. if (common_x[b]==0) common_x_list[ncx++]=b;
  519. common_x[b]++;
  520. }
  521. }
  522. }
  523. int64 f_71=0, f_70=0, f_67=0, f_66=0, f_58=0, f_57=0; // 14
  524. int64 f_69=0, f_68=0, f_64=0, f_61=0, f_60=0, f_55=0, f_48=0, f_42=0, f_41=0; // 13
  525. int64 f_65=0, f_63=0, f_59=0, f_54=0, f_47=0, f_46=0, f_40=0; // 12
  526. int64 f_62=0, f_53=0, f_51=0, f_50=0, f_49=0, f_38=0, f_37=0, f_36=0; // 8
  527. int64 f_44=0, f_33=0, f_30=0, f_26=0; // 11
  528. int64 f_52=0, f_43=0, f_32=0, f_29=0, f_25=0; // 10
  529. int64 f_56=0, f_45=0, f_39=0, f_31=0, f_28=0, f_24=0; // 9
  530. int64 f_35=0, f_34=0, f_27=0, f_18=0, f_16=0, f_15=0; // 4
  531. int64 f_17=0; // 5
  532. int64 f_22=0, f_20=0, f_19=0; // 6
  533. int64 f_23=0, f_21=0; // 7
  534. for (int nx1=0;nx1<deg[x];nx1++) {
  535. int a=inc[x][nx1].first, xa=inc[x][nx1].second;
  536. for (int i=0;i<nca;i++) common_a[common_a_list[i]]=0;
  537. nca=0;
  538. for (int na=0;na<deg[a];na++) {
  539. int b=adj[a][na];
  540. for (int nb=0;nb<deg[b];nb++) {
  541. int c=adj[b][nb];
  542. if (c==a || adjacent(a,c)) continue;
  543. if (common_a[c]==0) common_a_list[nca++]=c;
  544. common_a[c]++;
  545. }
  546. }
  547. // x = orbit-14 (tetrahedron)
  548. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  549. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  550. if (!adjacent(a,b)) continue;
  551. for (int nx3=nx2+1;nx3<deg[x];nx3++) {
  552. int c=inc[x][nx3].first, xc=inc[x][nx3].second;
  553. if (!adjacent(a,c) || !adjacent(b,c)) continue;
  554. orbit[x][14]++;
  555. f_70 += common3_get(TRIPLE(a,b,c))-1;
  556. f_71 += (tri[xa]>2 && tri[xb]>2)?(common3_get(TRIPLE(x,a,b))-1):0;
  557. f_71 += (tri[xa]>2 && tri[xc]>2)?(common3_get(TRIPLE(x,a,c))-1):0;
  558. f_71 += (tri[xb]>2 && tri[xc]>2)?(common3_get(TRIPLE(x,b,c))-1):0;
  559. f_67 += tri[xa]-2+tri[xb]-2+tri[xc]-2;
  560. f_66 += common2_get(PAIR(a,b))-2;
  561. f_66 += common2_get(PAIR(a,c))-2;
  562. f_66 += common2_get(PAIR(b,c))-2;
  563. f_58 += deg[x]-3;
  564. f_57 += deg[a]-3+deg[b]-3+deg[c]-3;
  565. }
  566. }
  567. // x = orbit-13 (diamond)
  568. for (int nx2=0;nx2<deg[x];nx2++) {
  569. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  570. if (!adjacent(a,b)) continue;
  571. for (int nx3=nx2+1;nx3<deg[x];nx3++) {
  572. int c=inc[x][nx3].first, xc=inc[x][nx3].second;
  573. if (!adjacent(a,c) || adjacent(b,c)) continue;
  574. orbit[x][13]++;
  575. f_69 += (tri[xb]>1 && tri[xc]>1)?(common3_get(TRIPLE(x,b,c))-1):0;
  576. f_68 += common3_get(TRIPLE(a,b,c))-1;
  577. f_64 += common2_get(PAIR(b,c))-2;
  578. f_61 += tri[xb]-1+tri[xc]-1;
  579. f_60 += common2_get(PAIR(a,b))-1;
  580. f_60 += common2_get(PAIR(a,c))-1;
  581. f_55 += tri[xa]-2;
  582. f_48 += deg[b]-2+deg[c]-2;
  583. f_42 += deg[x]-3;
  584. f_41 += deg[a]-3;
  585. }
  586. }
  587. // x = orbit-12 (diamond)
  588. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  589. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  590. if (!adjacent(a,b)) continue;
  591. for (int na=0;na<deg[a];na++) {
  592. int c=inc[a][na].first, ac=inc[a][na].second;
  593. if (c==x || adjacent(x,c) || !adjacent(b,c)) continue;
  594. orbit[x][12]++;
  595. f_65 += (tri[ac]>1)?common3_get(TRIPLE(a,b,c)):0;
  596. f_63 += common_x[c]-2;
  597. f_59 += tri[ac]-1+common2_get(PAIR(b,c))-1;
  598. f_54 += common2_get(PAIR(a,b))-2;
  599. f_47 += deg[x]-2;
  600. f_46 += deg[c]-2;
  601. f_40 += deg[a]-3+deg[b]-3;
  602. }
  603. }
  604. // x = orbit-8 (cycle)
  605. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  606. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  607. if (adjacent(a,b)) continue;
  608. for (int na=0;na<deg[a];na++) {
  609. int c=inc[a][na].first, ac=inc[a][na].second;
  610. if (c==x || adjacent(x,c) || !adjacent(b,c)) continue;
  611. orbit[x][8]++;
  612. f_62 += (tri[ac]>0)?common3_get(TRIPLE(a,b,c)):0;
  613. f_53 += tri[xa]+tri[xb];
  614. f_51 += tri[ac]+common2_get(PAIR(c,b));
  615. f_50 += common_x[c]-2;
  616. f_49 += common_a[b]-2;
  617. f_38 += deg[x]-2;
  618. f_37 += deg[a]-2+deg[b]-2;
  619. f_36 += deg[c]-2;
  620. }
  621. }
  622. // x = orbit-11 (paw)
  623. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  624. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  625. if (!adjacent(a,b)) continue;
  626. for (int nx3=0;nx3<deg[x];nx3++) {
  627. int c=inc[x][nx3].first, xc=inc[x][nx3].second;
  628. if (c==a || c==b || adjacent(a,c) || adjacent(b,c)) continue;
  629. orbit[x][11]++;
  630. f_44 += tri[xc];
  631. f_33 += deg[x]-3;
  632. f_30 += deg[c]-1;
  633. f_26 += deg[a]-2+deg[b]-2;
  634. }
  635. }
  636. // x = orbit-10 (paw)
  637. for (int nx2=0;nx2<deg[x];nx2++) {
  638. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  639. if (!adjacent(a,b)) continue;
  640. for (int nb=0;nb<deg[b];nb++) {
  641. int c=inc[b][nb].first, bc=inc[b][nb].second;
  642. if (c==x || c==a || adjacent(a,c) || adjacent(x,c)) continue;
  643. orbit[x][10]++;
  644. f_52 += common_a[c]-1;
  645. f_43 += tri[bc];
  646. f_32 += deg[b]-3;
  647. f_29 += deg[c]-1;
  648. f_25 += deg[a]-2;
  649. }
  650. }
  651. // x = orbit-9 (paw)
  652. for (int na1=0;na1<deg[a];na1++) {
  653. int b=inc[a][na1].first, ab=inc[a][na1].second;
  654. if (b==x || adjacent(x,b)) continue;
  655. for (int na2=na1+1;na2<deg[a];na2++) {
  656. int c=inc[a][na2].first, ac=inc[a][na2].second;
  657. if (c==x || !adjacent(b,c) || adjacent(x,c)) continue;
  658. orbit[x][9]++;
  659. f_56 += (tri[ab]>1 && tri[ac]>1)?common3_get(TRIPLE(a,b,c)):0;
  660. f_45 += common2_get(PAIR(b,c))-1;
  661. f_39 += tri[ab]-1+tri[ac]-1;
  662. f_31 += deg[a]-3;
  663. f_28 += deg[x]-1;
  664. f_24 += deg[b]-2+deg[c]-2;
  665. }
  666. }
  667. // x = orbit-4 (path)
  668. for (int na=0;na<deg[a];na++) {
  669. int b=inc[a][na].first, ab=inc[a][na].second;
  670. if (b==x || adjacent(x,b)) continue;
  671. for (int nb=0;nb<deg[b];nb++) {
  672. int c=inc[b][nb].first, bc=inc[b][nb].second;
  673. if (c==a || adjacent(a,c) || adjacent(x,c)) continue;
  674. orbit[x][4]++;
  675. f_35 += common_a[c]-1;
  676. f_34 += common_x[c];
  677. f_27 += tri[bc];
  678. f_18 += deg[b]-2;
  679. f_16 += deg[x]-1;
  680. f_15 += deg[c]-1;
  681. }
  682. }
  683. // x = orbit-5 (path)
  684. for (int nx2=0;nx2<deg[x];nx2++) {
  685. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  686. if (b==a || adjacent(a,b)) continue;
  687. for (int nb=0;nb<deg[b];nb++) {
  688. int c=inc[b][nb].first, bc=inc[b][nb].second;
  689. if (c==x || adjacent(a,c) || adjacent(x,c)) continue;
  690. orbit[x][5]++;
  691. f_17 += deg[a]-1;
  692. }
  693. }
  694. // x = orbit-6 (claw)
  695. for (int na1=0;na1<deg[a];na1++) {
  696. int b=inc[a][na1].first, ab=inc[a][na1].second;
  697. if (b==x || adjacent(x,b)) continue;
  698. for (int na2=na1+1;na2<deg[a];na2++) {
  699. int c=inc[a][na2].first, ac=inc[a][na2].second;
  700. if (c==x || adjacent(x,c) || adjacent(b,c)) continue;
  701. orbit[x][6]++;
  702. f_22 += deg[a]-3;
  703. f_20 += deg[x]-1;
  704. f_19 += deg[b]-1+deg[c]-1;
  705. }
  706. }
  707. // x = orbit-7 (claw)
  708. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  709. int b=inc[x][nx2].first, xb=inc[x][nx2].second;
  710. if (adjacent(a,b)) continue;
  711. for (int nx3=nx2+1;nx3<deg[x];nx3++) {
  712. int c=inc[x][nx3].first, xc=inc[x][nx3].second;
  713. if (adjacent(a,c) || adjacent(b,c)) continue;
  714. orbit[x][7]++;
  715. f_23 += deg[x]-3;
  716. f_21 += deg[a]-1+deg[b]-1+deg[c]-1;
  717. }
  718. }
  719. }
  720. // solve equations
  721. orbit[x][72] = C5[x];
  722. orbit[x][71] = (f_71-12*orbit[x][72])/2;
  723. orbit[x][70] = (f_70-4*orbit[x][72]);
  724. orbit[x][69] = (f_69-2*orbit[x][71])/4;
  725. orbit[x][68] = (f_68-2*orbit[x][71]);
  726. orbit[x][67] = (f_67-12*orbit[x][72]-4*orbit[x][71]);
  727. orbit[x][66] = (f_66-12*orbit[x][72]-2*orbit[x][71]-3*orbit[x][70]);
  728. orbit[x][65] = (f_65-3*orbit[x][70])/2;
  729. orbit[x][64] = (f_64-2*orbit[x][71]-4*orbit[x][69]-1*orbit[x][68]);
  730. orbit[x][63] = (f_63-3*orbit[x][70]-2*orbit[x][68]);
  731. orbit[x][62] = (f_62-1*orbit[x][68])/2;
  732. orbit[x][61] = (f_61-4*orbit[x][71]-8*orbit[x][69]-2*orbit[x][67])/2;
  733. orbit[x][60] = (f_60-4*orbit[x][71]-2*orbit[x][68]-2*orbit[x][67]);
  734. orbit[x][59] = (f_59-6*orbit[x][70]-2*orbit[x][68]-4*orbit[x][65]);
  735. orbit[x][58] = (f_58-4*orbit[x][72]-2*orbit[x][71]-1*orbit[x][67]);
  736. orbit[x][57] = (f_57-12*orbit[x][72]-4*orbit[x][71]-3*orbit[x][70]-1*orbit[x][67]-2*orbit[x][66]);
  737. orbit[x][56] = (f_56-2*orbit[x][65])/3;
  738. orbit[x][55] = (f_55-2*orbit[x][71]-2*orbit[x][67])/3;
  739. orbit[x][54] = (f_54-3*orbit[x][70]-1*orbit[x][66]-2*orbit[x][65])/2;
  740. orbit[x][53] = (f_53-2*orbit[x][68]-2*orbit[x][64]-2*orbit[x][63]);
  741. orbit[x][52] = (f_52-2*orbit[x][66]-2*orbit[x][64]-1*orbit[x][59])/2;
  742. orbit[x][51] = (f_51-2*orbit[x][68]-2*orbit[x][63]-4*orbit[x][62]);
  743. orbit[x][50] = (f_50-1*orbit[x][68]-2*orbit[x][63])/3;
  744. orbit[x][49] = (f_49-1*orbit[x][68]-1*orbit[x][64]-2*orbit[x][62])/2;
  745. orbit[x][48] = (f_48-4*orbit[x][71]-8*orbit[x][69]-2*orbit[x][68]-2*orbit[x][67]-2*orbit[x][64]-2*orbit[x][61]-1*orbit[x][60]);
  746. orbit[x][47] = (f_47-3*orbit[x][70]-2*orbit[x][68]-1*orbit[x][66]-1*orbit[x][63]-1*orbit[x][60]);
  747. orbit[x][46] = (f_46-3*orbit[x][70]-2*orbit[x][68]-2*orbit[x][65]-1*orbit[x][63]-1*orbit[x][59]);
  748. orbit[x][45] = (f_45-2*orbit[x][65]-2*orbit[x][62]-3*orbit[x][56]);
  749. orbit[x][44] = (f_44-1*orbit[x][67]-2*orbit[x][61])/4;
  750. orbit[x][43] = (f_43-2*orbit[x][66]-1*orbit[x][60]-1*orbit[x][59])/2;
  751. orbit[x][42] = (f_42-2*orbit[x][71]-4*orbit[x][69]-2*orbit[x][67]-2*orbit[x][61]-3*orbit[x][55]);
  752. orbit[x][41] = (f_41-2*orbit[x][71]-1*orbit[x][68]-2*orbit[x][67]-1*orbit[x][60]-3*orbit[x][55]);
  753. orbit[x][40] = (f_40-6*orbit[x][70]-2*orbit[x][68]-2*orbit[x][66]-4*orbit[x][65]-1*orbit[x][60]-1*orbit[x][59]-4*orbit[x][54]);
  754. orbit[x][39] = (f_39-4*orbit[x][65]-1*orbit[x][59]-6*orbit[x][56])/2;
  755. orbit[x][38] = (f_38-1*orbit[x][68]-1*orbit[x][64]-2*orbit[x][63]-1*orbit[x][53]-3*orbit[x][50]);
  756. orbit[x][37] = (f_37-2*orbit[x][68]-2*orbit[x][64]-2*orbit[x][63]-4*orbit[x][62]-1*orbit[x][53]-1*orbit[x][51]-4*orbit[x][49]);
  757. orbit[x][36] = (f_36-1*orbit[x][68]-2*orbit[x][63]-2*orbit[x][62]-1*orbit[x][51]-3*orbit[x][50]);
  758. orbit[x][35] = (f_35-1*orbit[x][59]-2*orbit[x][52]-2*orbit[x][45])/2;
  759. orbit[x][34] = (f_34-1*orbit[x][59]-2*orbit[x][52]-1*orbit[x][51])/2;
  760. orbit[x][33] = (f_33-1*orbit[x][67]-2*orbit[x][61]-3*orbit[x][58]-4*orbit[x][44]-2*orbit[x][42])/2;
  761. orbit[x][32] = (f_32-2*orbit[x][66]-1*orbit[x][60]-1*orbit[x][59]-2*orbit[x][57]-2*orbit[x][43]-2*orbit[x][41]-1*orbit[x][40])/2;
  762. orbit[x][31] = (f_31-2*orbit[x][65]-1*orbit[x][59]-3*orbit[x][56]-1*orbit[x][43]-2*orbit[x][39]);
  763. orbit[x][30] = (f_30-1*orbit[x][67]-1*orbit[x][63]-2*orbit[x][61]-1*orbit[x][53]-4*orbit[x][44]);
  764. orbit[x][29] = (f_29-2*orbit[x][66]-2*orbit[x][64]-1*orbit[x][60]-1*orbit[x][59]-1*orbit[x][53]-2*orbit[x][52]-2*orbit[x][43]);
  765. orbit[x][28] = (f_28-2*orbit[x][65]-2*orbit[x][62]-1*orbit[x][59]-1*orbit[x][51]-1*orbit[x][43]);
  766. orbit[x][27] = (f_27-1*orbit[x][59]-1*orbit[x][51]-2*orbit[x][45])/2;
  767. orbit[x][26] = (f_26-2*orbit[x][67]-2*orbit[x][63]-2*orbit[x][61]-6*orbit[x][58]-1*orbit[x][53]-2*orbit[x][47]-2*orbit[x][42]);
  768. orbit[x][25] = (f_25-2*orbit[x][66]-2*orbit[x][64]-1*orbit[x][59]-2*orbit[x][57]-2*orbit[x][52]-1*orbit[x][48]-1*orbit[x][40])/2;
  769. orbit[x][24] = (f_24-4*orbit[x][65]-4*orbit[x][62]-1*orbit[x][59]-6*orbit[x][56]-1*orbit[x][51]-2*orbit[x][45]-2*orbit[x][39]);
  770. orbit[x][23] = (f_23-1*orbit[x][55]-1*orbit[x][42]-2*orbit[x][33])/4;
  771. orbit[x][22] = (f_22-2*orbit[x][54]-1*orbit[x][40]-1*orbit[x][39]-1*orbit[x][32]-2*orbit[x][31])/3;
  772. orbit[x][21] = (f_21-3*orbit[x][55]-3*orbit[x][50]-2*orbit[x][42]-2*orbit[x][38]-2*orbit[x][33]);
  773. orbit[x][20] = (f_20-2*orbit[x][54]-2*orbit[x][49]-1*orbit[x][40]-1*orbit[x][37]-1*orbit[x][32]);
  774. orbit[x][19] = (f_19-4*orbit[x][54]-4*orbit[x][49]-1*orbit[x][40]-2*orbit[x][39]-1*orbit[x][37]-2*orbit[x][35]-2*orbit[x][31]);
  775. orbit[x][18] = (f_18-1*orbit[x][59]-1*orbit[x][51]-2*orbit[x][46]-2*orbit[x][45]-2*orbit[x][36]-2*orbit[x][27]-1*orbit[x][24])/2;
  776. orbit[x][17] = (f_17-1*orbit[x][60]-1*orbit[x][53]-1*orbit[x][51]-1*orbit[x][48]-1*orbit[x][37]-2*orbit[x][34]-2*orbit[x][30])/2;
  777. orbit[x][16] = (f_16-1*orbit[x][59]-2*orbit[x][52]-1*orbit[x][51]-2*orbit[x][46]-2*orbit[x][36]-2*orbit[x][34]-1*orbit[x][29]);
  778. orbit[x][15] = (f_15-1*orbit[x][59]-2*orbit[x][52]-1*orbit[x][51]-2*orbit[x][45]-2*orbit[x][35]-2*orbit[x][34]-2*orbit[x][27]);
  779. }
  780. endTime = clock();
  781. printf("%.2f sec\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  782. endTime_all = endTime;
  783. printf("total: %.2f sec\n", (double)(endTime_all-startTime_all)/CLOCKS_PER_SEC);
  784. }
  785. /** count edge orbits of graphlets on max 5 nodes */
  786. void ecount5() {
  787. clock_t startTime, endTime;
  788. startTime = clock();
  789. clock_t startTime_all, endTime_all;
  790. startTime_all = startTime;
  791. int frac,frac_prev;
  792. // precompute common nodes
  793. printf("stage 1 - precomputing common nodes\n");
  794. frac_prev=-1;
  795. for (int x=0;x<n;x++) {
  796. frac = 100LL*x/n;
  797. if (frac!=frac_prev) {
  798. printf("%d%%\r",frac);
  799. frac_prev=frac;
  800. }
  801. for (int n1=0;n1<deg[x];n1++) {
  802. int a=adj[x][n1];
  803. for (int n2=n1+1;n2<deg[x];n2++) {
  804. int b=adj[x][n2];
  805. PAIR ab=PAIR(a,b);
  806. common2[ab]++;
  807. for (int n3=n2+1;n3<deg[x];n3++) {
  808. int c=adj[x][n3];
  809. int st = adjacent(a,b)+adjacent(a,c)+adjacent(b,c);
  810. if (st<2) continue;
  811. TRIPLE abc=TRIPLE(a,b,c);
  812. common3[abc]++;
  813. }
  814. }
  815. }
  816. }
  817. // precompute triangles that span over edges
  818. int *tri = (int*)calloc(m,sizeof(int));
  819. for (int i=0;i<m;i++) {
  820. int x=edges[i].a, y=edges[i].b;
  821. for (int xi=0,yi=0; xi<deg[x] && yi<deg[y]; ) {
  822. if (adj[x][xi]==adj[y][yi]) { tri[i]++; xi++; yi++; }
  823. else if (adj[x][xi]<adj[y][yi]) { xi++; }
  824. else { yi++; }
  825. }
  826. }
  827. endTime = clock();
  828. printf("%.2f sec\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  829. startTime = endTime;
  830. // count full graphlets
  831. printf("stage 2 - counting full graphlets\n");
  832. int64 *C5 = (int64*)calloc(m,sizeof(int64));
  833. int *neighx = (int*)malloc(n*sizeof(int)); // lookup table - edges to neighbors of x
  834. memset(neighx,-1,n*sizeof(int));
  835. int *neigh = (int*)malloc(n*sizeof(int)), nn; // lookup table - common neighbors of x and y
  836. PII *neigh_edges = (PII*)malloc(n*sizeof(PII)); // list of common neighbors of x and y
  837. int *neigh2 = (int*)malloc(n*sizeof(int)), nn2;
  838. TIII *neigh2_edges = (TIII*)malloc(n*sizeof(TIII));
  839. frac_prev=-1;
  840. for (int x=0;x<n;x++) {
  841. frac = 100LL*x/n;
  842. if (frac!=frac_prev) {
  843. printf("%d%%\r",frac);
  844. frac_prev=frac;
  845. }
  846. for (int nx=0;nx<deg[x];nx++) {
  847. int y=inc[x][nx].first, xy=inc[x][nx].second;
  848. neighx[y]=xy;
  849. }
  850. for (int nx=0;nx<deg[x];nx++) {
  851. int y=inc[x][nx].first, xy=inc[x][nx].second;
  852. if (y >= x) break;
  853. nn=0;
  854. for (int ny=0;ny<deg[y];ny++) {
  855. int z=inc[y][ny].first, yz=inc[y][ny].second;
  856. if (z >= y) break;
  857. if (neighx[z]==-1) continue;
  858. int xz=neighx[z];
  859. neigh[nn]=z;
  860. neigh_edges[nn]={xz, yz};
  861. nn++;
  862. }
  863. for (int i=0;i<nn;i++) {
  864. int z = neigh[i], xz = neigh_edges[i].first, yz = neigh_edges[i].second;
  865. nn2 = 0;
  866. for (int j=i+1;j<nn;j++) {
  867. int w = neigh[j], xw = neigh_edges[j].first, yw = neigh_edges[j].second;
  868. if (adjacent(z,w)) {
  869. neigh2[nn2]=w;
  870. int zw=getEdgeId(z,w);
  871. neigh2_edges[nn2]={xw,yw,zw};
  872. nn2++;
  873. }
  874. }
  875. for (int i2=0;i2<nn2;i2++) {
  876. int z2 = neigh2[i2];
  877. int z2x=neigh2_edges[i2].first, z2y=neigh2_edges[i2].second, z2z=neigh2_edges[i2].third;
  878. for (int j2=i2+1;j2<nn2;j2++) {
  879. int z3 = neigh2[j2];
  880. int z3x=neigh2_edges[j2].first, z3y=neigh2_edges[j2].second, z3z=neigh2_edges[j2].third;
  881. if (adjacent(z2,z3)) {
  882. int zid=getEdgeId(z2,z3);
  883. C5[xy]++; C5[xz]++; C5[yz]++;
  884. C5[z2x]++; C5[z2y]++; C5[z2z]++;
  885. C5[z3x]++; C5[z3y]++; C5[z3z]++;
  886. C5[zid]++;
  887. }
  888. }
  889. }
  890. }
  891. }
  892. for (int nx=0;nx<deg[x];nx++) {
  893. int y=inc[x][nx].first, xy=inc[x][nx].second;
  894. neighx[y]=-1;
  895. }
  896. }
  897. endTime = clock();
  898. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  899. startTime = endTime;
  900. // set up a system of equations relating orbits for every node
  901. printf("stage 3 - building systems of equations\n");
  902. int *common_x = (int*)calloc(n,sizeof(int));
  903. int *common_x_list = (int*)malloc(n*sizeof(int)), nc_x=0;
  904. int *common_y = (int*)calloc(n,sizeof(int));
  905. int *common_y_list = (int*)malloc(n*sizeof(int)), nc_y=0;
  906. frac_prev=-1;
  907. for (int x=0;x<n;x++) {
  908. frac = 100LL*x/n;
  909. if (frac!=frac_prev) {
  910. printf("%d%%\r",frac);
  911. frac_prev=frac;
  912. }
  913. // common nodes of x and some other node
  914. for (int i=0;i<nc_x;i++) common_x[common_x_list[i]]=0;
  915. nc_x=0;
  916. for (int nx=0;nx<deg[x];nx++) {
  917. int a=adj[x][nx];
  918. for (int na=0;na<deg[a];na++) {
  919. int z=adj[a][na];
  920. if (z==x) continue;
  921. if (common_x[z]==0) common_x_list[nc_x++]=z;
  922. common_x[z]++;
  923. }
  924. }
  925. for (int nx=0;nx<deg[x];nx++) {
  926. int y=inc[x][nx].first, xy=inc[x][nx].second;
  927. int e=xy;
  928. if (y>=x) break;
  929. // common nodes of y and some other node
  930. for (int i=0;i<nc_y;i++) common_y[common_y_list[i]]=0;
  931. nc_y=0;
  932. for (int ny=0;ny<deg[y];ny++) {
  933. int a=adj[y][ny];
  934. for (int na=0;na<deg[a];na++) {
  935. int z=adj[a][na];
  936. if (z==y) continue;
  937. if (common_y[z]==0) common_y_list[nc_y++]=z;
  938. common_y[z]++;
  939. }
  940. }
  941. int64 f_66=0, f_65=0, f_62=0, f_61=0, f_60=0, f_51=0, f_50=0; // 11
  942. int64 f_64=0, f_58=0, f_55=0, f_48=0, f_41=0, f_35=0; // 10
  943. int64 f_63=0, f_59=0, f_57=0, f_54=0, f_53=0, f_52=0, f_47=0, f_40=0, f_39=0, f_34=0, f_33=0; // 9
  944. int64 f_45=0, f_36=0, f_26=0, f_23=0, f_19=0; // 7
  945. int64 f_49=0, f_38=0, f_37=0, f_32=0, f_25=0, f_22=0, f_18=0; // 6
  946. int64 f_56=0, f_46=0, f_44=0, f_43=0, f_42=0, f_31=0, f_30=0; // 5
  947. int64 f_27=0, f_17=0, f_15=0; // 4
  948. int64 f_20=0, f_16=0, f_13=0; // 3
  949. int64 f_29=0, f_28=0, f_24=0, f_21=0, f_14=0, f_12=0; // 2
  950. // smaller (3-node) graphlets
  951. orbit[x][0] = deg[x];
  952. for (int nx1=0;nx1<deg[x];nx1++) {
  953. int z=adj[x][nx1];
  954. if (z==y) continue;
  955. if (adjacent(y,z)) eorbit[e][1]++;
  956. else eorbit[e][0]++;
  957. }
  958. for (int ny=0;ny<deg[y];ny++) {
  959. int z=adj[y][ny];
  960. if (z==x) continue;
  961. if (!adjacent(x,z)) eorbit[e][0]++;
  962. }
  963. // edge-orbit 11 = (14,14)
  964. for (int nx1=0;nx1<deg[x];nx1++) {
  965. int a=adj[x][nx1], xa=inc[x][nx1].second;
  966. if (a==y || !adjacent(y,a)) continue;
  967. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  968. int b=adj[x][nx2], xb=inc[x][nx2].second;
  969. if (b==y || !adjacent(y,b) || !adjacent(a,b)) continue;
  970. int ya=getEdgeId(y,a), yb=getEdgeId(y,b), ab=getEdgeId(a,b);
  971. eorbit[e][11]++;
  972. f_66 += common3_get(TRIPLE(x,y,a))-1;
  973. f_66 += common3_get(TRIPLE(x,y,b))-1;
  974. f_65 += common3_get(TRIPLE(a,b,x))-1;
  975. f_65 += common3_get(TRIPLE(a,b,y))-1;
  976. f_62 += tri[xy]-2;
  977. f_61 += (tri[xa]-2)+(tri[xb]-2)+(tri[ya]-2)+(tri[yb]-2);
  978. f_60 += tri[ab]-2;
  979. f_51 += (deg[x]-3)+(deg[y]-3);
  980. f_50 += (deg[a]-3)+(deg[b]-3);
  981. }
  982. }
  983. // edge-orbit 10 = (13,13)
  984. for (int nx1=0;nx1<deg[x];nx1++) {
  985. int a=adj[x][nx1], xa=inc[x][nx1].second;
  986. if (a==y || !adjacent(y,a)) continue;
  987. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  988. int b=adj[x][nx2], xb=inc[x][nx2].second;
  989. if (b==y || !adjacent(y,b) || adjacent(a,b)) continue;
  990. int ya=getEdgeId(y,a), yb=getEdgeId(y,b);
  991. eorbit[e][10]++;
  992. f_64 += common3_get(TRIPLE(a,b,x))-1;
  993. f_64 += common3_get(TRIPLE(a,b,y))-1;
  994. f_58 += common2_get(PAIR(a,b))-2;
  995. f_55 += (tri[xa]-1)+(tri[xb]-1)+(tri[ya]-1)+(tri[yb]-1);
  996. f_48 += tri[xy]-2;
  997. f_41 += (deg[a]-2)+(deg[b]-2);
  998. f_35 += (deg[x]-3)+(deg[y]-3);
  999. }
  1000. }
  1001. // edge-orbit 9 = (12,13)
  1002. for (int nx=0;nx<deg[x];nx++) {
  1003. int a=adj[x][nx], xa=inc[x][nx].second;
  1004. if (a==y) continue;
  1005. for (int ny=0;ny<deg[y];ny++) {
  1006. int b=adj[y][ny], yb=inc[y][ny].second;
  1007. if (b==x || !adjacent(a,b)) continue;
  1008. int adj_ya=adjacent(y,a), adj_xb=adjacent(x,b);
  1009. if (adj_ya+adj_xb!=1) continue;
  1010. int ab=getEdgeId(a,b);
  1011. eorbit[e][9]++;
  1012. if (adj_xb) {
  1013. int xb=getEdgeId(x,b);
  1014. f_63 += common3_get(TRIPLE(a,b,y))-1;
  1015. f_59 += common3_get(TRIPLE(a,b,x));
  1016. f_57 += common_y[a]-2;
  1017. f_54 += tri[yb]-1;
  1018. f_53 += tri[xa]-1;
  1019. f_47 += tri[xb]-2;
  1020. f_40 += deg[y]-2;
  1021. f_39 += deg[a]-2;
  1022. f_34 += deg[x]-3;
  1023. f_33 += deg[b]-3;
  1024. } else if (adj_ya) {
  1025. int ya=getEdgeId(y,a);
  1026. f_63 += common3_get(TRIPLE(a,b,x))-1;
  1027. f_59 += common3_get(TRIPLE(a,b,y));
  1028. f_57 += common_x[b]-2;
  1029. f_54 += tri[xa]-1;
  1030. f_53 += tri[yb]-1;
  1031. f_47 += tri[ya]-2;
  1032. f_40 += deg[x]-2;
  1033. f_39 += deg[b]-2;
  1034. f_34 += deg[y]-3;
  1035. f_33 += deg[a]-3;
  1036. }
  1037. f_52 += tri[ab]-1;
  1038. }
  1039. }
  1040. // edge-orbit 8 = (10,11)
  1041. for (int nx=0;nx<deg[x];nx++) {
  1042. int a=adj[x][nx];
  1043. if (a==y || !adjacent(y,a)) continue;
  1044. for (int nx1=0;nx1<deg[x];nx1++) {
  1045. int b=adj[x][nx1];
  1046. if (b==y || b==a || adjacent(y,b) || adjacent(a,b)) continue;
  1047. eorbit[e][8]++;
  1048. }
  1049. for (int ny1=0;ny1<deg[y];ny1++) {
  1050. int b=adj[y][ny1];
  1051. if (b==x || b==a || adjacent(x,b) || adjacent(a,b)) continue;
  1052. eorbit[e][8]++;
  1053. }
  1054. }
  1055. // edge-orbit 7 = (10,10)
  1056. for (int nx=0;nx<deg[x];nx++) {
  1057. int a=adj[x][nx];
  1058. if (a==y || !adjacent(y,a)) continue;
  1059. for (int na=0;na<deg[a];na++) {
  1060. int b=adj[a][na], ab=inc[a][na].second;
  1061. if (b==x || b==y || adjacent(x,b) || adjacent(y,b)) continue;
  1062. eorbit[e][7]++;
  1063. f_45 += common_x[b]-1;
  1064. f_45 += common_y[b]-1;
  1065. f_36 += tri[ab];
  1066. f_26 += deg[a]-3;
  1067. f_23 += deg[b]-1;
  1068. f_19 += (deg[x]-2)+(deg[y]-2);
  1069. }
  1070. }
  1071. // edge-orbit 6 = (9,11)
  1072. for (int ny1=0;ny1<deg[y];ny1++) {
  1073. int a=adj[y][ny1], ya=inc[y][ny1].second;
  1074. if (a==x || adjacent(x,a)) continue;
  1075. for (int ny2=ny1+1;ny2<deg[y];ny2++) {
  1076. int b=adj[y][ny2], yb=inc[y][ny2].second;
  1077. if (b==x || adjacent(x,b) || !adjacent(a,b)) continue;
  1078. int ab=getEdgeId(a,b);
  1079. eorbit[e][6]++;
  1080. f_49 += common3_get(TRIPLE(y,a,b));
  1081. f_38 += tri[ab]-1;
  1082. f_37 += tri[xy];
  1083. f_32 += (tri[ya]-1)+(tri[yb]-1);
  1084. f_25 += deg[y]-3;
  1085. f_22 += deg[x]-1;
  1086. f_18 += (deg[a]-2)+(deg[b]-2);
  1087. }
  1088. }
  1089. for (int nx1=0;nx1<deg[x];nx1++) {
  1090. int a=adj[x][nx1], xa=inc[x][nx1].second;
  1091. if (a==y || adjacent(y,a)) continue;
  1092. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  1093. int b=adj[x][nx2], xb=inc[x][nx2].second;
  1094. if (b==y || adjacent(y,b) || !adjacent(a,b)) continue;
  1095. int ab=getEdgeId(a,b);
  1096. eorbit[e][6]++;
  1097. f_49 += common3_get(TRIPLE(x,a,b));
  1098. f_38 += tri[ab]-1;
  1099. f_37 += tri[xy];
  1100. f_32 += (tri[xa]-1)+(tri[xb]-1);
  1101. f_25 += deg[x]-3;
  1102. f_22 += deg[y]-1;
  1103. f_18 += (deg[a]-2)+(deg[b]-2);
  1104. }
  1105. }
  1106. // edge-orbit 5 = (8,8)
  1107. for (int nx=0;nx<deg[x];nx++) {
  1108. int a=adj[x][nx], xa=inc[x][nx].second;
  1109. if (a==y || adjacent(y,a)) continue;
  1110. for (int ny=0;ny<deg[y];ny++) {
  1111. int b=adj[y][ny], yb=inc[y][ny].second;
  1112. if (b==x || adjacent(x,b) || !adjacent(a,b)) continue;
  1113. int ab=getEdgeId(a,b);
  1114. eorbit[e][5]++;
  1115. f_56 += common3_get(TRIPLE(x,a,b));
  1116. f_56 += common3_get(TRIPLE(y,a,b));
  1117. f_46 += tri[xy];
  1118. f_44 += tri[xa]+tri[yb];
  1119. f_43 += tri[ab];
  1120. f_42 += common_x[b]-2;
  1121. f_42 += common_y[a]-2;
  1122. f_31 += (deg[x]-2)+(deg[y]-2);
  1123. f_30 += (deg[a]-2)+(deg[b]-2);
  1124. }
  1125. }
  1126. // edge-orbit 4 = (6,7)
  1127. for (int ny1=0;ny1<deg[y];ny1++) {
  1128. int a=adj[y][ny1];
  1129. if (a==x || adjacent(x,a)) continue;
  1130. for (int ny2=ny1+1;ny2<deg[y];ny2++) {
  1131. int b=adj[y][ny2];
  1132. if (b==x || adjacent(x,b) || adjacent(a,b)) continue;
  1133. eorbit[e][4]++;
  1134. f_27 += tri[xy];
  1135. f_17 += deg[y]-3;
  1136. f_15 += (deg[a]-1)+(deg[b]-1);
  1137. }
  1138. }
  1139. for (int nx1=0;nx1<deg[x];nx1++) {
  1140. int a=adj[x][nx1];
  1141. if (a==y || adjacent(y,a)) continue;
  1142. for (int nx2=nx1+1;nx2<deg[x];nx2++) {
  1143. int b=adj[x][nx2];
  1144. if (b==y || adjacent(y,b) || adjacent(a,b)) continue;
  1145. eorbit[e][4]++;
  1146. f_27 += tri[xy];
  1147. f_17 += deg[x]-3;
  1148. f_15 += (deg[a]-1)+(deg[b]-1);
  1149. }
  1150. }
  1151. // edge-orbit 3 = (5,5)
  1152. for (int nx=0;nx<deg[x];nx++) {
  1153. int a=adj[x][nx];
  1154. if (a==y || adjacent(y,a)) continue;
  1155. for (int ny=0;ny<deg[y];ny++) {
  1156. int b=adj[y][ny];
  1157. if (b==x || adjacent(x,b) || adjacent(a,b)) continue;
  1158. eorbit[e][3]++;
  1159. f_20 += tri[xy];
  1160. f_16 += (deg[x]-2)+(deg[y]-2);
  1161. f_13 += (deg[a]-1)+(deg[b]-1);
  1162. }
  1163. }
  1164. // edge-orbit 2 = (4,5)
  1165. for (int ny=0;ny<deg[y];ny++) {
  1166. int a=adj[y][ny];
  1167. if (a==x || adjacent(x,a)) continue;
  1168. for (int na=0;na<deg[a];na++) {
  1169. int b=adj[a][na], ab=inc[a][na].second;
  1170. if (b==y || adjacent(y,b) || adjacent(x,b)) continue;
  1171. eorbit[e][2]++;
  1172. f_29 += common_y[b]-1;
  1173. f_28 += common_x[b];
  1174. f_24 += tri[xy];
  1175. f_21 += tri[ab];
  1176. f_14 += deg[a]-2;
  1177. f_12 += deg[b]-1;
  1178. }
  1179. }
  1180. for (int nx=0;nx<deg[x];nx++) {
  1181. int a=adj[x][nx];
  1182. if (a==y || adjacent(y,a)) continue;
  1183. for (int na=0;na<deg[a];na++) {
  1184. int b=adj[a][na], ab=inc[a][na].second;
  1185. if (b==x || adjacent(x,b) || adjacent(y,b)) continue;
  1186. eorbit[e][2]++;
  1187. f_29 += common_x[b]-1;
  1188. f_28 += common_y[b];
  1189. f_24 += tri[xy];
  1190. f_21 += tri[ab];
  1191. f_14 += deg[a]-2;
  1192. f_12 += deg[b]-1;
  1193. }
  1194. }
  1195. // solve system of equations
  1196. eorbit[e][67]=C5[e];
  1197. eorbit[e][66]=(f_66-6*eorbit[e][67])/2;
  1198. eorbit[e][65]=(f_65-6*eorbit[e][67]);
  1199. eorbit[e][64]=(f_64-2*eorbit[e][66]);
  1200. eorbit[e][63]=(f_63-2*eorbit[e][65])/2;
  1201. eorbit[e][62]=(f_62-2*eorbit[e][66]-3*eorbit[e][67]);
  1202. eorbit[e][61]=(f_61-2*eorbit[e][65]-4*eorbit[e][66]-12*eorbit[e][67]);
  1203. eorbit[e][60]=(f_60-1*eorbit[e][65]-3*eorbit[e][67]);
  1204. eorbit[e][59]=(f_59-2*eorbit[e][65])/2;
  1205. eorbit[e][58]=(f_58-1*eorbit[e][64]-1*eorbit[e][66]);
  1206. eorbit[e][57]=(f_57-2*eorbit[e][63]-2*eorbit[e][64]-2*eorbit[e][65]);
  1207. eorbit[e][56]=(f_56-2*eorbit[e][63])/2;
  1208. eorbit[e][55]=(f_55-4*eorbit[e][62]-2*eorbit[e][64]-4*eorbit[e][66]);
  1209. eorbit[e][54]=(f_54-1*eorbit[e][61]-2*eorbit[e][63]-2*eorbit[e][65])/2;
  1210. eorbit[e][53]=(f_53-2*eorbit[e][59]-2*eorbit[e][64]-2*eorbit[e][65]);
  1211. eorbit[e][52]=(f_52-2*eorbit[e][59]-2*eorbit[e][63]-2*eorbit[e][65]);
  1212. eorbit[e][51]=(f_51-1*eorbit[e][61]-2*eorbit[e][62]-1*eorbit[e][65]-4*eorbit[e][66]-6*eorbit[e][67]);
  1213. eorbit[e][50]=(f_50-2*eorbit[e][60]-1*eorbit[e][61]-2*eorbit[e][65]-2*eorbit[e][66]-6*eorbit[e][67]);
  1214. eorbit[e][49]=(f_49-1*eorbit[e][59])/3;
  1215. eorbit[e][48]=(f_48-2*eorbit[e][62]-1*eorbit[e][66])/3;
  1216. eorbit[e][47]=(f_47-2*eorbit[e][59]-1*eorbit[e][61]-2*eorbit[e][65])/2;
  1217. eorbit[e][46]=(f_46-1*eorbit[e][57]-1*eorbit[e][63]);
  1218. eorbit[e][45]=(f_45-1*eorbit[e][52]-4*eorbit[e][58]-4*eorbit[e][60]);
  1219. eorbit[e][44]=(f_44-2*eorbit[e][56]-1*eorbit[e][57]-2*eorbit[e][63]);
  1220. eorbit[e][43]=(f_43-2*eorbit[e][56]-1*eorbit[e][63]);
  1221. eorbit[e][42]=(f_42-2*eorbit[e][56]-1*eorbit[e][57]-2*eorbit[e][63])/2;
  1222. eorbit[e][41]=(f_41-1*eorbit[e][55]-2*eorbit[e][58]-2*eorbit[e][62]-2*eorbit[e][64]-2*eorbit[e][66]);
  1223. eorbit[e][40]=(f_40-2*eorbit[e][54]-1*eorbit[e][55]-1*eorbit[e][57]-1*eorbit[e][61]-2*eorbit[e][63]-2*eorbit[e][64]-2*eorbit[e][65]);
  1224. eorbit[e][39]=(f_39-1*eorbit[e][52]-1*eorbit[e][53]-1*eorbit[e][57]-2*eorbit[e][59]-2*eorbit[e][63]-2*eorbit[e][64]-2*eorbit[e][65]);
  1225. eorbit[e][38]=(f_38-3*eorbit[e][49]-1*eorbit[e][56]-1*eorbit[e][59]);
  1226. eorbit[e][37]=(f_37-1*eorbit[e][53]-1*eorbit[e][59]);
  1227. eorbit[e][36]=(f_36-1*eorbit[e][52]-2*eorbit[e][60])/2;
  1228. eorbit[e][35]=(f_35-6*eorbit[e][48]-1*eorbit[e][55]-4*eorbit[e][62]-1*eorbit[e][64]-2*eorbit[e][66]);
  1229. eorbit[e][34]=(f_34-2*eorbit[e][47]-1*eorbit[e][53]-1*eorbit[e][55]-2*eorbit[e][59]-1*eorbit[e][61]-2*eorbit[e][64]-2*eorbit[e][65]);
  1230. eorbit[e][33]=(f_33-2*eorbit[e][47]-1*eorbit[e][52]-2*eorbit[e][54]-2*eorbit[e][59]-1*eorbit[e][61]-2*eorbit[e][63]-2*eorbit[e][65]);
  1231. eorbit[e][32]=(f_32-6*eorbit[e][49]-1*eorbit[e][53]-2*eorbit[e][59])/2;
  1232. eorbit[e][31]=(f_31-2*eorbit[e][42]-1*eorbit[e][44]-2*eorbit[e][46]-2*eorbit[e][56]-2*eorbit[e][57]-2*eorbit[e][63]);
  1233. eorbit[e][30]=(f_30-2*eorbit[e][42]-2*eorbit[e][43]-1*eorbit[e][44]-4*eorbit[e][56]-1*eorbit[e][57]-2*eorbit[e][63]);
  1234. eorbit[e][29]=(f_29-2*eorbit[e][38]-1*eorbit[e][45]-1*eorbit[e][52])/2;
  1235. eorbit[e][28]=(f_28-2*eorbit[e][43]-1*eorbit[e][45]-1*eorbit[e][52])/2;
  1236. eorbit[e][27]=(f_27-1*eorbit[e][34]-1*eorbit[e][47]);
  1237. eorbit[e][26]=(f_26-1*eorbit[e][33]-2*eorbit[e][36]-1*eorbit[e][50]-1*eorbit[e][52]-2*eorbit[e][60])/2;
  1238. eorbit[e][25]=(f_25-2*eorbit[e][32]-1*eorbit[e][37]-3*eorbit[e][49]-1*eorbit[e][53]-1*eorbit[e][59]);
  1239. eorbit[e][24]=(f_24-1*eorbit[e][39]-1*eorbit[e][45]-1*eorbit[e][52]);
  1240. eorbit[e][23]=(f_23-2*eorbit[e][36]-1*eorbit[e][45]-1*eorbit[e][52]-2*eorbit[e][58]-2*eorbit[e][60]);
  1241. eorbit[e][22]=(f_22-1*eorbit[e][37]-1*eorbit[e][44]-1*eorbit[e][53]-1*eorbit[e][56]-1*eorbit[e][59]);
  1242. eorbit[e][21]=(f_21-2*eorbit[e][38]-2*eorbit[e][43]-1*eorbit[e][52])/2;
  1243. eorbit[e][20]=(f_20-1*eorbit[e][40]-1*eorbit[e][54]);
  1244. eorbit[e][19]=(f_19-1*eorbit[e][33]-2*eorbit[e][41]-1*eorbit[e][45]-2*eorbit[e][50]-1*eorbit[e][52]-4*eorbit[e][58]-4*eorbit[e][60]);
  1245. eorbit[e][18]=(f_18-2*eorbit[e][32]-2*eorbit[e][38]-1*eorbit[e][44]-6*eorbit[e][49]-1*eorbit[e][53]-2*eorbit[e][56]-2*eorbit[e][59]);
  1246. eorbit[e][17]=(f_17-2*eorbit[e][25]-1*eorbit[e][27]-1*eorbit[e][32]-1*eorbit[e][34]-1*eorbit[e][47])/3;
  1247. eorbit[e][16]=(f_16-2*eorbit[e][20]-2*eorbit[e][22]-1*eorbit[e][31]-2*eorbit[e][40]-1*eorbit[e][44]-2*eorbit[e][54])/2;
  1248. eorbit[e][15]=(f_15-2*eorbit[e][25]-2*eorbit[e][29]-1*eorbit[e][31]-2*eorbit[e][32]-1*eorbit[e][34]-2*eorbit[e][42]-2*eorbit[e][47]);
  1249. eorbit[e][14]=(f_14-1*eorbit[e][18]-2*eorbit[e][21]-1*eorbit[e][30]-2*eorbit[e][38]-1*eorbit[e][39]-2*eorbit[e][43]-1*eorbit[e][52])/2;
  1250. eorbit[e][13]=(f_13-2*eorbit[e][22]-2*eorbit[e][28]-1*eorbit[e][31]-1*eorbit[e][40]-2*eorbit[e][44]-2*eorbit[e][54]);
  1251. eorbit[e][12]=(f_12-2*eorbit[e][21]-2*eorbit[e][28]-2*eorbit[e][29]-2*eorbit[e][38]-2*eorbit[e][43]-1*eorbit[e][45]-1*eorbit[e][52]);
  1252. }
  1253. }
  1254. endTime = clock();
  1255. printf("%.2f\n", (double)(endTime-startTime)/CLOCKS_PER_SEC);
  1256. endTime_all = endTime;
  1257. printf("total: %.2f\n", (double)(endTime_all-startTime_all)/CLOCKS_PER_SEC);
  1258. }
  1259. int writeResults(int g, const char* output_filename) {
  1260. fstream fout;
  1261. if (fout.fail()) {
  1262. cerr << "Failed to open file " << output_filename << endl;
  1263. return 1;
  1264. }
  1265. fout.open(output_filename, fstream::out | fstream::binary);
  1266. int no[] = {0,0,1,4,15,73};
  1267. for (int i=0;i<n;i++) {
  1268. for (int j=0;j<no[g];j++) {
  1269. if (j!=0)
  1270. fout << " ";
  1271. fout << orbit[i][j];
  1272. }
  1273. fout << endl;
  1274. }
  1275. fout.close();
  1276. }
  1277. string writeResultsString(int g) {
  1278. std::stringstream ss("", ios_base::app | ios_base::out);
  1279. int no[] = {0,0,1,4,15,73};
  1280. for (int i=0;i<n;i++) {
  1281. for (int j=0;j<no[g];j++) {
  1282. if (j!=0)
  1283. ss << " ";
  1284. ss << orbit[i][j];
  1285. }
  1286. ss << endl;
  1287. }
  1288. return ss.str();
  1289. }
  1290. int writeEdgeResults(int g, const char* output_filename) {
  1291. fstream fout;
  1292. if (fout.fail()) {
  1293. cerr << "Failed to open file " << output_filename << endl;
  1294. return 1;
  1295. }
  1296. int no[] = {0,0,0,2,12,68};
  1297. for (int i=0;i<m;i++) {
  1298. for (int j=0;j<no[g];j++) {
  1299. if (j!=0) fout << " ";
  1300. fout << eorbit[i][j];
  1301. }
  1302. fout << endl;
  1303. }
  1304. fout.close();
  1305. }
  1306. string writeEdgeResultsString(int g) {
  1307. std::stringstream ss("", ios_base::app | ios_base::out);
  1308. int no[] = {0,0,0,2,12,68};
  1309. for (int i=0;i<m;i++) {
  1310. for (int j=0;j<no[g];j++) {
  1311. if (j!=0) ss << " ";
  1312. ss << eorbit[i][j];
  1313. }
  1314. ss << endl;
  1315. }
  1316. return ss.str();
  1317. }
  1318. int motif_counts(const char* orbit_type, int graphlet_size,
  1319. const char* input_filename, const char* output_filename, string &out_str) {
  1320. fstream fin; // input and output files
  1321. // open input, output files
  1322. if (strcmp(orbit_type, "node")!=0 && strcmp(orbit_type, "edge")!=0) {
  1323. cerr << "Incorrect orbit type '" << orbit_type << "'. Should be 'node' or 'edge'." << endl;
  1324. return 0;
  1325. }
  1326. if (graphlet_size!=4 && graphlet_size!=5) {
  1327. cerr << "Incorrect graphlet size " << graphlet_size << ". Should be 4 or 5." << endl;
  1328. return 0;
  1329. }
  1330. fin.open(input_filename, fstream::in);
  1331. if (fin.fail()) {
  1332. cerr << "Failed to open file " << input_filename << endl;
  1333. return 0;
  1334. }
  1335. // read input graph
  1336. fin >> n >> m;
  1337. int d_max=0;
  1338. edges = (PAIR*)malloc(m*sizeof(PAIR));
  1339. deg = (int*)calloc(n,sizeof(int));
  1340. for (int i=0;i<m;i++) {
  1341. int a,b;
  1342. fin >> a >> b;
  1343. if (!(0<=a && a<n) || !(0<=b && b<n)) {
  1344. cerr << "Node ids should be between 0 and n-1." << endl;
  1345. return 0;
  1346. }
  1347. if (a==b) {
  1348. cerr << "Self loops (edge from x to x) are not allowed." << endl;
  1349. return 0;
  1350. }
  1351. deg[a]++; deg[b]++;
  1352. edges[i]=PAIR(a,b);
  1353. }
  1354. for (int i=0;i<n;i++) d_max=max(d_max,deg[i]);
  1355. printf("nodes: %d\n",n);
  1356. printf("edges: %d\n",m);
  1357. printf("max degree: %d\n",d_max);
  1358. fin.close();
  1359. if ((int)(set<PAIR>(edges,edges+m).size())!=m) {
  1360. cerr << "Input file contains duplicate undirected edges." << endl;
  1361. return 0;
  1362. }
  1363. // set up adjacency matrix if it's smaller than 100MB
  1364. if ((int64)n*n < 100LL*1024*1024*8) {
  1365. adjacent = adjacent_matrix;
  1366. adj_matrix = (int*)calloc((n*n)/adj_chunk+1,sizeof(int));
  1367. for (int i=0;i<m;i++) {
  1368. int a=edges[i].a, b=edges[i].b;
  1369. adj_matrix[(a*n+b)/adj_chunk]|=(1<<((a*n+b)%adj_chunk));
  1370. adj_matrix[(b*n+a)/adj_chunk]|=(1<<((b*n+a)%adj_chunk));
  1371. }
  1372. } else {
  1373. adjacent = adjacent_list;
  1374. }
  1375. // set up adjacency, incidence lists
  1376. adj = (int**)malloc(n*sizeof(int*));
  1377. for (int i=0;i<n;i++) adj[i] = (int*)malloc(deg[i]*sizeof(int));
  1378. inc = (PII**)malloc(n*sizeof(PII*));
  1379. for (int i=0;i<n;i++) inc[i] = (PII*)malloc(deg[i]*sizeof(PII));
  1380. int *d = (int*)calloc(n,sizeof(int));
  1381. for (int i=0;i<m;i++) {
  1382. int a=edges[i].a, b=edges[i].b;
  1383. adj[a][d[a]]=b; adj[b][d[b]]=a;
  1384. inc[a][d[a]]=PII(b,i); inc[b][d[b]]=PII(a,i);
  1385. d[a]++; d[b]++;
  1386. }
  1387. for (int i=0;i<n;i++) {
  1388. sort(adj[i],adj[i]+deg[i]);
  1389. sort(inc[i],inc[i]+deg[i]);
  1390. }
  1391. // initialize orbit counts
  1392. orbit = (int64**)malloc(n*sizeof(int64*));
  1393. for (int i=0;i<n;i++) orbit[i] = (int64*)calloc(73,sizeof(int64));
  1394. // initialize edge orbit counts
  1395. eorbit = (int64**)malloc(m*sizeof(int64*));
  1396. for (int i=0;i<m;i++) eorbit[i] = (int64*)calloc(68,sizeof(int64));
  1397. if (strcmp(orbit_type,"node") == 0) {
  1398. printf("Counting NODE orbits of graphlets on %d nodes.\n\n",graphlet_size);
  1399. if (graphlet_size==4) count4();
  1400. if (graphlet_size==5) count5();
  1401. if (strcmp(output_filename, "std") == 0) {
  1402. cout << "orbit counts: \n" << writeResultsString(graphlet_size) << endl;
  1403. } else {
  1404. out_str = writeResults(graphlet_size, output_filename);
  1405. }
  1406. } else {
  1407. printf("Counting EDGE orbits of graphlets on %d nodes.\n\n",graphlet_size);
  1408. if (graphlet_size==4) ecount4();
  1409. if (graphlet_size==5) ecount5();
  1410. if (strcmp(output_filename, "std") == 0) {
  1411. cout << "orbit counts: \n" << writeEdgeResultsString(graphlet_size) << endl;
  1412. } else {
  1413. out_str = writeEdgeResults(graphlet_size, output_filename);
  1414. }
  1415. }
  1416. return 1;
  1417. }
  1418. int init(int argc, char *argv[]) {
  1419. if (argc!=5) {
  1420. cerr << "Incorrect number of arguments." << endl;
  1421. cerr << "Usage: orca.exe [orbit type: node|edge] [graphlet size: 4/5] [graph - input file] [graphlets - output file]" << endl;
  1422. return 0;
  1423. }
  1424. int graphlet_size;
  1425. sscanf(argv[2],"%d", &graphlet_size);
  1426. string out;
  1427. motif_counts(argv[1], graphlet_size, argv[3], argv[4], out);
  1428. return 1;
  1429. }
  1430. int main(int argc, char *argv[]) {
  1431. if (!init(argc, argv)) {
  1432. // cerr << "Stopping!" << endl;
  1433. return 1;
  1434. }
  1435. return 0;
  1436. }