static void subdivisiongraph(sparsegraph *g, int k, sparsegraph *h) /* h := subdivision graph of g, k new vertices per edge */ { DYNALLSTAT(size_t,eno,eno_sz); /* edge number */ int *ge,*gd,*he,*hd; size_t *gv,*hv; int gnv,hnv; size_t i,j,l,gnde,hnde,num; size_t hi,lo,mid,w; if (k == 0) { copy_sg(g,h); return; } sortlists_sg(g); SG_VDE(g,gv,gd,ge); gnv = g->nv; gnde = g->nde; DYNALLOC1(size_t,eno,eno_sz,gnde,"subdivideg"); hnv = gnv + k*(gnde/2); if (hnv <= 0 || (gnde > 0 && ((size_t)(hnv-gnv))/(gnde/2) != k)) gt_abort(">E subdivideg: output graph too large\n"); hnde = gnde * (k+1); if (hnde/(k+1) != gnde) gt_abort(">E subdivideg: output graph too large\n"); num = 0; for (i = 0; i < gnv; ++i) { for (j = gv[i]; j < gv[i]+gd[i]; ++j) { if (ge[j] == i) gt_abort(">E subdivideg can't handle undirected loops\n"); else if (ge[j] > i) eno[j] = num++; else { lo = gv[ge[j]]; hi = lo + gd[ge[j]] - 1; while (lo <= hi) { mid = lo + (hi-lo)/2; if (ge[mid] == i) break; else if (ge[mid] < i) lo = mid+1; else hi = mid-1; } if (lo > hi) gt_abort(">E subdivideg : binary search failed\n"); eno[j] = eno[mid]; } } } SG_ALLOC(*h,hnv,hnde,"subdivideg"); h->nv = hnv; h->nde = hnde; SG_VDE(h,hv,hd,he); for (i = 0; i < gnv; ++i) { hd[i] = gd[i]; hv[i] = gv[i]; } for (i = gnv; i < hnv; ++i) { hd[i] = 2; hv[i] = gnde + 2*(i-gnv); } for (i = 0; i < gnv; ++i) { for (j = gv[i]; j < gv[i]+gd[i]; ++j) if (ge[j] > i) { w = gnv + k*eno[j]; he[j] = w; he[hv[w]] = i; for (l = 1; l < k; ++l) { he[hv[w]+1] = w+1; he[hv[w+1]] = w; ++w; } } else { w = gnv + k*eno[j] + k - 1; he[j] = w; he[hv[w]+1] = i; } } }
int main(int argc, char** argv) { char buffer[1500]; int print_orig = 0; if ( argc > 1 ) { print_orig = 1; } while ( scanf("%s", buffer) != EOF ) { /* buffer holds an s6 string */ sparsegraph g; SG_INIT(g); int num_loops; stringtosparsegraph(buffer, &g, &num_loops); int nv = g.nv; int m = (nv + WORDSIZE - 1) / WORDSIZE; nauty_check(WORDSIZE, m, nv, NAUTYVERSIONID); DYNALLSTAT(int, lab, lab_n); DYNALLSTAT(int, ptn, ptn_n); DYNALLSTAT(int, orbits, orbits_n); DYNALLOC1(int, lab, lab_n, nv, "malloc"); DYNALLOC1(int, ptn, ptn_n, nv, "malloc"); DYNALLOC1(int, orbits, orbits_n, nv, "malloc"); static DEFAULTOPTIONS_SPARSEGRAPH( options); options.defaultptn = TRUE; /* Don't need colors */ options.getcanon = TRUE; /* gets labels */ options.digraph = TRUE; statsblk stats; /* we'll use this at the end */ DYNALLSTAT(setword, workspace, worksize); DYNALLOC1(setword, workspace, worksize, 50 * m, "malloc"); sparsegraph canon_g; SG_INIT(canon_g); /* call nauty */ nauty((graph*) &g, lab, ptn, NULL, orbits, &options, &stats, workspace, 50 * m, m, g.nv, (graph*) &canon_g); sortlists_sg(&canon_g); char* canon_str = sgtos6(&canon_g); int canon_len = strlen(canon_str); if ( print_orig == 0 ) { printf("%s", canon_str); } else { canon_str[canon_len-1] = 0; printf("%s", canon_str); printf("\t%s\n", buffer); } /* free workspace */ DYNFREE(workspace, worksize); DYNFREE(lab,lab_n); DYNFREE(ptn,ptn_n); DYNFREE(orbits,orbits_n); SG_FREE(canon_g); SG_FREE(g); } return 0; }
static void linegraph(sparsegraph *g, sparsegraph *h) /* h := linegraph of g */ { DYNALLSTAT(size_t,eno,eno_sz); /* edge number */ int *ge,*gd,*he,*hd; size_t *gv,*hv; int gnv,hnv; size_t i,j,k,gnde,hnde,xhnde,num; size_t hi,lo,mid,v,w; sortlists_sg(g); SG_VDE(g,gv,gd,ge); gnv = g->nv; gnde = g->nde; DYNALLOC1(size_t,eno,eno_sz,gnde,"linegraphg"); hnv = gnde/2; if (hnv != gnde/2) gt_abort(">E linegraphg: too many input edges\n"); hnde = 0; num = 0; for (i = 0; i < gnv; ++i) { xhnde = hnde; hnde += gd[i]*((size_t)gd[i]-1); if (hnde < xhnde) gt_abort(">E linegraphg: too many output edges\n"); for (j = gv[i]; j < gv[i]+gd[i]; ++j) { if (ge[j] == i) gt_abort(">E linegraphg can't handle loops\n"); else if (ge[j] > i) eno[j] = num++; else { lo = gv[ge[j]]; hi = lo + gd[ge[j]] - 1; while (lo <= hi) { mid = lo + (hi-lo)/2; if (ge[mid] == i) break; else if (ge[mid] < i) lo = mid+1; else hi = mid-1; } if (lo > hi) gt_abort(">E linegraphg : binary search failed\n"); eno[j] = eno[mid]; } } } SG_ALLOC(*h,hnv,hnde,"linegraphg"); h->nv = hnv; h->nde = hnde; SG_VDE(h,hv,hd,he); for (i = 0; i < hnv; ++i) hd[i] = 0; for (i = 0; i < gnv; ++i) { for (j = gv[i]; j < gv[i]+gd[i]; ++j) hd[eno[j]] += gd[i]-1; } hv[0] = 0; for (i = 1; i < hnv; ++i) hv[i] = hv[i-1] + hd[i-1]; for (i = 0; i < hnv; ++i) hd[i] = 0; for (i = 0; i < gnv; ++i) { for (j = gv[i]; j < gv[i]+gd[i]-1; ++j) for (k = j+1; k < gv[i]+gd[i]; ++k) { v = eno[j]; w = eno[k]; he[hv[v]+(hd[v]++)] = w; he[hv[w]+(hd[w]++)] = v; } } }