Exemple #1
0
void
fmperm(permutation *perm, set *fix, set *mcr, int m, int n)
{
    register int i,k,l;

#if !MAXN
    DYNALLOC1(permutation,workperm,workperm_sz,n,"writeperm");
#endif

    EMPTYSET(fix,m);
    EMPTYSET(mcr,m);

    for (i = n; --i >= 0;) workperm[i] = 0;

    for (i = 0; i < n; ++i)
        if (perm[i] == i)
        {
            ADDELEMENT(fix,i);
            ADDELEMENT(mcr,i);
        }
        else if (workperm[i] == 0)
        {
            l = i;
            do
            {
                k = l;
                l = perm[l];
                workperm[k] = 1;
            }
            while (l != i);

            ADDELEMENT(mcr,i);
        }
}
Exemple #2
0
static boolean
ismax(int *p, int n)
/* test if x^p <= x */
{
    int i,j,k;
    set px[MAXME];

    EMPTYSET(px,me);

    for (j = 0; j < nix; ++j)
    {
        i = ix[j];
        k = i >> 1;
        if (i & 1) ADDELEMENT(px,edgeno[p[v1[k]]][p[v0[k]]]);
        else       ADDELEMENT(px,edgeno[p[v0[k]]][p[v1[k]]]);

        if (px[0] > x[0])
        {
            rejectlevel = k;
            return FALSE;
        }
    }

    rejectlevel = MAXNE+1;

    if (px[0] < x[0]) return TRUE;

    for (i = 1; i < me; ++i)
        if      (px[i] > x[i]) return FALSE;
        else if (px[i] < x[i]) return TRUE;

    ++newgroupsize;
    ntgroup = TRUE;
    return TRUE;
}
Exemple #3
0
void
permset(set *set1, set *set2, int m, permutation *perm)
{
    register setword setw;
    register int pos,w,b;

    EMPTYSET(set2,m);

#if  MAXM==1
    setw = set1[0];
    while (setw  != 0)
    {
        TAKEBIT(b,setw);
        pos = perm[b];
        ADDELEMENT(set2,pos);
    }
#else
    for (w = 0; w < m; ++w)
    {
        setw = set1[w];
        while (setw != 0)
        {
            TAKEBIT(b,setw);
            pos = perm[TIMESWORDSIZE(w)+b];
            ADDELEMENT(set2,pos);
        }
    }
#endif
}
Exemple #4
0
static void
makecanon(graph *g, graph *gcan, int n1, int n2)
/* gcan := canonise(g) */
{
    int lab[MAXN],ptn[MAXN],orbits[MAXN];
    setword active[1];
    int i;
    statsblk stats;
    static DEFAULTOPTIONS_GRAPH(options);
    setword workspace[50];

    options.writemarkers = FALSE;
    options.writeautoms = FALSE;
    options.getcanon = TRUE;
    options.defaultptn = FALSE;

    for (i = 0; i < n1+n2; ++i)
    {
        lab[i] = i;
        ptn[i] = 1;
    }
    ptn[n1-1] = ptn[n1+n2-1] = 0;
    EMPTYSET(active,1);
    ADDELEMENT(active,0);
    ADDELEMENT(active,n1);

    nauty(g,lab,ptn,active,orbits,&options,&stats,
                                         workspace,50,1,n1+n2,gcan);
}
Exemple #5
0
static void add_edges(graph_info *g, unsigned start, int extended_m,
					  level *my_level)
{
	//setup m and k[n] for the children
	//note that these values will not change b/w each child
	//of this node in the search tree
	g->m++;
	g->k[g->n - 1]++;
	unsigned old_max_k = g->max_k;
	if(g->k[g->n - 1] > g->max_k)
		g->max_k = g->k[g->n - 1];
	
	//if the child has a node of degree greater than MAX_K,
	//don't search it
	if(g->k[g->n - 1] <= my_level->max_k)
	{
		for(unsigned i = start; i < g->n - 1; i++)
		{
			g->k[i]++;
			
			//same as comment above
			if(g->k[i] <= my_level->max_k)
			{
				unsigned old_max_k = g->max_k;
				if(g->k[i] > g->max_k)
					g->max_k = g->k[i];
				
				g->distances[g->n*i + (g->n-1)] = g->distances[g->n*(g->n-1) + i] = 1;
				ADDELEMENT(GRAPHROW(g->nauty_graph, i, extended_m), g->n-1);
				ADDELEMENT(GRAPHROW(g->nauty_graph, g->n-1, extended_m), i);
				
				add_edges(g, i + 1, extended_m, my_level);
				
				DELELEMENT(GRAPHROW(g->nauty_graph, i, extended_m), g->n-1);
				DELELEMENT(GRAPHROW(g->nauty_graph, g->n-1, extended_m), i);
				g->distances[g->n*i + (g->n-1)] = g->distances[g->n*(g->n-1) + i] = GRAPH_INFINITY;
				g->max_k = old_max_k;
			}
			g->k[i]--;
		}
	}
	
	//tear down values we created in the beginning
	g->max_k = old_max_k;
	g->m--;
	g->k[g->n - 1]--;
	
	
	if(g->k[g->n - 1] > 0)
	{
		graph_info *temporary = new_graph_info(*g);
		fill_dist_matrix(*temporary); 
		temporary->diameter = calc_diameter(*temporary); 
		temporary->sum_of_distances = calc_sum(*temporary); 
		if(!add_graph_to_level(temporary, my_level))
			graph_info_destroy(temporary);
	}
}
void translate(GRAPH *g, NAUTYGRAPH nautyg, int m, int newOrder) {

    int i, j, k, dummy;

    dummy = g->order;

    for (i = 0; i < newOrder * m; i++) nautyg[i] = 0;

    for (i = 0; i < g->order; i++) {
        for (j = 0; j < 3; j++) {
            int neighbour = g->adjacency[i][j];
            if (neighbour == SEMIEDGE) neighbour = dummy++;
            if (neighbour > i) {
                if (g->colours[i][j] == 0) {
                    ADDELEMENT(nautyg + (m * i), neighbour);
                    ADDELEMENT(nautyg + (m * neighbour), i);
                } else {
                    int next = dummy++;
                    ADDELEMENT(nautyg + (m * i), next);
                    ADDELEMENT(nautyg + (m * next), i);
                    for (k = 0; k < g->colours[i][j] - 1; k++) {
                        ADDELEMENT(nautyg + (m * dummy), next);
                        ADDELEMENT(nautyg + (m * next), dummy);
                        next = dummy++;
                    }
                    ADDELEMENT(nautyg + (m * neighbour), next);
                    ADDELEMENT(nautyg + (m * next), neighbour);
                }
            }
        }
    }
}
Exemple #7
0
void
Nauty::addElement(int ix, int jx)
{
  // Right now die if bad index.  Can throw exception later
  //printf("addelement %d %d \n", ix, jx);
  assert(ix < n_ && jx < n_);
  if(ix != jx){  //No Loops
    set *gv = GRAPHROW(G_, ix, m_);
    ADDELEMENT(gv, jx);
    set *gv2 = GRAPHROW(G_, jx, m_);
    ADDELEMENT(gv2, ix);
    autoComputed_ = false;
  }
}
Exemple #8
0
void
targetcell(graph *g, int *lab, int *ptn, int level, int numcells,
           set *tcell, int *tcellsize, int *cellpos, int tc_level,
           int hint, int (*goodcell)(graph*,int*,int*,int,int,int,int),
           int m, int n)
{
    register int i,j,k;

    if (hint >= 0 && ptn[hint] > level &&
            (hint == 0 || ptn[hint-1] <= level))
        i = hint;
    else if (level <= tc_level && goodcell != NULL)
        i = (*goodcell)(g,lab,ptn,level,tc_level,m,n);
    else
        for (i = 0; i < n && ptn[i] <= level; ++i) {}

    if (i == n)
        i = j = 0;
    else
        for (j = i + 1; ptn[j] > level; ++j) {}

    *tcellsize = j - i + 1;

    EMPTYSET(tcell,m);
    for (k = i; k <= j; ++k) ADDELEMENT(tcell,lab[k]);

    *cellpos = i;
}
Exemple #9
0
void
compl(graph *g, int m, int n, graph *h)
/* h := complement of g */
{
	int i,j;
	setword *gi,*hi;
#if MAXN
	set all[MAXM];
#else
	DYNALLSTAT(set,all,all_sz);
	DYNALLOC1(set,all,all_sz,m,"complg");
#endif

	EMPTYSET(all,m);
	for (i = 0; i < n; ++i) ADDELEMENT(all,i);

	gi = (setword*) g;
	hi = (setword*) h;

	for (i = 0; i < n; ++i)
	{
	    for (j = 0; j < m; ++j) hi[j] = gi[j] ^ all[j];
	    DELELEMENT(hi,i);
	    gi += m;
	    hi += m;
	}
}
Exemple #10
0
static void
newedge(graph *g1, int m1, int n1,
        int v1, int v2, int w1, int w2,
        graph *g2, int m2)
