示例#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);
        }
}
示例#2
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);
}
示例#3
0
文件: directg.c 项目: igraph/nautier
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;
}
示例#4
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;
}
示例#5
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
}
示例#6
0
文件: complg.c 项目: 3ki5tj/nauty
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;
	}
}
示例#7
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);
}
示例#8
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;
}
示例#9
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;
}
示例#11
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;
}
示例#12
0
文件: directg.c 项目: igraph/nautier
static int
trythisone(grouprec *group, int ne, int n)
{
    int i,k;
    boolean accept;
#ifdef PROCESS
    graph g[WORDSIZE];
#endif

    first = TRUE;

    ++gd_ngen;
    nix = ne;
    newgroupsize = 1;
    ntgroup = FALSE;

    if (!group || groupsize == 1)
        accept = TRUE;
    else if (lastrejok && !ismax(lastreject,n))
        accept = FALSE;
    else if (lastrejok && groupsize == 2)
        accept = TRUE;
    else
    {
        newgroupsize = 1;
        ntgroup = FALSE;
        if (allgroup2(group,testmax) == 0)
            accept = TRUE;
        else
            accept = FALSE;
    }

    if (accept)
    {

#ifdef GROUPTEST
        if (groupsize % newgroupsize != 0)
                        gt_abort("group size error\n");
        totallab += groupsize/newgroupsize;
#endif

        if (Vswitch && !ntisol && !ntgroup) return MAXNE+1;

        ++dg_nout;

#ifdef PROCESS
	EMPTYSET(g,n);
	for (i = -1; (i = nextelement(x,me,i)) >= 0; )
        {
            k = i >> 1;
            if (i & 1) g[v1[k]] |= bit[v0[k]];
            else       g[v0[k]] |= bit[v1[k]];
        }
	PROCESS(outfile,g,n);
#endif

        if (outfile)
        {
            fprintf(outfile,"%d %d",n,ne);
            if (Gswitch) fprintf(outfile," %lu",newgroupsize);
    
            for (i = -1; (i = nextelement(x,me,i)) >= 0; )
            {
                k = i >> 1;
                if (i & 1) fprintf(outfile," %d %d",v1[k],v0[k]);
                else       fprintf(outfile," %d %d",v0[k],v1[k]);
            }
            fprintf(outfile,"\n");
        }
        return MAXNE+1;
    }
    else
        return rejectlevel;
示例#13
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);
}
示例#14
0
文件: Nauty.cpp 项目: coin-or/Couenne
Nauty::Nauty(int vertices)
{

  n_ = vertices;
  m_ = (n_ + WORDSIZE - 1)/WORDSIZE;

  //printf ("size of long = %d (%d)\nwordsize = %d\nn,m = %d,%d\n", 
  //          SIZEOF_LONG, sizeof (long), WORDSIZE, n_, m_);

  nauty_check (WORDSIZE, m_, n_, NAUTYVERSIONID);

  /// Apparently sizes are skewed on 64bit machines

#define MULTIPLIER 2

  G_ = (graph *) malloc(MULTIPLIER * m_ * n_ * sizeof(int));
  lab_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));  
  ptn_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
  active_ = NULL;
  orbits_ = (int *) malloc(MULTIPLIER * n_ * sizeof(int));
  options_ = (optionblk *) malloc(MULTIPLIER * sizeof(optionblk));
  stats_ = (statsblk *) malloc(MULTIPLIER * sizeof(statsblk));
  worksize_ = 100*m_;
  workspace_ = (setword *) malloc(MULTIPLIER * worksize_*sizeof(setword));
  canonG_ = NULL;
  if (G_ == 0 || lab_ == 0 || ptn_ == 0 || 
      orbits_ == 0 || options_ == 0 || stats_ == 0 ||
      workspace_ == 0) assert(0);

  // Zero allocated memory
  memset(G_, 0, m_*n_*sizeof(int));
  memset(lab_, 0, n_*sizeof(int));
  memset(ptn_, 0, n_*sizeof(int));
  memset(orbits_, 0, n_*sizeof(int));
  memset(workspace_, 0, worksize_*sizeof(setword));

  // Set the options you want
  options_->getcanon = FALSE;
  options_->digraph = FALSE;
  options_->writeautoms = FALSE;
  options_->writemarkers = FALSE;
  options_->defaultptn = TRUE;
  options_->cartesian = FALSE;
  options_->linelength = 78;
  options_->outfile = NULL;
  options_->userrefproc = NULL;
  options_->userautomproc = NULL;
  options_->userlevelproc = NULL;
  options_->usernodeproc = NULL;
  //  options_->usertcellproc = NULL;
  options_->invarproc = NULL;
  options_->tc_level = 100;
  options_->mininvarlevel = 0;
  options_->maxinvarlevel = 1;
  options_->invararg = 0;
  options_->dispatch = &dispatch_graph;
   // Make an empty graph
  for (int j = 0; j < n_; j++) {
    set *gv = GRAPHROW(G_, j, m_);
    EMPTYSET(gv, m_);
  }

  vstat_ = new int[n_];
   clearPartitions();
   afp_ = NULL;
 }
示例#15
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;
}
示例#16
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;    
    }
}