/***************************************************************************** * * * Quarticgen by Brendan D. McKay and S. Narjess Afzaly * * This program generates all quartic graphs up to a given order * * * * Parameters - <r> means read-only, <w> means write-only, <wr> means both: * * nmax <r> # vertices. This must be at least 5 and * * at most MAXN. * * * * numread <w> # irreducible graphs with n <= nmax vertices * * numwritten <w> # quartic graphs of order nmax * * diffnum <w> # all non-root (not irreducible ones) nodes in the * * search tree (both accepted and rejected ones) * * numaac <w> # accepted non-root nodes in the search tree * * *
****************************************************************************/ //Just the nodes above or on the SL will be generated. The children of nodes oh the SL won't be investigated or generated. #define MAXN 28 #define LEV1 2 //if (nmax<= threshold) then (SplitLevel = nmax-LEV1 ), otherwise (SplitLevel = LEV2). #define LEV2 15 #define threshold 16 #define WORDSIZE 64 #include"gtools.h" #include"quarticirred28.h"
#define USAGE "genquarticg [-ugs -h -c -l] n [res/mod] [file]"
#define HELPTEXT \ " generate all non-isomorphic quartic graphs of a given order \n\
\n\
n : the number of the vertices\n\
file : the name of the output file (default stdout)\n\
-u : donot output any graphs, just generate and count them\n\
-g : use graph6 format for output (default)\n\
-s : use sparse6 format for output\n\
-h write a header (only with -g or -s). \n\
-c : only write connected graphs\n\
-C : only write biconnected graphs\n\
res/mod : only generate subset res out of subsets 0..mod-1\n\
-l : canonically label output graphs.\n"
static FILE *outfile; /* file for output graphs */ staticchar *outfilename;
boolean nooutput; /* presence of -u */
boolean graph6; /* presence of -g */
boolean sparse6; /* presence of -s */
boolean header; /* presence of -h */ staticint connec; /* 1 for -c, 2 for -C, 0 for neither */
boolean connec1; /* presence of -c */
boolean connec2; /* presence of -C */
boolean canonise; /* presence of -l */ //????????
typedefstruct
{ int first; int sec;
setword fn;
setword sn;
setword end; int intersect; int cond;
} edgestruct;
typedefstruct
{ int first; int sec; int multp;
} pairstruct;
typedefstruct
{ int base; int first1; int sec1; int first2; int sec2;
} dovistruct;
typedefenum
{ accept,reject,undef } CHOISE;
int *pCNT, *pnumpair, *pdoviorbit, *pepairorbit; int (*pantidovi)[MAXN], (*pantipair)[MAXE], (*pantiedge)[MAXN]; int count[MAXN]; long numread;
nauty_counter numwritten;
pairstruct *pepair;
dovistruct *pdovi;
edgestruct *pedge;
setword active;
boolean goodret; staticint nmax, m, code, numcells, mod, res, splitlevel, splitcount; //TMP static splitlevel,splitcount,mod,res; ??????TMP? staticvoid extend(int, graph *, edgestruct *, pairstruct *, int, int * , int *, setword *, int *, boolean ); staticint init_refinex( int *, int *, int *, set *, int); staticvoid refinex( graph *, int *, int *, int , int *, int *, set *, boolean , int *, int , int ); staticvoid userautom1(int,int*,int*,int,int,int); staticvoid userautom2(int,int*,int*,int,int,int); staticvoid userautom3(int,int*,int*,int,int,int);
static boolean
isbiconnected(graph *g, int n) /* test if g is biconnected */
{ int sp,v,w;
setword sw;
setword visited; int numvis,num[MAXN],lp[MAXN],stack[MAXN];
for (;;)
{ if ((sw = g[v] & ~visited)) /* not "==" */
{
w = v;
v = FIRSTBITNZ(sw); /* visit next child */
stack[++sp] = v;
visited |= bit[v];
lp[v] = num[v] = numvis++;
sw = g[v] & visited & ~bit[w]; while (sw)
{
w = FIRSTBITNZ(sw);
sw &= ~bit[w]; if (num[w] < lp[v]) lp[v] = num[w];
}
} else
{
w = v; /* back up to parent */ if (sp <= 1) return numvis == n;
v = stack[--sp]; if (lp[w] >= num[v]) returnFALSE; if (lp[w] < lp[v]) lp[v] = lp[w];
}
}
}
/**************************************************************************** * extend recursively extends quartic graph until number of vertices * * of the graph reaches nmax after which it is written to outputfile *
****************************************************************************/
staticvoid
extend(int n, graph *g, edgestruct *edge, pairstruct *epair, int numpair, int *epairorbit, int *multar, setword *zar, int *col00w, boolean connectflag)
{ int vm1, vm2, vm3, vm4, vt1, vt2, vt3, vt4, c, b, mcol1,
tcol, got_one, i, j, numpair1, numdovi, maxdovi, i1, j1, i2, j2,
temp, mult, multm, rely, numedge, dcol, dcolp, e1, e2; int firsttime[MAXN], firsttimey[MAXN], multar1[MAXN],
col00[MAXN], col00w1[MAXN], doviorbit[3*MAXN],
epairorbit1[MAXP], l[MAXN], lab[MAXN], ptn[MAXN], orbits[MAXN]; int antipair[MAXE][MAXE], antiedge[MAXN][MAXN], antidovi[MAXN][MAXN];
setword x, y, z, bitj1, bitj2, biti2;
setword yi[MAXN], zar1[MAXN];
CHOISE colours;
pairstruct epair1[MAXP];
edgestruct edge1[MAXE];
graph gi[MAXN];
dovistruct dovi[3*MAXN];
dovistruct dovimax; register setword gi1, gi2, gj1, gj2;
boolean conf;
///////////////////////////////////////////////////////////////////////// if( n == splitlevel )
{ if (splitcount-- != 0) return;
splitcount = mod - 1;
} ///////////////////////////////////////////////////////////////////////// for( c = 1; c < numpair; c++)
{ if( epairorbit[c] == c )
{
int eqn[MAXN],neqn;
setword zval[MAXN],eqcol0; int dcol0,dcol1;
setword xn;
/***************************************************************************** * * * userautom1(count,perm,orbits,numorbits,stabvertex,n) is a simple * * version of the procedure named by options.userautomproc. * * *
*****************************************************************************/
staticvoid
userautom1(int count, int *perm, int *orbits, int numorbits, int stabvertex, int n)
{ int epairperm[MAXP]; int vn1, vn2, vn3, vn4, etmp, i, e1, e2;
epairperm[0] = 0; for (i = 1; i < *pnumpair; i++)
{
e1 = pepair[i].first;
e2 = pepair[i].sec;
/***************************************************************************** * * * userautom2(count,perm,orbits,numorbits,stabvertex,n) is a simple * * version of the procedure named by options.userautomproc. * * *
*****************************************************************************/ staticvoid
userautom2(int count, int *perm, int *orbits, int numorbits, int stabvertex, int n)
{ int doviperm[3*MAXN]; int vn1, vn2, vn3, vn4, vnb, i, etmp;
for (i = 0; i < *pCNT; i++)
{
vnb = perm[pdovi[i].base];
vn1 = perm[pdovi[i].first1];
vn2 = perm[pdovi[i].sec1];
vn3 = perm[pdovi[i].first2];
vn4 = perm[pdovi[i].sec2];
/***************************************************************************** * * * userautom3(count,perm,orbits,numorbits,stabvertex,n) is a simple * * version of the procedure named by options.userautomproc. * * *
*****************************************************************************/ staticvoid
userautom3( int count, int *perm, int *orbits, int numorbits, int stabvertex, int n)
{
int doviperm[3*MAXN], epairperm[MAXP]; int vn1, vn2, vn3, vn4, vnb, i, etmp, e1, e2;
for (i = 0; i < *pCNT; i++)
{
vnb = perm[pdovi[i].base];
vn1 = perm[pdovi[i].first1];
vn2 = perm[pdovi[i].sec1];
vn3 = perm[pdovi[i].first2];
vn4 = perm[pdovi[i].sec2];
/***************************************************************************** * * * init_refinex(clr, lb, p, active, n) initializes some parameters * * of the procedure refinex * * *
*****************************************************************************/
staticint
init_refinex( int *clr, int *lb, int *p, set *active, int n)
{ registerint i, j, ci, ncell;
ncell = 1;
*active = bit[0]; for (i = 0; i < n; i++)
{
ci = clr[i]; for (j = i-1; (j >= 0) && (clr[lb[j]] > ci) ; j--)
lb[j+1] = lb[j];
lb[j+1] = i;
}
lb[n] = n; for (i = 0; i < n; i++)
{ if( clr[lb[i]] != clr[lb[i+1]] )
{
p[i] = 0;
ncell++;
*active |= bit[i+1];
} else
p[i] = 1;
}
p[n] = 0; return ncell;
}
/***************************************************************************** * * * refinex(g,lab,ptn,level,numcells,count,active,goodret,code,m,n) is a * * custom version of refine() which can exit quickly if required. * * * * Only use at level==0. * * goodret : whether to do an early return for code 1 * * code := -1 for n-1 not max, 0 for maybe, 1 for definite * * *
*****************************************************************************/ staticvoid
refinex(graph *g, int *lab, int *ptn, int level, int *numcells, int *count,
set *active, boolean goodret, int *code, int m, int n)
{ int i, c1, c2, labc1, split1, split2, cell1, cell2, cnt, bmin, bmax; int workperm[MAXN], bucket[MAXN+2];
setword x, lact, workset;
set *gptr;
if (n == 1)
{
*code = 1; return;
}
*code = 0;
lact = *active;
split1 = -1; while (*numcells < n && lact)
{
TAKEBIT(split1,lact);
for (split2 = split1; ptn[split2] > 0; ++split2) {} if (split1 == split2) /* trivial splitting cell */
{
gptr = GRAPHROW(g,lab[split1],1); for (cell1 = 0; cell1 < n; cell1 = cell2 + 1)
{ for (cell2 = cell1; ptn[cell2] > 0; ++cell2) {} if (cell1 == cell2) continue;
if (!quiet)
{
msg[0] = '\0'; if (strlen(argv[0]) > 75) fprintf(stderr,">A %s",argv[0]); else CATMSG1(">A %s",argv[0]);
CATMSG1(" n = %d", nmax); // if (connec) CATMSG0(connec2 ? "C" : connec1 ? "c" : "",); if (connec2) CATMSG0(" C"); elseif (connec1) CATMSG0(" c"); if (mod > 1) CATMSG2(" class= %d/%d", res, mod);
CATMSG0("\n");
fputs(msg,stderr);
fflush(stderr);
}
if (header)
{ if (SPARSE6)
writeline(outfile,SPARSE6_HEADER); // No enter after the header is ok? else
writeline(outfile,GRAPH6_HEADER);
fflush(outfile);
}
// if (mod > 1 && nmax > 10) if( mod > 1 )
{ if( nmax <= threshold )
splitlevel = nmax - LEV1; else
splitlevel = LEV2;
splitcount = res;
} else
{
splitlevel = -1;
mod = 1;
res = 0; // narjess for the sake of n>splitlevel (below)
}
timebefore = CPUTIME;
m = 1;
cntr = numread = numwritten = 0; for(cntr = 0; cntr < NUMIRRED; cntr++)
{
n = graphsize(irred[cntr]); ////////////////////////////////////////////////////////////////// if( n == splitlevel )
{ if (splitcount-- != 0) continue; if( n == nmax )
splitcount = mod-1; else
splitcount = 0;
} if( n > splitlevel )
{ if ( gotmr && res ) continue;
} /////////////////////////////////////////////////////////////////////////
if( n < nmax )
{
numread++;
stringtograph(irred[cntr],g,m);
epairorbit[0] = 0;
numpair = 1;
numedge = 0; for (i = 0; i < n; i++)
{
multar[i] = 10;
x = g[i] & BITMASK(i); while (x)
{
TAKEBIT(j,x);
edge[numedge].first = i;
edge[numedge].sec = j;
antiedge[i][j] = numedge;
numedge++;
if (!quiet)
{ if (nooutput)
fprintf(stderr,">Z " COUNTER_FMT " graphs generated in %3.2f seconds\n",
numwritten,timeafter-timebefore); else
fprintf(stderr,">Z " COUNTER_FMT " graphs written to %s in %3.2f seconds\n",
numwritten,outfilename,timeafter-timebefore);
}
exit(0);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.32 Sekunden
(vorverarbeitet)
¤
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.