/* Make g2 by subdividing edges v1-v2 and w1-w2 in g1
   and adding an edge between them.  Must have m2 >= m1.  */
{
    int i,j;
    setword *s1,*s2;

    s1 = g1;
    s2 = g2;
    for (i = 0; i < n1; ++i)
    {
        for (j = 0; j < m1; ++j) *(s2++) = *(s1++);
        for (; j < m2; ++j) *(s2++) = 0;
    }

    s2 = GRAPHROW(g2,v1,m2);
    DELELEMENT(s2,v2);
    ADDELEMENT(s2,n1);

    s2 = GRAPHROW(g2,v2,m2);
    DELELEMENT(s2,v1);
    ADDELEMENT(s2,n1);

    s2 = GRAPHROW(g2,w1,m2);
    DELELEMENT(s2,w2);
    ADDELEMENT(s2,n1+1);

    s2 = GRAPHROW(g2,w2,m2);
    DELELEMENT(s2,w1);
    ADDELEMENT(s2,n1+1);

    s2 = GRAPHROW(g2,n1,m2);
    EMPTYSET(s2,m2);
    ADDELEMENT(s2,v1);
    ADDELEMENT(s2,v2);
    ADDELEMENT(s2,n1+1);

    s2 = GRAPHROW(g2,n1+1,m2);
    EMPTYSET(s2,m2);
    ADDELEMENT(s2,w1);
    ADDELEMENT(s2,w2);
    ADDELEMENT(s2,n1);
}
Exemple #11
0
void translate(GRAPH *g, NAUTYGRAPH nautyg, int m, int newOrder) {

    int i, j, dummy;

    dummy = g->order;

    for (i = 0; i < newOrder * m; i++) nautyg[i] = 0;

    for (i = 0; i < g->order; i++) {
        boolean multiedgeHandled = FALSE;
        for (j = 0; j < 3; j++) {
            int neighbour = g->adjacency[i][j];
            if (neighbour == SEMIEDGE) neighbour = dummy++;
            if (neighbour > i) {
                if (g->multiedge[i] == neighbour && !multiedgeHandled) {
                    int extraNeighbour = dummy++;
                    ADDELEMENT(nautyg + (m * i), extraNeighbour);
                    ADDELEMENT(nautyg + (m * extraNeighbour), i);
                    ADDELEMENT(nautyg + (m * extraNeighbour), neighbour);
                    ADDELEMENT(nautyg + (m * neighbour), extraNeighbour);
                    multiedgeHandled = TRUE;
                } else {
                    ADDELEMENT(nautyg + (m * i), neighbour);
                    ADDELEMENT(nautyg + (m * neighbour), i);
                }
            }
        }
    }
}
Exemple #12
0
int
permcycles(int *p, int n, int *len, boolean sort)
/* Puts in len[0..] the cycle lengths of p.  If sort, sort them. 
   Return the number of cycles. */
{
    int m,i,j,k,h,nc,leni;

    m = (n + WORDSIZE - 1) / WORDSIZE;
    DYNALLOC1(set,workset,workset_sz,m,"malloc");

    EMPTYSET(workset,m);

    nc = 0;
    for (i = 0; i < n; ++i)
        if (!ISELEMENT(workset,i))
	{
	    k = 1;
	    for (j = p[i]; j != i; j = p[j]) 
	    {
		ADDELEMENT(workset,j);
		++k;
	    }
	    len[nc++] = k;
	}

    if (sort && nc > 1)
    {
	j = nc / 3;
        h = 1;
        do
            h = 3 * h + 1;
        while (h < j);

	do
        {
            for (i = h; i < nc; ++i)
            {
                leni = len[i];
                for (j = i; len[j-h] > leni; )
                {
                    len[j] = len[j-h];
                    if ((j -= h) < h) break;
                }
                len[j] = leni;
            }
            h /= 3;
        }
        while (h > 0);
    }

    return nc;
}
Exemple #13
0
void
fmptn(int *lab, int *ptn, int level, set *fix, set *mcr, int m, int n)
{
    register int i,lmin;

    EMPTYSET(fix,m);
    EMPTYSET(mcr,m);

    for (i = 0; i < n; ++i)
        if (ptn[i] <= level)
        {
            ADDELEMENT(fix,lab[i]);
            ADDELEMENT(mcr,lab[i]);
        }
        else
        {
            lmin = lab[i];
            do
                if (lab[++i] < lmin) lmin = lab[i];
            while (ptn[i] > level);
            ADDELEMENT(mcr,lmin);
        }
}
void
maketargetcell(graphnau *g, int *lab, int *ptn, int level, set *tcell,
           int *tcellsize, int *cellpos, int tc_level, boolean digraph,
	   int hint,
           int (*targetcell)(graphnau*,int*,int*,int,int,boolean,int,int,int),
           int m, int n)
{
	int i,j,k;

	i = (*targetcell)(g,lab,ptn,level,tc_level,digraph,hint,m,n);
	for (j = i + 1; ptn[j] > level; ++j) {}

	*tcellsize = j - i + 1;

	EMPTYSET(tcell,m);
	for (k = i; k <= j; ++k) ADDELEMENT(tcell,lab[k]);

	*cellpos = i;
}
Exemple #15
0
void
breakout(int *lab, int *ptn, int level, int tc, int tv,
         set *active, int m)
{
    register int i,prev,next;

    EMPTYSET(active,m);
    ADDELEMENT(active,tc);

    i = tc;
    prev = tv;

    do
    {
        next = lab[i];
        lab[i++] = prev;
        prev = next;
    }
    while (prev != tv);

    ptn[tc] = level;
}
Exemple #16
0
static void
multi(graph *g, int nfixed, long minedges, long maxedges, long maxmult,
      int maxdeg, boolean lswitch, int m, int n)
{
    static DEFAULTOPTIONS_GRAPH(options);
    statsblk stats;
    setword workspace[100];
    grouprec *group;
    int ne;
    int i,j,k,j0,j1,thisdeg,maxd,x0,x1;
    set *gi;
    int lab[MAXNV],ptn[MAXNV],orbits[MAXNV],deg[MAXNV];
    int delta[MAXNV],def[MAXNV];
    set active[(MAXNV+WORDSIZE-1)/WORDSIZE];
    boolean isreg;

#ifdef PATHCOUNTS
    ++count0;
#endif

    j0 = -1;  /* last vertex with degree 0 */
    j1 = n;   /* first vertex with degree > 0 */
 
    ne = 0;
    maxd = 0;
    for (i = 0, gi = g; i < n; ++i, gi += m)
    {
        thisdeg = 0;
        for (j = 0; j < m; ++j) thisdeg += POPCOUNT(gi[j]);
        deg[i] = thisdeg;
        if (thisdeg > maxd) maxd = thisdeg;
        if (thisdeg == 0) lab[++j0] = i;
        else              lab[--j1] = i;
        ne += thisdeg;
    }
    ne /= 2;

    if (maxdeg >= 0 && maxd > maxdeg) return;

#ifdef PATHCOUNTS
    ++count1;
#endif

    if (Aswitch || Bswitch)
        for (i = 0; i < n; ++i)
        for (j = 0; j < n; ++j)
            edgeno[i][j] = -1;

    if (ne == 0 && minedges <= 0
                && (!lswitch || (lswitch && (maxdeg&1) == 0)))
    {
        trythisone(NULL,lswitch,deg,maxdeg,0,n);
        return;
    }

#ifdef PATHCOUNTS
    ++count2;
#endif

    k = 0;
    for (i = 0, gi = g; i < n; ++i, gi += m)
    {
        for (j = i; (j = nextelement(gi,m,j)) >= 0; )
        {
            v0[k] = i;
            v1[k] = j;
            edgeno[i][j] = edgeno[j][i] = k;
            lastlev[i] = lastlev[j] = k;
            ++k;
        }
    }

    isreg = !lswitch && (maxdeg >= 0 && 2*minedges == n*(long)maxdeg);
        /* Case of regular multigraphs */

    if (isreg)  /* regular case */
    /* Condition: def(v) <= total def of neighbours */
    {
        for (i = 0; i < n; ++i)
        {
            def[i] = maxdeg - deg[i];
            delta[i] = -def[i];
        }

        for (i = 0; i < k; ++i)
        {
            x0 = v0[i]; x1 = v1[i];
            delta[x0] += def[x1];
            delta[x1] += def[x0];
        }

        for (i = 0; i < n; ++i) if (delta[i] < 0) return;
    }

    if ((isreg || lswitch) && (maxdeg & n & 1) == 1) return;
    if (isreg && j0 >= 0 && maxdeg > 0) return;
    if (lswitch && j0 >= 0 && (maxdeg&1) == 1) return;

#ifdef PATHCOUNTS
    ++count3;
#endif

    if (maxedges == NOLIMIT)
    {
	if (maxmult == NOLIMIT) maxedges = maxdeg*n/2;
	else                    maxedges = ne*maxmult;
    }
    if (maxmult == NOLIMIT) maxmult = maxedges - ne + 1;
    if (maxdeg >= 0 && maxmult > maxdeg) maxmult = maxdeg;
    if (maxedges < ne || ne*maxmult < minedges) return;

#ifdef PATHCOUNTS
    ++count4;
#endif

    if (n > MAXNV || ne > MAXNE)
    {
        fprintf(stderr,">E multig: MAXNV or MAXNE exceeded\n");
        exit(1);
    }

    nauty_check(WORDSIZE,m,n,NAUTYVERSIONID);

    for (i = 0; i < n; ++i) ptn[i] = 1;
    ptn[n-1] = 0;
    EMPTYSET(active,m);
    if (j0 != n-1) ADDELEMENT(active,j0+1);

    for (i = 0; i <= j0; ++i) ptn[i] = 0;

    for (i = j0+1; i < n; ++i)
    if (lab[i] < nfixed) break;

    if (i != j0+1 && i != n)
    {
        ptn[i-1] = 0;
        ADDELEMENT(active,i);
    }

    options.defaultptn = FALSE;
    options.userautomproc = groupautomproc;
    options.userlevelproc = grouplevelproc;

    nauty(g,lab,ptn,active,orbits,&options,&stats,workspace,100,m,n,NULL);

    if (stats.grpsize2 == 0)
        groupsize = stats.grpsize1 + 0.1;
    else
        groupsize = 0;

    group = groupptr(FALSE);
    makecosetreps(group);

    lastrejok = FALSE;

    if (isreg)
        scan_reg(0,ne,minedges,maxedges,0,maxmult,group,n,delta,def,maxdeg);
    else if (lswitch)
        scan_lp(0,ne,minedges,maxedges,0,maxmult,group,n,deg,maxdeg);
    else if (maxdeg >= 0)
        scan_md(0,ne,minedges,maxedges,0,maxmult,group,n,deg,maxdeg);
    else
        scan(0,ne,minedges,maxedges,0,maxmult,group,n);
}
Exemple #17
0
void
doref(graph *g, int *lab, int *ptn, int level, int *numcells,
      int *qinvar, permutation *invar, set *active, int *code,
      void (*refproc)(graph*,int*,int*,int,int*,permutation*,set*,int*,int,int),
      void (*invarproc)(graph*,int*,int*,int,int,int,permutation*,
                        int,boolean,int,int),
      int mininvarlev, int maxinvarlev, int invararg,
      boolean digraph, int m, int n)
{
    register int j,h;
    register permutation pw;
    int iw;
    int i,cell1,cell2,nc,tvpos,minlev,maxlev;
    long longcode;
    boolean same;

#if !MAXN
    DYNALLOC1(permutation,workperm,workperm_sz,n,"doref");
#endif

    if ((tvpos = nextelement(active,M,-1)) < 0) tvpos = 0;

    (*refproc)(g,lab,ptn,level,numcells,invar,active,code,M,n);

    minlev = (mininvarlev < 0 ? -mininvarlev : mininvarlev);
    maxlev = (maxinvarlev < 0 ? -maxinvarlev : maxinvarlev);
    if (invarproc != NULL && *numcells < n
            && level >= minlev && level <= maxlev)
    {
        (*invarproc)(g,lab,ptn,level,*numcells,tvpos,invar,invararg,
                     digraph,M,n);
        EMPTYSET(active,m);
        for (i = n; --i >= 0;) workperm[i] = invar[lab[i]];
        nc = *numcells;
        for (cell1 = 0; cell1 < n; cell1 = cell2 + 1)
        {
            pw = workperm[cell1];
            same = TRUE;
            for (cell2 = cell1; ptn[cell2] > level; ++cell2)
                if (workperm[cell2+1] != pw) same = FALSE;

            if (same) continue;

            j = (cell2 - cell1 + 1) / 3;
            h = 1;
            do
                h = 3 * h + 1;
            while (h < j);

            do                      /* shell sort */
            {
                for (i = cell1 + h; i <= cell2; ++i)
                {
                    iw = lab[i];
                    pw = workperm[i];
                    for (j = i; workperm[j-h] > pw; )
                    {
                        workperm[j] = workperm[j-h];
                        lab[j] = lab[j-h];
                        if ((j -= h) < cell1 + h) break;
                    }
                    workperm[j] = pw;
                    lab[j] = iw;
                }
                h /= 3;
            }
            while (h > 0);

            for (i = cell1 + 1; i <= cell2; ++i)
                if (workperm[i] != workperm[i-1])
                {
                    ptn[i-1] = level;
                    ++*numcells;
                    ADDELEMENT(active,i);
                }
        }

        if (*numcells > nc)
        {
            *qinvar = 2;
            longcode = *code;
            (*refproc)(g,lab,ptn,level,numcells,invar,active,code,M,n);
            longcode = MASH(longcode,*code);
            *code = CLEANUP(longcode);
        }
        else
            *qinvar = 1;
    }
    else
        *qinvar = 0;
}
Exemple #18
0
/* Cette fonction génère les structures qui vont bien pour les appels à Nauty */
void Carquois::genGraph()
{
    int i,j,m,nbSommetsNauty;
    int lab1[MAXN],ptn[MAXN],orbits[MAXN];
    static DEFAULTOPTIONS_GRAPH(options);
    statsblk stats;
    setword workspace[5*MAXM];
    
    if(!this->graphAJour)
    {
        
        nbSommetsNauty = 2 * this->getN();
        m=(nbSommetsNauty + WORDSIZE - 1)/WORDSIZE;

        /* Si on trouve une valeur strictement positive dans la matrice d'incidence, alors on ajoute une arrête dans notre graphe */
        for(i=0;i<this->getN();i++)
        {
            gv=GRAPHROW(nautyG,i+this->getN(),m);
            EMPTYSET(gv,m);
            
            gv=GRAPHROW(nautyG,i,m);
            EMPTYSET(gv,m);
            /* On ajoute les fausses arrêtes entre le layer 0 et le layer 1 */
            ADDELEMENT(gv,i+this->getN());
            for(j=0;j<this->getN();j++)
            {
                /* multiplicité de 1 */
                if(this->getM(i,j)==1)
                {
                    gv=GRAPHROW(nautyG,i,m);
                    ADDELEMENT(gv,j);
                }
                else
                {
                    if(this->getM(i,j)==2)
                    {
                        gv=GRAPHROW(nautyG,i+this->getN(),m);
                        ADDELEMENT(gv,j+this->getN());
                    }
                }
            }
        }
        options.getcanon = TRUE;
        options.digraph = TRUE;
        options.defaultptn = FALSE;
        nauty_check(WORDSIZE,m,nbSommetsNauty,NAUTYVERSIONID);
        
        for(i=0;i<2*n;i++)
        {
            lab1[i]=i;
            ptn[i]=1;
        }
        ptn[n-1]=0;
        ptn[2*n-1]=0;
        
        
        nauty(nautyG,lab1,ptn,NULL,orbits,&options,&stats,
                                  workspace,5*MAXM,m,nbSommetsNauty,nautyGC);
        this->graphAJour=1;    
    }
}