static void na_newedge(graph *g1, int m1, int n1, boolean dolabel) /* Make all graphs by non-adjacent edge addition. */ { int n2,m2; int v1,v2,w1,w2; set *sv1,*sw1; graph *gq; #if MAXN graph h[MAXN*MAXM]; grapg g2[MAXN*MAXM]; #else DYNALLSTAT(graph,h,h_sz); DYNALLSTAT(graph,g2,g2_sz); #endif n2 = n1 + 2; m2 = (n2 + WORDSIZE - 1) / WORDSIZE; if (m2 < m1) m2 = m1; #if !MAXN DYNALLOC2(graph,g2,g2_sz,m2,n2,"newedgeg"); if (dolabel) DYNALLOC2(graph,h,h_sz,m2,n2,"newedgeg"); #endif for (v1 = 0, sv1 = g1; v1 < n1-3; ++v1, sv1 += m1) for (w1 = v1+1, sw1 = sv1 + m1; w1 < n1-1; ++w1, sw1 += m1) { for (v2 = v1; (v2 = nextelement(sv1,m1,v2)) >= 0; ) for (w2 = w1; (w2 = nextelement(sw1,m1,w2)) >= 0; ) { if (v2 == w1 || v2 == w2) continue; newedge(g1,m1,n1,v1,v2,w1,w2,g2,m2); gq = g2; if (dolabel) { fcanonise(g2,m2,n2,h,NULL,FALSE); /* FIXME (loops) */ gq = h; } if (outcode == SPARSE6) writes6(outfile,gq,m2,n2); else writeg6(outfile,gq,m2,n2); ++nout; } } }
int main(int argc, char *argv[]) { DYNALLSTAT(graph,g,g_sz); DYNALLSTAT(int,lab,lab_sz); DYNALLSTAT(int,ptn,ptn_sz); DYNALLSTAT(int,orbits,orbits_sz); static DEFAULTOPTIONS_GRAPH(options); statsblk stats; int n,m,v; grouprec *group; /* The following cause nauty to call two procedures which store the group information as nauty runs. */ options.userautomproc = groupautomproc; options.userlevelproc = grouplevelproc; while (1) { printf("\nenter n : "); if (scanf("%d",&n) == 1 && n > 0) { m = SETWORDSNEEDED(n); nauty_check(WORDSIZE,m,n,NAUTYVERSIONID); DYNALLOC2(graph,g,g_sz,m,n,"malloc"); DYNALLOC1(int,lab,lab_sz,n,"malloc"); DYNALLOC1(int,ptn,ptn_sz,n,"malloc"); DYNALLOC1(int,orbits,orbits_sz,n,"malloc"); EMPTYGRAPH(g,m,n); for (v = 0; v < n; ++v) ADDONEEDGE(g,v,(v+1)%n,m); printf("Automorphisms of C[%d]:\n",n); densenauty(g,lab,ptn,orbits,&options,&stats,m,n,NULL); /* Get a pointer to the structure in which the group information has been stored. If you use TRUE as an argument, the structure will be "cut loose" so that it won't be used again the next time nauty() is called. Otherwise, as here, the same structure is used repeatedly. */ group = groupptr(FALSE); /* Expand the group structure to include a full set of coset representatives at every level. This step is necessary if allgroup() is to be called. */ makecosetreps(group); /* Call the procedure writeautom() for every element of the group. The first call is always for the identity. */ allgroup(group,writeautom); } else break;
int main(int argc, char *argv[]) { DYNALLSTAT(int,lab1,lab1_sz); DYNALLSTAT(int,lab2,lab2_sz); DYNALLSTAT(int,ptn,ptn_sz); DYNALLSTAT(int,orbits,orbits_sz); DYNALLSTAT(int,map,map_sz); DYNALLSTAT(graph,g1,g1_sz); DYNALLSTAT(graph,g2,g2_sz); DYNALLSTAT(graph,cg1,cg1_sz); DYNALLSTAT(graph,cg2,cg2_sz); static DEFAULTOPTIONS_GRAPH(options); statsblk stats; int n,m,i; size_t k; /* Select option for canonical labelling */ options.getcanon = TRUE; while (1) { printf("\nenter n : "); if (scanf("%d",&n) == 1 && n > 0) { if (n%2 != 0) { fprintf(stderr,"Sorry, n must be even\n"); continue; } m = SETWORDSNEEDED(n); nauty_check(WORDSIZE,m,n,NAUTYVERSIONID); DYNALLOC1(int,lab1,lab1_sz,n,"malloc"); DYNALLOC1(int,lab2,lab2_sz,n,"malloc"); DYNALLOC1(int,ptn,ptn_sz,n,"malloc"); DYNALLOC1(int,orbits,orbits_sz,n,"malloc"); DYNALLOC1(int,map,map_sz,n,"malloc"); /* Now make the first graph */ DYNALLOC2(graph,g1,g1_sz,n,m,"malloc"); EMPTYGRAPH(g1,m,n); for (i = 0; i < n; i += 2) /* Spokes */ ADDONEEDGE(g1,i,i+1,m); for (i = 0; i < n-2; ++i) /* Cycle */ ADDONEEDGE(g1,i,i+2,m); ADDONEEDGE(g1,1,n-2,m); ADDONEEDGE(g1,0,n-1,m); /* Now make the second graph */ DYNALLOC2(graph,g2,g2_sz,n,m,"malloc"); EMPTYGRAPH(g2,m,n); for (i = 0; i < n; ++i) { ADDONEEDGE(g2,i,(i+1)%n,m); /* Rim */ ADDONEEDGE(g2,i,(i+n/2)%n,m); /* Diagonals */ } /* Create canonical graphs */ DYNALLOC2(graph,cg1,cg1_sz,n,m,"malloc"); DYNALLOC2(graph,cg2,cg2_sz,n,m,"malloc"); densenauty(g1,lab1,ptn,orbits,&options,&stats,m,n,cg1); densenauty(g2,lab2,ptn,orbits,&options,&stats,m,n,cg2); /* Compare canonically labelled graphs */ for (k = 0; k < m*(size_t)n; ++k) if (cg1[k] != cg2[k]) break; if (k == m*(size_t)n) { printf("Isomorphic.\n"); if (n <= 1000) { /* Write the isomorphism. For each i, vertex lab1[i] of sg1 maps onto vertex lab2[i] of sg2. We compute the map in order of labelling because it looks better. */ for (i = 0; i < n; ++i) map[lab1[i]] = lab2[i]; for (i = 0; i < n; ++i) printf(" %d-%d",i,map[i]); printf("\n"); } } else printf("Not isomorphic.\n"); } else break; }
static void* runit(void * threadarg) /* Main routine for one thread */ { DYNALLSTAT(graph,g,g_sz); DYNALLSTAT(int,lab,lab_sz); DYNALLSTAT(int,ptn,ptn_sz); DYNALLSTAT(int,orbits,orbits_sz); DEFAULTOPTIONS_GRAPH(options); statsblk stats; set *gv; int n,m,v; n = ((params*)threadarg)->n; /* Default options are set by the DEFAULTOPTIONS_GRAPH macro above. Here we change those options that we want to be different from the defaults. writeautoms=TRUE causes automorphisms to be written. */ options.writeautoms = ((params*)threadarg)->writeautoms; m = SETWORDSNEEDED(n); /* The following optional call verifies that we are linking to compatible versions of the nauty routines. */ nauty_check(WORDSIZE,m,n,NAUTYVERSIONID); DYNALLOC2(graph,g,g_sz,m,n,"malloc"); DYNALLOC1(int,lab,lab_sz,n,"malloc"); DYNALLOC1(int,ptn,ptn_sz,n,"malloc"); DYNALLOC1(int,orbits,orbits_sz,n,"malloc"); /* Now we will make a polygon of n vertices */ EMPTYGRAPH(g,m,n); for (v = 0; v < n; ++v) ADDONEEDGE(g,v,(v+1)%n,m); if (options.writeautoms) printf("Generators for Aut(C[%d]):\n",n); densenauty(g,lab,ptn,orbits,&options,&stats,m,n,NULL); if (options.writeautoms) { printf("order = "); writegroupsize(stdout,stats.grpsize1,stats.grpsize2); printf("\n"); } if (stats.numorbits != 1 || stats.grpsize1 != 2*n) fprintf(stderr,">E group error\n"); /* If we are using multiple threads, we need to free all the dynamic memory we have allocated. We don't have to do this after each call to nauty, just once before the thread finishes. */ DYNFREE(g,g_sz); DYNFREE(lab,lab_sz); DYNFREE(ptn,ptn_sz); DYNFREE(orbits,orbits_sz); nauty_freedyn(); nautil_freedyn(); naugraph_freedyn(); /* Use nausparse_freedyn() instead if sparse format is being used. */ return NULL; }
int main(int argc, char *argv[]) { DYNALLSTAT(int,lab1,lab1_sz); DYNALLSTAT(int,lab2,lab2_sz); DYNALLSTAT(int,ptn,ptn_sz); DYNALLSTAT(int,orbits,orbits_sz); DYNALLSTAT(int,map,map_sz); DYNALLSTAT(graph,g1,g1_sz); DYNALLSTAT(graph,g2,g2_sz); DYNALLSTAT(graph,cg1,cg1_sz); DYNALLSTAT(graph,cg2,cg2_sz); static DEFAULTOPTIONS_GRAPH(options); statsblk stats; int n,m,i; /* Select option for canonical labelling */ options.getcanon = TRUE; while (1) { printf("\nenter n : "); if (scanf("%d",&n) == 1 && n > 0) { if (n%2 != 0) { fprintf(stderr,"Sorry, n must be even\n"); continue; } m = SETWORDSNEEDED(n); nauty_check(WORDSIZE,m,n,NAUTYVERSIONID); DYNALLOC1(int,lab1,lab1_sz,n,"malloc"); DYNALLOC1(int,lab2,lab2_sz,n,"malloc"); DYNALLOC1(int,ptn,ptn_sz,n,"malloc"); DYNALLOC1(int,orbits,orbits_sz,n,"malloc"); DYNALLOC1(int,map,map_sz,n,"malloc"); DYNALLOC2(graph,g1,g1_sz,n,m,"malloc"); DYNALLOC2(graph,g2,g2_sz,n,m,"malloc"); DYNALLOC2(graph,cg1,cg1_sz,n,m,"malloc"); DYNALLOC2(graph,cg2,cg2_sz,n,m,"malloc"); /* Now make the first graph */ /* ADDEDGE() is defined above */ EMPTYGRAPH(g1,m,n); /* start with no edges */ for (i = 0; i < n-2; ++i) ADDONEEDGE(g1,i,i+2,m); ADDONEEDGE(g1,n-2,1,m); ADDONEEDGE(g1,n-1,0,m); for (i = 0; i < n; i += 2) ADDONEEDGE(g1,i,i+1,m); /* Now make the second graph */ EMPTYGRAPH(g2,m,n); /* start with no edges */ for (i = 0; i < n-1; ++i) ADDONEEDGE(g2,i,i+1,m); ADDONEEDGE(g2,n-1,0,m); for (i = 0; i < n/2; ++i) ADDONEEDGE(g2,i,i+n/2,m); /* Label g1, result in cg1 and labelling in lab1; similarly g2. It is not necessary to pre-allocate space in cg1 and cg2, but they have to be initialised as we did above. */ densenauty(g1,lab1,ptn,orbits,&options,&stats,m,n,cg1); densenauty(g2,lab2,ptn,orbits,&options,&stats,m,n,cg2); /* Compare canonically labelled graphs */ if (memcmp(cg1,cg2,m*sizeof(graph)*n) == 0) { printf("Isomorphic.\n"); if (n <= 1000) { /* Write the isomorphism. For each i, vertex lab1[i] of sg1 maps onto vertex lab2[i] of sg2. We compute the map in order of labelling because it looks better. */ for (i = 0; i < n; ++i) map[lab1[i]] = lab2[i]; for (i = 0; i < n; ++i) printf(" %d-%d",i,map[i]); printf("\n"); } } else printf("Not isomorphic.\n"); } else break; }