Exemplo n.º 1
0
static void
makeprism_sg(sparsegraph *sg, sparsegraph *sh)
/* Make the cartesian product sh = sg x K2.
   sh must be initialized. */
{
    size_t *v,*vv,vi,vvi;
    int *d,*dd,*e,*ee;
    int i,j,n;

    SG_VDE(sg,v,d,e);
    n = sg->nv;

    SG_ALLOC(*sh,2*sg->nv,2*(n+sg->nde),"makeprism_sg");
    sh->nv = 2*n;
    sh->nde = 2*(n+sg->nde);
    SG_VDE(sh,vv,dd,ee);
 
    vvi = 0;
    for (i = 0; i < n; ++i)
    {
	vi = v[i];
	dd[2*i] = dd[2*i+1] = d[i] + 1;
	vv[2*i] = vvi;
	for (j = 0; j < d[i]; ++j) ee[vvi++] = 2*e[vi++];
	ee[vvi++] = 2*i+1;
	vi = v[i];
	vv[2*i+1] = vvi;
	for (j = 0; j < d[i]; ++j) ee[vvi++] = 2*e[vi++]+1;
	ee[vvi++] = 2*i;
    }
}
Exemplo n.º 2
0
int
static main(int argc, char *argv[])
{
    DYNALLSTAT(int,lab,lab_sz);
    DYNALLSTAT(int,ptn,ptn_sz);
    DYNALLSTAT(int,orbits,orbits_sz);
    static DEFAULTOPTIONS_SPARSEGRAPH(options);
    statsblk stats;
    sparsegraph sg;   /* Declare sparse graph structure */

    int n,m,i;

    options.writeautoms = TRUE;

 /* Initialise sparse graph structure. */

    SG_INIT(sg);

    while (1)
    {
        printf("\nenter n : ");
        if (scanf("%d",&n) == 1 && n > 0)
        {
            m = SETWORDSNEEDED(n);
            nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);

            DYNALLOC1(int,lab,lab_sz,n,"malloc");
            DYNALLOC1(int,ptn,ptn_sz,n,"malloc");
            DYNALLOC1(int,orbits,orbits_sz,n,"malloc");

         /* SG_ALLOC makes sure that the v,d,e fields of a sparse graph
            structure point to arrays that are large enough.  This only
            works if the structure has been initialised. */

            SG_ALLOC(sg,n,2*n,"malloc");

            sg.nv = n;              /* Number of vertices */
            sg.nde = 2*n;           /* Number of directed edges */

            for (i = 0; i < n; ++i)
            {
                sg.v[i] = 2*i;
                sg.d[i] = 2;
                sg.e[2*i] = (i+n-1)%n;      /* edge i->i-1 */
                sg.e[2*i+1] = (i+n+1)%n;    /* edge i->i+1 */
            }

            printf("Generators for Aut(C[%d]):\n",n);
            sparsenauty(&sg,lab,ptn,orbits,&options,&stats,NULL);

            printf("Automorphism group size = ");
            writegroupsize(stdout,stats.grpsize1,stats.grpsize2);
            printf("\n");
        }
        else
            break;
Exemplo n.º 3
0
int
static 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);
    static DEFAULTOPTIONS_TRACES(options);
    TracesStats stats;
 /* Declare and initialize sparse graph structures */
    SG_DECL(sg1); SG_DECL(sg2);
    SG_DECL(cg1); SG_DECL(cg2);

    int n,m,i;

 /* Select option for canonical labelling */

    options.getcanon = TRUE;
 
 /* Read a number of vertices and process */

    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 */

            SG_ALLOC(sg1,n,3*n,"malloc");
            sg1.nv = n;              /* Number of vertices */
            sg1.nde = 3*n;           /* Number of directed edges */

            for (i = 0; i < n; ++i)
            {
                sg1.v[i] = 3*i;     /* Position of vertex i in v array */
                sg1.d[i] = 3;       /* Degree of vertex i */
            }
             
            for (i = 0; i < n; i += 2)   /* Spokes */
            {
                sg1.e[sg1.v[i]] = i+1;
                sg1.e[sg1.v[i+1]] = i;
            }

            for (i = 0; i < n-2; ++i)  /* Clockwise edges */
                sg1.e[sg1.v[i]+1] = i+2;
            sg1.e[sg1.v[n-2]+1] = 1;
            sg1.e[sg1.v[n-1]+1] = 0;

            for (i = 2; i < n; ++i)  /* Anticlockwise edges */
                sg1.e[sg1.v[i]+2] = i-2;
            sg1.e[sg1.v[1]+2] = n-2;
            sg1.e[sg1.v[0]+2] = n-1;
                
         /* Now make the second graph */

            SG_ALLOC(sg2,n,3*n,"malloc");
            sg2.nv = n;              /* Number of vertices */
            sg2.nde = 3*n;           /* Number of directed edges */

            for (i = 0; i < n; ++i)
            {
                sg2.v[i] = 3*i;
                sg2.d[i] = 3;
            }

            for (i = 0; i < n; ++i)
            {
                sg2.v[i] = 3*i;
                sg2.d[i] = 3;
                sg2.e[sg2.v[i]] = (i+1) % n;      /* Clockwise */
                sg2.e[sg2.v[i]+1] = (i+n-1) % n;  /* Anti-clockwise */
                sg2.e[sg2.v[i]+2] = (i+n/2) % n;  /* Diagonals */
            }

         /* Label sg1, result in cg1 and labelling in lab1; similarly sg2.
            It is not necessary to pre-allocate space in cg1 and cg2, but
            they have to be initialised as we did above.  */
            
            Traces(&sg1,lab1,ptn,orbits,&options,&stats,&cg1);
            Traces(&sg2,lab2,ptn,orbits,&options,&stats,&cg2);

         /* Compare canonically labelled graphs */

            if (aresame_sg(&cg1,&cg2))
            {
                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;
    }
