/* genspecialg.c version 1.3; B D McKay, Mar 19, 2018 */
#define USAGE "genspecialg [-s|-g|-z|-d|-v] [-q]\n\
[-p#| -c#| -e#| -k#| -b#, #[ ,#] |-Q#| -f#| -J#, #\ n\
|-P#, #| C#, #. ..|G#, #. ..|T#, #. ..]* [outfile]"
#define HELPTEXT \
" Generate special graphs.\n\
# : size parameter called n in the descriptions\n\
\n\
-s : Write in sparse6 format (default )\n\
-g : Write in graph6 format\n\
-z : Make digraph versions and write in digraph6 format\n\
-d : Write in dreadnaut format (can be used with -z)\n\
-v : For each graph, report the size to stderr\n\
-q : Suppress summary\n\
\n\
If defined , the digraph version is shown in parentheses:\n\
-p# : path (directed path) on n vertices.\n\
-c# : cycle (directed cycle) on n vertices.\n\
-e# : empty graph (digraph with loops only) on n vertices.\n\
-k# : complete graph (with loops) on n vertices\n\
-b#, #[ ,#] : complete bipartite graph (directed l->r) on n vertices\n\
minus a matching of given size if present\n\
-f# : flower snark on 4 *# vertices\n\
-P#, # : generalized Petersen graph; usual one is -P5,2 \n\
-Q# : hypercube on 2 ^n vertices and degree n.\n\
-J#, # : Johnson graph J(n,k), args are n and k.\n\
-C#, #. .. : circulant (di)graph.\n\
-T#, #. .. : theta (di)graph Theta(#, #, ...), give path lengths.\n\
-G#, #. .. : (directed) grid, use negative values for open directions\n\
\n\
Any number of graphs can be generated at once.\n"
/* Ideas: multipartite, knesser, full trees, antiregular, individual,
de Bruijn digraphs */
#include "gtools.h"
#define MAXARGS 10000 /* Maximum argument list for multi-argument parameters */
#define SWAP(x,y) {int w = x; x = y; y = w;}
static long args[MAXARGS];
static short vmark_val = 32000 ;
DYNALLSTAT(short ,vmark,vmark_sz);
#define MARK(i) vmark[i] = vmark_val
#define UNMARK(i) vmark[i] = 0
#define ISMARKED(i) (vmark[i] == vmark_val)
#define ISNOTMARKED(i) (vmark[i] != vmark_val)
#define RESETMARKS {if (vmark_val++ >= 32000 ) \
{size_t ij; for (ij=0 ;ij<vmark_sz;++ij) vmark[ij]=0 ; vmark_val=1 ;}}
static void
preparemarks(size_t nn)
{
size_t oldsize;
short *oldpos;
oldsize = vmark_sz;
oldpos = vmark;
DYNALLOC1(short ,vmark,vmark_sz,nn,"preparemarks" );
if (vmark_sz != oldsize || vmark != oldpos) vmark_val = 32000 ;
}
/**************************************************************************/
static void
writedread(FILE *f, sparsegraph *sg, boolean digraph)
/* Write in dreadnaut format */
{
size_t *v;
int *d,*e,n,i,j,k;
SG_VDE(sg,v,d,e);
n = sg->nv;
if (digraph) fprintf(f,"n=%d $=0 dg\n" ,n);
else fprintf(f,"n=%d $=0 g\n" ,n);
for (i = 0 ; i < n; ++i)
{
for (j = 0 ; j < d[i]; ++j)
{
k = e[v[i]+j];
if (k >= i || digraph) fprintf(f," %d" ,k);
}
if (i == n-1 ) fprintf(f,".\n$$\n" );
else fprintf(f,";\n" );
}
}
/**************************************************************************/
static int binom[32 ][16 ]; /* Cached binomial coefficients */
static int
binomial(int n, int k)
/* Value of binomial(n,k), error if too big for int */
{
int i,nki,ans;
nauty_counter work;
if (k > n/2 ) k = n - k;
if (k < 0 ) return 0 ;
if (n < 32 && binom[n][k] > 0 ) return binom[n][k];
work = 1 ;
for (i = 1 ; i <= k; ++i)
{
nki = n-k+i;
work = (work/i) * nki + (work%i) * nki / i;
if ((int )work != work) { fprintf(stderr,"Overflow\n" ); exit (1 ); }
}
ans = (int )work;
if (n < 32 ) binom[n][k] = ans;
return ans;
}
/**************************************************************************/
static void
unrank(int r, int k, int *a)
/* r-th k-set in colex order (r=0,1,...) */
{
int i,p;
for (i = k; i > 0 ; --i)
{
p = i - 1 ;
do ++p; while (binomial(p,i) <= r);
r -= binomial(p-1 ,i);
a[i-1 ] = p-1 ;
}
}
static int
rank(int k, int *a)
/* Rank of a[0..k-1] in colex order */
{
int i,r;
r = 0 ;
for (i = 0 ; i < k; ++i)
r += binomial(a[i],i+1 );
return r;
}
/**************************************************************************/
static int
vnumber(long *dimen, int *index, int ndimen)
{
int i,v;
v = 0 ;
for (i = 0 ; i < ndimen; ++i)
v = v*dimen[i] + index[i];
return v;
}
/**************************************************************************/
static void
makepath(long n, boolean digraph, sparsegraph *sg)
{
int *d,*e,i;
size_t *v,k;
if (n < 1 || n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: bad argument for -p\n" );
if (digraph) SG_ALLOC(*sg,n,n-1 ,"genspecialg" );
else SG_ALLOC(*sg,n,2 UL*n-2 ,"genspecialg" );
SG_VDE(sg,v,d,e);
if (digraph || n == 1 )
{
sg->nv = n;
sg->nde = n-1 ;
for (i = 0 ; i < n-1 ; ++i)
{
d[i] = 1 ;
v[i] = i;
e[i] = i+1 ;
}
d[n-1 ] = 0 ;
v[n-1 ] = 0 ;
}
else
{
sg->nv = n;
sg->nde = 2 *n-2 ;
d[0 ] = 1 ;
v[0 ] = 0 ;
e[0 ] = 1 ;
for (i = 1 , k = 1 ; i < n-1 ; ++i, k += 2 )
{
d[i] = 2 ;
v[i] = k;
e[k] = i-1 ;
e[k+1 ] = i+1 ;
}
d[n-1 ] = 1 ;
v[n-1 ] = k;
e[k] = n-2 ;
}
}
/**************************************************************************/
static void
makecycle(long n, boolean digraph, sparsegraph *sg)
{
int *d,*e,i;
size_t *v;
if (!digraph && (n < 1 || n == 2 || n > NAUTY_INFINITY-2 ))
gt_abort(">E genspecialg: bad argument for -c\n" );
if (digraph && (n < 1 || n > NAUTY_INFINITY-2 ))
gt_abort(">E genspecialg: bad argument for -zc\n" );
if (digraph) SG_ALLOC(*sg,n,n,"genspecialg" );
else SG_ALLOC(*sg,n,2 UL*n,"genspecialg" );
SG_VDE(sg,v,d,e);
if (digraph || n == 1 )
{
sg->nv = n;
sg->nde = n;
for (i = 0 ; i < n-1 ; ++i)
{
d[i] = 1 ;
v[i] = i;
e[i] = i+1 ;
}
d[n-1 ] = 1 ;
v[n-1 ] = n-1 ;
e[n-1 ] = 0 ;
}
else
{
sg->nv = n;
sg->nde = 2 UL*n;
d[0 ] = 2 ;
v[0 ] = 0 ;
e[0 ] = 1 ;
e[1 ] = n-1 ;
for (i = 1 ; i < n-1 ; ++i)
{
d[i] = 2 ;
v[i] = 2 UL*i;
e[2 UL*i] = i-1 ;
e[2 UL*i+1 ] = i+1 ;
}
d[n-1 ] = 2 ;
v[n-1 ] = 2 UL*n-2 ;
e[2 UL*n-2 ] = 0 ;
e[2 UL*n-1 ] = n-2 ;
}
}
/**************************************************************************/
static void
makeflowersnark(long k, boolean digraph, sparsegraph *sg)
/* Flower snark on 4*k vertices, no digraph variant
*
* The flower snark Jn can be constructed with the following process :
* Build n copies of the star graph on 4 vertices . Denote the
* central vertex of each star Ai and the outer vertices Bi , Ci and
* Di . This results in a disconnected graph on 4 n vertices with 3 n
* edges ( Ai - Bi , Ai - Ci and Ai - Di for 1 ? i ? n ) . Construct the n - cycle
* ( B1 . . . Bn ) . This adds n edges . Finally construct the 2 n - cycle
* ( C1 . . . CnD1 . . . Dn ) . This adds 2 n edges . By construction , the
* Flower snark Jn is a cubic graph with 4 n vertices and 6 n edges .
*/
#define FSA(i) (4 *(i))
#define FSB(i) (4 *(i)+1 )
#define FSC(i) (4 *(i)+2 )
#define FSD(i) (4 *(i)+3 )
{
int n,*d,*e,i,j;
size_t *v,nde;
if (k < 3 || k > (NAUTY_INFINITY-2 )/4 )
gt_abort(">E genspecialg: bad argument for -f\n" );
n = 4 *k;
nde = 12 *(size_t)k;
SG_ALLOC(*sg,n,nde,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = n;
sg->nde = nde;
for (i = 0 ; i < n; ++i)
{
d[i] = 0 ;
v[i] = 3 *(size_t)i;
}
for (i = 0 ; i < k; ++i)
{
e[v[FSA(i)]+d[FSA(i)]++] = FSB(i);
e[v[FSB(i)]+d[FSB(i)]++] = FSA(i);
e[v[FSA(i)]+d[FSA(i)]++] = FSC(i);
e[v[FSC(i)]+d[FSC(i)]++] = FSA(i);
e[v[FSA(i)]+d[FSA(i)]++] = FSD(i);
e[v[FSD(i)]+d[FSD(i)]++] = FSA(i);
}
for (i = 0 ; i < k; ++i)
{
j = FSB((i+1 )%k);
e[v[FSB(i)]+d[FSB(i)]++] = j;
e[v[j]+d[j]++] = FSB(i);
}
for (i = 0 ; i < k-1 ; ++i)
{
e[v[FSC(i)]+d[FSC(i)]++] = FSC(i+1 );
e[v[FSC(i+1 )]+d[FSC(i+1 )]++] = FSC(i);
}
for (i = 0 ; i < k-1 ; ++i)
{
e[v[FSD(i)]+d[FSD(i)]++] = FSD(i+1 );
e[v[FSD(i+1 )]+d[FSD(i+1 )]++] = FSD(i);
}
e[v[FSD(0 )]+d[FSD(0 )]++] = FSC(k-1 );
e[v[FSC(k-1 )]+d[FSC(k-1 )]++] = FSD(0 );
e[v[FSC(0 )]+d[FSC(0 )]++] = FSD(k-1 );
e[v[FSD(k-1 )]+d[FSD(k-1 )]++] = FSC(0 );
}
/**************************************************************************/
static void
makeJohnson(long n, long k, boolean digraph, sparsegraph *sg)
{
size_t *v;
int *d,*e,*ep,nv,deg,i,j,s,t,u;
DYNALLSTAT(int ,a,a_sz);
DYNALLSTAT(int ,b,b_sz);
if (k > n/2 ) k = n - k;
if (k < 0 ) gt_abort(">E genspecialg: bad parameters for -J\n" );
nv = binomial(n,k);
if (nv > NAUTY_INFINITY-2 ) gt_abort(">E genspecialg: too big -J\n" );
deg = k*(n-k);
SG_ALLOC(*sg,nv,nv*(size_t)deg,"genspecialg" );
sg->nv = nv;
sg->nde = nv*(size_t)deg;
SG_VDE(sg,v,d,e);
DYNALLOC1(int ,a,a_sz,k,"genspecialg" );
DYNALLOC1(int ,b,b_sz,k,"genspecialg" );
preparemarks(n);
for (i = 0 ; i < nv; ++i)
{
v[i] = i*(size_t)deg;
d[i] = deg;
ep = e + v[i];
unrank(i,k,a);
//{int x;for(x=0;x<k;++x)printf(" %d",a[x]);printf("\n");}
RESETMARKS;
for (j = 0 ; j < k; ++j) MARK(a[j]);
for (j = 0 ; j < n; ++j)
if (ISNOTMARKED(j))
{
for (s = 0 ; s < k; ++s)
{
for (t = 0 ; t < k; ++t) b[t] = a[t];
u = s;
while (u > 0 && b[u-1 ] > j)
{
b[u] = b[u-1 ];
--u;
}
while (u < k-1 && b[u+1 ] < j)
{
b[u] = b[u+1 ];
++u;
}
b[u] = j;
//{int x;printf("-");for(x=0;x<k;++x)printf(" %d",b[x]);printf(" (%d)\n",rank(k,b));}
*(ep++) = rank(k,b);
}
}
}
}
/**************************************************************************/
static void
makecomplete(long n, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,j;
size_t *v,k;
if (n < 1 || n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: bad argument for -k\n" );
if (digraph) SG_ALLOC(*sg,n,n*(size_t)n,"genspecialg" );
else SG_ALLOC(*sg,n,n*(size_t)(n-1 ),"genspecialg" );
SG_VDE(sg,v,d,e);
if (digraph)
{
sg->nv = n;
sg->nde = n*(size_t)n;
for (i = 0 , k = 0 ; i < n; ++i, k += n)
{
d[i] = n;
v[i] = k;
for (j = 0 ; j < n; ++j) e[k+j] = j;
}
}
else
{
sg->nv = n;
sg->nde = n*(size_t)(n-1 );
for (i = 0 , k = 0 ; i < n; ++i)
{
d[i] = n-1 ;
v[i] = k;
for (j = 0 ; j < n; ++j)
if (j != i) e[k++] = j;
}
}
}
/**************************************************************************/
static void
makeempty(long n, boolean digraph, sparsegraph *sg)
{
int *d,*e,i;
size_t *v;
if (n < 1 || n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: bad argument for -e\n" );
if (digraph) SG_ALLOC(*sg,n,n,"genspecialg" );
else SG_ALLOC(*sg,n,0 ,"genspecialg" );
SG_VDE(sg,v,d,e);
if (digraph)
{
sg->nv = n;
sg->nde = n;
for (i = 0 ; i < n; ++i)
{
d[i] = 1 ;
v[i] = i;
e[i] = i;
}
}
else
{
sg->nv = n;
sg->nde = 0 ;
for (i = 0 ; i < n; ++i)
{
d[i] = 0 ;
v[i] = 0 ;
}
}
}
/**************************************************************************/
static void
makehypercube(long deg, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,j;
size_t *v,k,nv;
if (deg < 0 || deg > 30 )
gt_abort(">E genspecialg: bad argument for -q\n" );
if (digraph)
gt_abort(">E genspecialg: -zq is not implemented\n" );
nv = 1 UL << deg;
SG_ALLOC(*sg,nv,deg*nv,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = nv;
sg->nde = deg*nv;
for (i = 0 , k = 0 ; i < nv; ++i, k += deg)
{
d[i] = deg;
v[i] = k;
for (j = 0 ; j < deg; ++j) e[k+j] = i ^ (1 <<j);
}
}
/**************************************************************************/
static void
maketheta(long *len, int npaths, boolean digraph, sparsegraph *sg)
{
int i,j,k,n,ntemp,*d,*e;
size_t *v,ne,etemp;
boolean hasone;
hasone = FALSE ;
n = 2 ;
ne = 0 ;
for (i = 0 ; i < npaths; ++i)
{
if (len[i] < 1 )
gt_abort(">E genspecialg: -T paths must be at least length 1\n" );
if (len[i] == 1 )
{
if (hasone) gt_abort(
">E genspecialg: -T only one path of length 1 allowed\n" );
hasone = TRUE ;
}
ntemp = n;
n += len[i]-1 ;
if (n < ntemp)
gt_abort(">E genspecialg: -T too many vertices\n" );
etemp = ne;
ne += len[i];
if (ne < etemp) gt_abort(">E genspecialg: -T too many edges\n" );
}
if (n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: -T size is too big\n" );
if (!digraph)
{
etemp = ne;
ne *= 2 ;
if (ne < etemp) gt_abort(">E genspecialg: -T too many edges\n" );
}
SG_ALLOC(*sg,n,ne,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = n;
sg->nde = ne;
v[0 ] = 0 ;
v[1 ] = npaths;
if (digraph)
{
v[2 ] = v[1 ];
for (i = 3 ; i < n; ++i) v[i] = v[i-1 ] + 1 ;
}
else
{
v[2 ] = v[1 ] + npaths;
for (i = 3 ; i < n; ++i) v[i] = v[i-1 ] + 2 ;
}
for (i = 0 ; i < n; ++i) d[i] = 0 ;
if (hasone)
{
e[v[0 ]+(d[0 ]++)] = 1 ;
if (!digraph) e[v[1 ]+(d[1 ]++)] = 0 ;
}
k = 2 ;
for (i = 0 ; i < npaths; ++i)
{
if (len[i] == 1 ) continue ;
e[v[0 ]+(d[0 ]++)] = k;
if (!digraph) e[v[k]+(d[k]++)] = 0 ;
for (j = 0 ; j < len[i]-2 ; ++j)
{
e[v[k]+(d[k]++)] = k+1 ;
if (!digraph) e[v[k+1 ]+(d[k+1 ]++)] = k;
++k;
}
e[v[k]+(d[k]++)] = 1 ;
if (!digraph) e[v[1 ]+(d[1 ]++)] = k;
++k;
}
}
/**************************************************************************/
static void
makegrid(long *dim, int ndim, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,j,deg,n,oldn;
size_t *v,k;
boolean closed[30 ];
int index[30 ];
n = 1 ;
deg = 0 ;
for (i = 0 ; i < ndim; ++i)
{
if (dim[i] >= -1 && dim[i] <= 1 )
gt_abort(">E genspecialg: -G dimensions must be at least 2\n" );
if (dim[i] == 2 && !digraph)
gt_abort(">E genspecialg: -G dimen 2 is only ok for digraphs\n" );
closed[i] = (dim[i] > 0 );
if (dim[i] < 0 ) dim[i] = -dim[i];
oldn = n;
n *= dim[i];
if (n < 0 || n / dim[i] != oldn)
gt_abort(">E genspecialg: -G size is too big\n" );
if (digraph || dim[i] == 2 ) ++deg;
else deg += 2 ;
index[i] = 0 ;
}
if (n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: -G size is too big\n" );
SG_ALLOC(*sg,n,deg*(size_t)n,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = n;
sg->nde = deg*(size_t)n;
k = 0 ;
for (i = 0 ; i < n; ++i)
{
v[i] = k;
for (j = 0 ; j < ndim; ++j)
{
if (index[j] < dim[j]-1 )
{
++index[j];
e[k++] = vnumber(dim,index,ndim);
--index[j];
}
if (!digraph && index[j] > 0 )
{
--index[j];
e[k++] = vnumber(dim,index,ndim);
++index[j];
}
if (closed[j] && index[j] == dim[j]-1 )
{
index[j] = 0 ;
e[k++] = vnumber(dim,index,ndim);
index[j] = dim[j]-1 ;
}
if (closed[j] && !digraph && index[j] == 0 )
{
index[j] = dim[j]-1 ;
e[k++] = vnumber(dim,index,ndim);
index[j] = 0 ;
}
}
d[i] = k - v[i];
for (j = ndim; --j >= 0 ;)
{
if (index[j] != dim[j]-1 )
{
++index[j];
break ;
}
else
index[j] = 0 ;
}
}
}
/**************************************************************************/
static void
makecirculant(long n, long *conn, int nconn, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,j,deg;
size_t *v,k;
if (nconn > 0 && conn[0 ] <= 0 )
gt_abort(">E genspecialg: -C connections must be nonzero\n" );
for (i = 1 ; i < nconn; ++i)
if (conn[i] <= conn[i-1 ])
gt_abort(">E genspecialg: -C connections must be increasing\n" );
if (nconn == 0 )
deg = 0 ;
else
{
if (digraph)
{
if (conn[nconn-1 ] >= n) gt_abort(
">E genspecialg: -C connections must be 1..n-1\n" );
deg = nconn;
}
else
{
if (conn[nconn-1 ] > n/2 ) gt_abort(
">E genspecialg: -C connections must be 1..n/2\n" );
deg = 2 *nconn - (2 *conn[nconn-1 ]==n);
}
}
SG_ALLOC(*sg,n,deg*n,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = n;
sg->nde = deg*n;
for (i = 0 ; i < n; ++i)
{
d[i] = deg;
v[i] = deg*(size_t)i;
}
for (i = 0 ; i < n; ++i)
{
k = v[i];
for (j = 0 ; j < nconn; ++j)
{
e[k++] = (i + conn[j]) % n;
if (!digraph && 2 *conn[j] != n)
e[k++] = (i - conn[j] + n) % n;
}
}
}
/**************************************************************************/
static void
makegenpetersen(long n1, long n2, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,n;
size_t *v,k;
if (digraph) gt_abort(">E no digraph version of -P is implemented\n" );
n = 2 *n1;
if (n < 1 || n1 > NAUTY_INFINITY/2 -1 || n2 < 1 || 2 *n2 >= n1)
gt_abort(">E -Pm,k needs m>0,0<k<m/2; or m too large\n" );
SG_ALLOC(*sg,n,3 UL*n,"genspecialg" );
SG_VDE(sg,v,d,e);
sg->nv = n;
sg->nde = 3 UL*n;
for (i = 0 ; i < n; ++i)
{
d[i] = 3 ;
v[i] = 3 UL*i;
}
for (i = 0 ; i < n1; ++i)
{
k = v[i];
e[k] = (i + 1 ) % n1;
e[k+1 ] = (i + n1 - 1 ) % n1;
e[k+2 ] = i + n1;
}
for (i = 0 ; i < n1; ++i)
{
k = v[n1+i];
e[k] = n1 + (i + n2) % n1;
e[k+1 ] = n1 + (i - n2 + n1) % n1;
e[k+2 ] = i;
}
}
/**************************************************************************/
static void
makecompletebipartite(long n1, long n2,
long matching, boolean digraph, sparsegraph *sg)
{
int *d,*e,i,j,jmissing,n;
size_t *v,k;
n = n1 + n2;
if (matching > n1 || matching > n2)
gt_abort(">E genspecialg: matching too large\n" );
if (n1 < 1 || n2 < 1 || n > NAUTY_INFINITY-2 )
gt_abort(">E genspecialg: bad argument for -b\n" );
if (digraph) SG_ALLOC(*sg,n,n1*n2,"genspecialg" );
else SG_ALLOC(*sg,n,2 *n1*n2,"genspecialg" );
SG_VDE(sg,v,d,e);
if (digraph)
{
sg->nv = n;
sg->nde = n1*n2 - matching;
for (i = 0 , k = 0 ; i < n1; ++i)
{
v[i] = k;
jmissing = (i < matching ? n1+i : -1 );
for (j = n1; j < n; ++j) if (j != jmissing) e[k++] = j;
d[i] = k - v[i];
}
for (i = n1; i < n; ++i)
{
d[i] = 0 ;
v[i] = k;
}
}
else
{
sg->nv = n;
sg->nde = 2 *(n1*n2 - matching);
for (i = 0 , k = 0 ; i < n1; ++i)
{
v[i] = k;
jmissing = (i < matching ? n1+i : -1 );
for (j = n1; j < n; ++j) if (j != jmissing) e[k++] = j;
d[i] = k - v[i];
}
for (i = n1; i < n; ++i)
{
v[i] = k;
jmissing = (i < n1+matching ? i-n1 : -1 );
for (j = 0 ; j < n1; ++j) if (j != jmissing) e[k++] = j;
d[i] = k - v[i];
}
}
}
/**************************************************************************/
int
main(int argc, char *argv[])
{
int codetype;
int argnum,j;
char *arg,sw;
boolean badargs,quiet;
boolean Cswitch,Pswitch,gswitch,sswitch,zswitch,Jswitch,dswitch;
boolean pswitch,cswitch,eswitch,kswitch,bswitch,Qswitch,Gswitch;
boolean fswitch,Tswitch,verbose,havegraph,dreadnaut;
long size;
static FILE *outfile;
char *outfilename;
sparsegraph sg;
long Pargs[2 ],bargs[3 ],Jargs[2 ];
int nPargs,nbargs,nCargs,nGargs,nJargs,nTargs;
int numgraphs;
HELP; PUTVERSION;
numgraphs = 0 ;
gswitch = sswitch = zswitch = Pswitch = FALSE ;
pswitch = cswitch = eswitch = kswitch = FALSE ;
Gswitch = Cswitch = bswitch = Qswitch = verbose = FALSE ;
dswitch = Jswitch = fswitch = Tswitch = quiet = FALSE ;
outfilename = NULL;
argnum = 0 ;
badargs = FALSE ;
for (j = 1 ; !badargs && j < argc; ++j)
{
arg = argv[j];
if (arg[0 ] == '-' && arg[1 ] != '\0' )
{
++arg;
while (*arg != '\0' )
{
sw = *arg++;
SWBOOLEAN('g' ,gswitch)
else SWBOOLEAN('s' ,sswitch)
else SWBOOLEAN('z' ,zswitch)
else SWBOOLEAN('d' ,dswitch)
else SWBOOLEAN('q' ,quiet)
else SWBOOLEAN('v' ,verbose)
else SWLONG('p' ,pswitch,size,"genspecialg -p" )
else SWLONG('c' ,cswitch,size,"genspecialg -c" )
else SWLONG('e' ,eswitch,size,"genspecialg -e" )
else SWLONG('k' ,kswitch,size,"genspecialg -k" )
else SWLONG('f' ,fswitch,size,"genspecialg -f" )
else SWLONG('Q' ,Qswitch,size,"genspecialg -Q" )
else SWSEQUENCEMIN('b' ,"," ,bswitch,bargs,2 ,3 ,nbargs,"genspecialg -b" )
else SWSEQUENCEMIN('J' ,"," ,Jswitch,Jargs,2 ,2 ,nJargs,"genspecialg -J" )
else SWSEQUENCEMIN('P' ,"," ,Pswitch,Pargs,2 ,2 ,nPargs,"genspecialg -P" )
else SWSEQUENCEMIN('C' ,"," ,Cswitch,args,
1 ,MAXARGS,nCargs,"genspecialg -C" )
else SWSEQUENCEMIN('G' ,"," ,Gswitch,args,2 ,30 ,nGargs,"genspecialg -G" )
else SWSEQUENCEMIN('T' ,"," ,Tswitch,args,1 ,MAXARGS,
nTargs,"genspecialg -T" )
else badargs = TRUE ;
}
}
else
{
++argnum;
if (argnum == 1 ) outfilename = arg;
else badargs = TRUE ;
}
}
if ((gswitch!=0 ) + (sswitch!=0 ) + (zswitch!=0 ) > 1 )
gt_abort(">E genspecialg: -gsz are incompatible\n" );
if ((gswitch!=0 ) + (sswitch!=0 ) + (dswitch!=0 ) > 1 )
gt_abort(">E genspecialg: -gsd are incompatible\n" );
if (badargs)
{
fprintf(stderr,">E Usage: %s\n" ,USAGE);
GETHELP;
exit (1 );
}
if (gswitch) codetype = GRAPH6;
else if (zswitch) codetype = DIGRAPH6;
else codetype = SPARSE6;
dreadnaut = dswitch;
if (!outfilename || outfilename[0 ] == '-' )
{
outfilename = "stdout" ;
outfile = stdout;
}
else if ((outfile = fopen(outfilename,"w" )) == NULL)
{
fprintf(stderr,"Can't open output file %s\n" ,outfilename);
gt_abort(NULL);
}
SG_INIT(sg);
argnum = 0 ;
badargs = havegraph = FALSE ;
for (j = 1 ; !badargs && j < argc; ++j)
{
arg = argv[j];
if (arg[0 ] == '-' && arg[1 ] != '\0' )
{
++arg;
while (*arg != '\0' )
{
sw = *arg++;
SWBOOLEAN('g' ,gswitch)
else SWBOOLEAN('s' ,sswitch)
else SWBOOLEAN('z' ,zswitch)
else SWBOOLEAN('d' ,dswitch)
else SWBOOLEAN('q' ,quiet)
else SWBOOLEAN('v' ,verbose)
else if (sw == 'p' )
{
SWLONG('p' ,pswitch,size,"genspecialg -p" )
makepath(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'c' )
{
SWLONG('c' ,cswitch,size,"genspecialg -c" )
makecycle(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'e' )
{
SWLONG('e' ,eswitch,size,"genspecialg -e" )
makeempty(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'k' )
{
SWLONG('k' ,kswitch,size,"genspecialg -k" )
makecomplete(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'f' )
{
SWLONG('f' ,fswitch,size,"genspecialg -f" )
makeflowersnark(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'Q' )
{
SWLONG('Q' ,Qswitch,size,"genspecialg -Q" )
makehypercube(size,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'b' )
{
SWSEQUENCEMIN('b' ,"," ,bswitch,bargs,2 ,3 ,nbargs,"genspecialg -b" )
makecompletebipartite(bargs[0 ],bargs[1 ],
(nbargs==2 ?0 :bargs[2 ]),zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'J' )
{
SWSEQUENCEMIN('J' ,"," ,Jswitch,Jargs,2 ,2 ,nJargs,"genspecialg -J" )
makeJohnson(Jargs[0 ],Jargs[1 ],zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'P' )
{
SWSEQUENCEMIN('P' ,"," ,Pswitch,Pargs,2 ,2 ,nPargs,"genspecialg -P" )
makegenpetersen(Pargs[0 ],Pargs[1 ],zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'C' )
{
SWSEQUENCEMIN('C' ,"," ,Cswitch,args,
1 ,MAXARGS,nCargs,"genspecialg -C" )
makecirculant(args[0 ],args+1 ,nCargs-1 ,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'G' )
{
SWSEQUENCEMIN('G' ,"," ,Gswitch,args,2 ,30 ,nGargs,"genspecialg -G" )
makegrid(args,nGargs,zswitch,&sg);
havegraph = TRUE ;
}
else if (sw == 'T' )
{
SWSEQUENCEMIN('T' ,"," ,Tswitch,args,1 ,MAXARGS,
nTargs,"genspecialg -T" )
maketheta(args,nTargs,zswitch,&sg);
havegraph = TRUE ;
}
if (havegraph)
{
sortlists_sg(&sg);
if (dreadnaut) writedread(outfile,&sg,zswitch);
else if (codetype == GRAPH6) writeg6_sg(outfile,&sg);
else if (codetype == DIGRAPH6) writed6_sg(outfile,&sg);
else writes6_sg(outfile,&sg);
++numgraphs;
havegraph = FALSE ;
if (verbose)
fprintf(stderr,"Graph %d: %d vertices %lu edges\n" ,numgraphs,
sg.nv,(unsigned long )(zswitch ? sg.nde : sg.nde/2 ));
}
}
}
else
{
++argnum;
}
}
if (!quiet)
fprintf(stderr,">Z %d graphs written to %s\n" ,numgraphs,outfilename);
exit (0 );
}
Messung V0.5 in Prozent C=98 H=67 G=83
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet am 2026-06-26)
¤
*© Formatika GbR, Deutschland