/* copies of some of the options: */ static TLS_ATTR
boolean getcanon,digraph,writeautoms,domarkers,cartesian,doschreier; static TLS_ATTR int linelength,tc_level,mininvarlevel,maxinvarlevel,invararg; static TLS_ATTR void (*usernodeproc)(graph*,int*,int*,int,int,int,int,int,int); static TLS_ATTR void (*userautomproc)(int,int*,int*,int,int,int); static TLS_ATTR void (*userlevelproc)
(int*,int*,int,int*,statsblk*,int,int,int,int,int,int); static TLS_ATTR int (*usercanonproc)
(graph*,int*,graph*,unsignedlong,int,int,int); static TLS_ATTR void (*invarproc)
(graph*,int*,int*,int,int,int,int*,int,boolean,int,int); static TLS_ATTR FILE *outfile; static TLS_ATTR dispatchvec dispatch;
/* local versions of some of the arguments: */ static TLS_ATTR int m,n; static TLS_ATTR graph *g,*canong; static TLS_ATTR int *orbits; static TLS_ATTR statsblk *stats; /* temporary versions of some stats: */ static TLS_ATTR unsignedlong invapplics,invsuccesses; static TLS_ATTR int invarsuclevel;
/* working variables: <the "bsf leaf" is the leaf which is best guess so
far at the canonical leaf> */ static TLS_ATTR int gca_first, /* level of greatest common ancestor of
current node and first leaf */
gca_canon, /* ditto for current node and bsf leaf */
noncheaplevel, /* level of greatest ancestor for which cheapautom==FALSE */
allsamelevel, /* level of least ancestor of first leaf for whichalldescendantleavesareknowntobe
equivalent */
eqlev_first, /* level to which codes for this node match those
for first leaf */
eqlev_canon, /* level to which codes for this node match those
for the bsf leaf. */
comp_canon, /* -1,0,1 according as code at eqlev_canon+1 is <,==,>thatforbsfleaf.Alsousedfor
similar purpose during leaf processing */
samerows, /* number of rows of canong which are correct for
the bsf leaf BDM:correct description? */
canonlevel, /* level of bsf leaf */
stabvertex, /* point fixed in ancestor of first leaf at level
gca_canon */
cosetindex; /* the point being fixed at level gca_first */
static TLS_ATTR boolean needshortprune; /* used to flag calls to shortprune */
/* In the dynamically allocated case (MAXN=0), each level of recursion needsoneset(tcell)torepresentthetargetcell.Thisis implementedbyusingalinkedlistoftcnodeanchoredattheroot ofthesearchtree.Eachnodepointstoitschild(ifany)andto thedynamicallyallocatedtcell.Apartfromthefirstnodeof thelist,eachnodealwayshasatcellgoodformuptoalloc_m. tcnodesandtcellsarekeptbetweencallstonauty,exceptthat
they are freed and reallocated if m gets bigger than alloc_m. */
#else static TLS_ATTR set defltwork[2*MAXM]; /* workspace in case none provided */ static TLS_ATTR int workperm[MAXN]; /* various scratch uses */ static TLS_ATTR set fixedpts[MAXM]; /* points which were explicitly
fixed to get current node */ static TLS_ATTR int firstlab[MAXN], /* label from first leaf */
canonlab[MAXN]; /* label from bsf leaf */ static TLS_ATTR short firstcode[MAXN+2], /* codes for first leaf */
canoncode[MAXN+2]; /* codes for bsf leaf */ static TLS_ATTR int firsttc[MAXN+2]; /* index of target cell for left path */ static TLS_ATTR set active[MAXM]; /* used to contain index to cells now
active for refinement purposes */ #endif
static TLS_ATTR set *workspace,*worktop; /* first and just-after-last
addresses of work area to hold automorphism data */ static TLS_ATTR set *fmptr; /* pointer into workspace */
static TLS_ATTR schreier *gp; /* These two for Schreier computations */ static TLS_ATTR permnode *gens;
void
nauty(graph *g_arg, int *lab, int *ptn, set *active_arg, int *orbits_arg, optionblk *options, statsblk *stats_arg,
set *ws_arg, int worksize, int m_arg, int n_arg, graph *canong_arg)
{ int i; int numcells; int retval; int initstatus; #if !MAXN
tcnode *tcp,*tcq; #endif
/* determine dispatch vector */
if (options->dispatch == NULL)
{
fprintf(ERRFILE,">E nauty: null dispatch vector\n");
fprintf(ERRFILE,"Maybe you need to recompile\n"); exit(1);
} else
dispatch = *(options->dispatch);
if (getcanon) if (canong_arg == NULL)
{
stats_arg->errstatus = CANONGNIL;
fprintf(ERRFILE, "nauty: canong=NULL but options.getcanon=TRUE\n\n"); return;
}
/* initialize everything: */
if (options->defaultptn)
{ for (i = 0; i < n; ++i) /* give all verts same colour */
{
lab[i] = i;
ptn[i] = NAUTY_INFINITY;
}
ptn[n-1] = 0;
EMPTYSET(active,m);
ADDELEMENT(active,0);
numcells = 1;
} else
{
ptn[n-1] = 0;
numcells = 0; for (i = 0; i < n; ++i) if (ptn[i] != 0) ptn[i] = NAUTY_INFINITY; else ++numcells; if (active_arg == NULL)
{
EMPTYSET(active,m); for (i = 0; i < n; ++i)
{
ADDELEMENT(active,i); while (ptn[i]) ++i;
}
} else for (i = 0; i < M; ++i) active[i] = active_arg[i];
}
g = canong = NULL;
initstatus = 0;
OPTCALL(dispatch.init)(g_arg,&g,canong_arg,&canong,
lab,ptn,active,options,&initstatus,m,n); if (initstatus)
{
stats->errstatus = initstatus; return;
}
if (g == NULL) g = g_arg; if (canong == NULL) canong = canong_arg;
if (doschreier) newgroup(&gp,&gens,n);
for (i = 0; i < n; ++i) orbits[i] = i;
stats->grpsize1 = 1.0;
stats->grpsize2 = 0;
stats->numgenerators = 0;
stats->numnodes = 0;
stats->numbadleaves = 0;
stats->tctotal = 0;
stats->canupdates = 0;
stats->numorbits = n;
EMPTYSET(fixedpts,m);
noncheaplevel = 1;
eqlev_canon = -1; /* needed even if !getcanon */
staticint #if !MAXN
firstpathnode0(int *lab, int *ptn, int level, int numcells,
tcnode *tcnode_parent) #else
firstpathnode(int *lab, int *ptn, int level, int numcells) #endif
{ int tv; int tv1,index,rtnlevel,tcellsize,tc,childcount,qinvar,refcode; #if !MAXN
set *tcell;
tcnode *tcnode_this;
/* refine partition : */
doref(g,lab,ptn,level,&numcells,&qinvar,workperm,
active,&refcode,dispatch.refine,invarproc,
mininvarlevel,maxinvarlevel,invararg,digraph,M,n);
firstcode[level] = (short)refcode; if (qinvar > 0)
{
++invapplics; if (qinvar == 2)
{
++invsuccesses; if (mininvarlevel < 0) mininvarlevel = level; if (maxinvarlevel < 0) maxinvarlevel = level; if (level < invarsuclevel) invarsuclevel = level;
}
}
tc = -1; if (numcells != n)
{ /* locate new target cell, setting tc to its position in lab, tcell
to its contents, and tcellsize to its size: */
maketargetcell(g,lab,ptn,level,tcell,&tcellsize,
&tc,tc_level,digraph,-1,dispatch.targetcell,M,n);
stats->tctotal += tcellsize;
}
firsttc[level] = tc;
staticint #if !MAXN
othernode0(int *lab, int *ptn, int level, int numcells,
tcnode *tcnode_parent) #else
othernode(int *lab, int *ptn, int level, int numcells) #endif
{ int tv; int tv1,refcode,rtnlevel,tcellsize,tc,qinvar; short code; #if !MAXN
set *tcell;
tcnode *tcnode_this;
/* call processnode to classify the type of this node: */
rtnlevel = processnode(lab,ptn,level,numcells); if (rtnlevel < level) /* keep returning if necessary */ return rtnlevel; if (needshortprune)
{
needshortprune = FALSE;
shortprune(tcell,fmptr-M,M);
}
if (!(*dispatch.cheapautom)(ptn,level,digraph,n))
noncheaplevel = level + 1;
/* use the elements of the target cell to produce the children: */ for (tv1 = tv = nextelement(tcell,M,-1); tv >= 0;
tv = nextelement(tcell,M,tv))
{
breakout(lab,ptn,level+1,tc,tv,active,M);
ADDELEMENT(fixedpts,tv); #if !MAXN
rtnlevel = othernode0(lab,ptn,level+1,numcells+1,tcnode_this); #else
rtnlevel = othernode(lab,ptn,level+1,numcells+1); #endif
DELELEMENT(fixedpts,tv);
if (rtnlevel < level) return rtnlevel; /* use stored automorphism data to prune target cell: */ if (needshortprune)
{
needshortprune = FALSE;
shortprune(tcell,fmptr-M,M);
} if (tv == tv1)
{
longprune(tcell,fixedpts,workspace,fmptr,M); if (doschreier) pruneset(fixedpts,gp,&gens,tcell,M,n);
}
case1: /* lab is equivalent to firstlab */ if (fmptr == worktop) fmptr -= 2 * M;
fmperm(workperm,fmptr,fmptr+M,M,n);
fmptr += 2 * M; if (writeautoms)
writeperm(outfile,workperm,cartesian,linelength,n);
stats->numorbits = orbjoin(orbits,workperm,n);
++stats->numgenerators;
OPTCALL(userautomproc)(stats->numgenerators,workperm,orbits,
stats->numorbits,stabvertex,n); if (doschreier) addgenerator(&gp,&gens,workperm,n); return gca_first;
case2: /* lab is equivalent to canonlab */ if (fmptr == worktop) fmptr -= 2 * M;
fmperm(workperm,fmptr,fmptr+M,M,n);
fmptr += 2 * M;
save = stats->numorbits;
stats->numorbits = orbjoin(orbits,workperm,n); if (stats->numorbits == save)
{ if (gca_canon != gca_first) needshortprune = TRUE; return gca_canon;
} if (writeautoms)
writeperm(outfile,workperm,cartesian,linelength,n);
++stats->numgenerators;
OPTCALL(userautomproc)(stats->numgenerators,workperm,orbits,
stats->numorbits,stabvertex,n); if (doschreier) addgenerator(&gp,&gens,workperm,n); if (orbits[cosetindex] < cosetindex) return gca_first; if (gca_canon != gca_first)
needshortprune = TRUE; return gca_canon;
case3: /* lab is better than canonlab */
++stats->canupdates; for (i = 0; i < n; ++i) canonlab[i] = lab[i];
canonlevel = eqlev_canon = gca_canon = level;
comp_canon = 0;
canoncode[level+1] = 077777;
samerows = sr; if (getcanon && usercanonproc != NULL)
{
(*dispatch.updatecan)(g,canong,canonlab,samerows,M,n);
samerows = n; if ((*usercanonproc)(g,canonlab,canong,stats->canupdates,
(int)canoncode[level],M,n)) return NAUTY_ABORTED;
} break;
case4: /* non-automorphism terminal node */
++stats->numbadleaves; break;
} /* end of switch statement */
/* only cases 3 and 4 get this far: */ if (level != noncheaplevel)
{
ispruneok = TRUE; if (fmptr == worktop) fmptr -= 2 * M;
fmptn(lab,ptn,noncheaplevel,fmptr,fmptr+M,M,n);
fmptr += 2 * M;
} else
ispruneok = FALSE;
save = (allsamelevel > eqlev_canon ? allsamelevel-1 : eqlev_canon);
newlevel = (noncheaplevel <= save ? noncheaplevel-1 : save);
void
nauty_check(int wordsize, int m, int n, int version)
{ if (wordsize != WORDSIZE)
{
fprintf(ERRFILE,"Error: WORDSIZE mismatch in nauty.c\n"); exit(1);
}
#if MAXN if (m > MAXM)
{
fprintf(ERRFILE,"Error: MAXM inadequate in nauty.c\n"); exit(1);
}
if (n > MAXN)
{
fprintf(ERRFILE,"Error: MAXN inadequate in nauty.c\n"); exit(1);
} #endif
if (version < NAUTYREQUIRED)
{
fprintf(ERRFILE,"Error: nauty.c version mismatch\n"); exit(1);
}
#if !HAVE_TLS if ((version & 1))
{
fprintf(ERRFILE, "*** Warning: program with TLS calling nauty without TLS ***\n");
} #endif
}
void
extra_level(int level, int *lab, int *ptn, int numcells, int tv1, int index, int tcellsize, int childcount, int n)
{
MULTIPLY(stats->grpsize1,stats->grpsize2,index); if (domarkers)
writemarker(level,tv1,index,tcellsize,stats->numorbits,numcells);
OPTCALL(userlevelproc)(lab,ptn,level,orbits,stats,tv1,index,tcellsize,
numcells,childcount,n);
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.57Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-15)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.