Exemplo n.º 4
0
static boolean
readblissgraph(FILE *f, sparsegraph *g)
/* Reads a graph from Bliss format into a sparse graph */
{
    int n,c;
    unsigned long ne,j;
    int haven;
    int i,v,w;
    int haveptn;
    DYNALLSTAT(vpair,elist,elist_sz);

    haven = 0;
    j = 0;
    while ((c = nextchar(f)) >= 0)
    {
	switch (c)
	{
	case 'c':
	    while ((c = getc(f)) != '\n' && c != EOF) {}
	    break;

	case 'p':
	    if (haven)
	    {
		fprintf(stderr,"Duplicate p line\n");
		exit(1);
	    }
	    if (fscanf(f," edge %d %lu",&n,&ne) != 2)
	    {
		fprintf(stderr,"Bad p line\n");
		return FALSE;
	    }
	    haven = 1;
            DYNALLOC1(vpair,elist,elist_sz,ne,"Alloc vpair");
	    break;

	case 'n':
	    if (!haven)
	    {
                fprintf(stderr,"Missing p line\n");
                return FALSE;
            }  
            if (fscanf(f,"%d%d",&w,&v) != 2 || w < 1 || w > n)
            {
                fprintf(stderr,"Bad n line\n");
                return FALSE;
            }
	    break;

	case 'e':
	    if (!haven || j == ne)
	    {
		fprintf(stderr,"Missing p line or too many e lines\n");
		return FALSE;
	    }
	    if (fscanf(f,"%d%d",&v,&w) != 2 || v < 1 || w < 1 || v > n || w > n)
	    {
		fprintf(stderr,"Bad e line\n");
		return FALSE;
	    }
	    elist[j].v = v-1; elist[j].w = w-1;
	    ++j;
	    break;

	default:
	    fprintf(stderr,"Unknown line %c\n",c);
	    return FALSE;
	}
    }

    if (j != ne)
    {
        fprintf(stderr,"Wrong number of e lines\n");
        exit(1);
    }

    SG_ALLOC(*g,n,2*ne,"SG_ALLOC");
    g->nv = n;
    g->nde = 2*ne;

    for (i = 0; i < n; ++i) g->d[i] = 0;
    for (j = 0; j < ne; ++j) 
    {
	++(g->d[elist[j].v]);
	++(g->d[elist[j].w]);
    }
    g->v[0] = 0;
    for (i = 1; i < n; ++i) g->v[i] = g->v[i-1] + g->d[i-1];
    for (i = 0; i < n; ++i) g->d[i] = 0;

    for (j = 0; j < ne; ++j) 
    {
	v = elist[j].v;
	w = elist[j].w;
        g->e[g->v[v]+(g->d[v])++] = w;
        g->e[g->v[w]+(g->d[w])++] = v;
    }

    return TRUE;
}
Exemplo n.º 5
0
int
main(int argc, char *argv[])
{
    DYNALLSTAT(int,p,p_sz);
    DYNALLSTAT(boolean,issquare,issquare_sz);
    DYNALLSTAT(int,lab,lab_sz);
    DYNALLSTAT(int,ptn,ptn_sz);
    DYNALLSTAT(int,orbits,orbits_sz);
    static DEFAULTOPTIONS_TRACES(options);
    TracesStats stats;
 /* Declare and initialize sparse graph structures */
    SG_DECL(sg);

    int deg,n,m,i,j;
    size_t k;
    permnode *gens;

 /* Select option for passing generators to Traces */

    options.generators = &gens;
 
 /* Read a number of vertices and process it */

    while (1)
    {
        printf("\nenter n : ");
        if (scanf("%d",&n) == 1 && n > 2)
        {
            m = SETWORDSNEEDED(n);
            nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);

            DYNALLOC1(int,lab,lab_sz,n,"malloc");
            DYNALLOC1(int,ptn,ptn_sz,n,"malloc");
            DYNALLOC1(int,orbits,orbits_sz,n,"malloc");
            DYNALLOC1(int,p,p_sz,n,"malloc");
            DYNALLOC1(boolean,issquare,issquare_sz,n,"malloc");

         /* Initialise list of automorphisms */

            gens = NULL;

         /* Find the squares and the degree */

            for (i = 0; i < n; ++i) issquare[i] = FALSE;
            for (i = 0; i < n; ++i) issquare[(i*i)%n] = TRUE;
            if (!issquare[n-1])
            {
                printf("-1 must be a square mod n; try again\n");
                continue;
            }

            deg = 0;
            for (i = 1; i < n; ++i) if (issquare[i]) ++deg;

         /* Now make the graph */

            SG_ALLOC(sg,n,n*deg,"malloc");
            sg.nv = n;              /* Number of vertices */
            sg.nde = n*deg;           /* Number of directed edges */

            for (i = 0; i < n; ++i)
            {
                sg.v[i] = i*deg;     /* Position of vertex i in v array */
                sg.d[i] = deg;       /* Degree of vertex i */
            }
             
            for (i = 0; i < n; ++i)   /* Edges */
            {
                k = sg.v[i];
                for (j = 1; j < n; ++j)
                    if (issquare[j]) sg.e[k++] = (i + j) % n;
            }

         /* Add known automorphisms */

            /* We wouldn't need freeschreier() if we were only
               processing one graph, but it doesn't hurt.  This
               is how to properly dispose of previous generators. */

            freeschreier(NULL,&gens);

            /* Cyclic rotation */
            for (i = 0; i < n; ++i) p[i] = (i + 1) % n;
            addpermutation(&gens,p,n);

            /* Reflection about 0 */
            for (i = 0; i < n; ++i) p[i] = (n - i) % n;
            addpermutation(&gens,p,n);

         /* Call Traces */
            
            Traces(&sg,lab,ptn,orbits,&options,&stats,NULL);

            printf("Automorphism group size = ");
            writegroupsize(stdout,stats.grpsize1,stats.grpsize2);
            printf("\n");

        /* Traces left the automorphims we gave it, augmented by
           any extra automorphims it found, in a circular list
           pointed to by gens.  See schreier.txt for documentation. */
        }
        else
            break;
Exemplo n.º 6
0
static void*
runit(void * threadarg)          /* Main routine for one thread */
{
    DYNALLSTAT(int,lab,lab_sz);
    DYNALLSTAT(int,ptn,ptn_sz);
    DYNALLSTAT(int,orbits,orbits_sz);
    DEFAULTOPTIONS_SPARSEGRAPH(options);
    statsblk stats;
    sparsegraph sg;   /* Declare sparse graph structure */

    int n,m,i;

    n = ((params*)threadarg)->n;
    options.writeautoms = ((params*)threadarg)->writeautoms;

 /* Initialise sparse graph structure. */

    SG_INIT(sg);

    m = SETWORDSNEEDED(n);
    nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);

    DYNALLOC1(int,lab,lab_sz,n,"malloc");
    DYNALLOC1(int,ptn,ptn_sz,n,"malloc");
    DYNALLOC1(int,orbits,orbits_sz,n,"malloc");

 /* SG_ALLOC makes sure that the v,d,e fields of a sparse graph
    structure point to arrays that are large enough.  This only
    works if the structure has been initialised. */

    SG_ALLOC(sg,n,2*n,"malloc");

    sg.nv = n;              /* Number of vertices */
    sg.nde = 2*n;           /* Number of directed edges */

    for (i = 0; i < n; ++i)
    {
        sg.v[i] = 2*i;
        sg.d[i] = 2;
        sg.e[2*i] = (i+n-1)%n;      /* edge i->i-1 */
        sg.e[2*i+1] = (i+n+1)%n;    /* edge i->i+1 */
    }

    if (options.writeautoms)
        printf("Generators for Aut(C[%d]):\n",n);
    sparsenauty(&sg,lab,ptn,orbits,&options,&stats,NULL);

    if (options.writeautoms)
    {
        printf("Automorphism group size = ");
        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. */

    SG_FREE(sg);
    DYNFREE(lab,lab_sz);
    DYNFREE(ptn,ptn_sz);
    DYNFREE(orbits,orbits_sz);
    nauty_freedyn();
    nautil_freedyn();
    nausparse_freedyn();  /* Use naugraph_freedyn() instead if
                            dense format is being used. */

    return NULL;
}
Exemplo n.º 7
0
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;
	    }
    }
}
Exemplo n.º 8
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;
        }
    }
}