static boolean isstrong(graph *g, int n) /* test if tournament g is strongly-connected * This code is strictly for tournaments only. */ { setword seen,expanded,toexpand,allbits; int i; allbits = ALLMASK(n); seen = bit[0] | g[0]; expanded = bit[0]; while (seen != allbits && (toexpand = (seen & ~expanded))) /* not == */ { i = FIRSTBITNZ(toexpand); expanded |= bit[i]; seen |= g[i]; } if (seen != allbits) return FALSE; seen = (allbits ^ g[0]); expanded = bit[0]; while (seen != allbits && (toexpand = (seen & ~expanded))) /* not == */ { i = FIRSTBITNZ(toexpand); expanded |= bit[i]; seen |= (g[i] ^ allbits); } return seen == allbits; }
void contract1(graph *g, graph *h, int v, int w, int n) /* Contract distinct vertices v and w (not necessarily adjacent) with result in h. No loops are created. */ { int x,y; setword bitx,bity,mask1,mask2; int i; if (w < v) { x = w; y = v; } else { x = v; y = w; } bitx = bit[x]; bity = bit[y]; mask1 = ALLMASK(y); mask2 = BITMASK(y); for (i = 0; i < n; ++i) if (g[i] & bity) h[i] = (g[i] & mask1) | bitx | ((g[i] & mask2) << 1); else h[i] = (g[i] & mask1) | ((g[i] & mask2) << 1); h[x] |= h[y]; for (i = y+1; i < n; ++i) h[i-1] = h[i]; h[x] &= ~bitx; }
static boolean isconnected(graph *g, int n) /* test if g is connected */ { setword seen,expanded,toexpand,allbits; int i; allbits = ALLMASK(n); expanded = bit[n-1]; seen = expanded | g[n-1]; while (seen != allbits && (toexpand = (seen & ~expanded))) /* not == */ { i = FIRSTBITNZ(toexpand); expanded |= bit[i]; seen |= g[i]; } return seen == allbits; }
void delete1(graph *g, graph *h, int v, int n) /* Delete vertex v from g, result in h */ { setword mask1,mask2,gi; int i; mask1 = ALLMASK(v); mask2 = BITMASK(v); for (i = 0; i < v; ++i) { gi = g[i]; h[i] = (gi & mask1) | ((gi & mask2) << 1); } for (i = v; i < n-1; ++i) { gi = g[i+1]; h[i] = (gi & mask1) | ((gi & mask2) << 1); } }
long cyclecount1(graph *g, int n) /* The total number of cycles in g (assumed no loops), m=1 only */ { setword body,nbhd; long total; int i,j; body = ALLMASK(n); total = 0; for (i = 0; i < n-2; ++i) { body ^= bit[i]; nbhd = g[i] & body; while (nbhd) { TAKEBIT(j,nbhd); total += pathcount1(g,j,body,nbhd); } } return total; }
int static main(int argc, char *argv[]) { int i,j,bad; setword w,ww; printf("NAUTYVERSION=%s NAUTYVERSIONID=%d\n", NAUTYVERSION,NAUTYVERSIONID); printf("MAXN=%d MAXM=%d WORDSIZE=%d NAUTY_INFINITY=%d\n", MAXN,MAXM,WORDSIZE,NAUTY_INFINITY); printf("sizes: short=%d int=%d long=%d double=%d\n", (int)sizeof(short),(int)sizeof(int),(int)sizeof(long), (int)sizeof(double)); printf("sizes: boolean=%d setword=%d\n", (int)sizeof(boolean),(int)sizeof(setword)); printf("CLZ=%d,%d,%d\n",HAVE_CLZ,HAVE_CLZL,HAVE_CLZLL); #if SIZEOF_LONGLONG > 0 printf("sizeof(long long)=%d\n",sizeof(long long)); #endif printf("defined:"); #ifdef __STDC__ printf(" __STDC__"); #endif #ifdef BIGNAUTY printf(" BIGNAUTY(obsolete!)"); #endif #ifdef SYS_UNIX printf(" SYS_UNIX"); #endif #ifdef SYS_CRAY printf(" SYS_CRAY"); #endif #ifdef SETWORD_SHORT printf(" SETWORD_SHORT"); #endif #ifdef SETWORD_INT printf(" SETWORD_INT"); #endif #ifdef SETWORD_LONG printf(" SETWORD_LONG"); #endif #ifdef SETWORD_LONGLONG printf(" SETWORD_LONGLONG"); #endif printf("\n"); bad = 0; if (8*sizeof(setword) != WORDSIZE) { printf("\n ***** NOTE: WORDSIZE mismatch *****\n\n"); ++bad; } for (i = 0; i < WORDSIZE; ++i) { w = ALLMASK(i); if (POPCOUNT(w) != i) { printf("\n ***** POPCOUNT(ALLMASK) error %d *****\n\n",i); ++bad; } } for (i = 0; i < WORDSIZE; ++i) { w = BITMASK(i); if (POPCOUNT(w) != WORDSIZE-i-1) { printf("\n ***** POPCOUNT(BITMASK) error %d *****\n\n",i); ++bad; } } for (i = 0; i < WORDSIZE; ++i) if (POPCOUNT(ALLMASK(i)) != i) { printf("\n ***** POPCOUNT(ALLMASK) error %d *****\n\n",i); ++bad; } for (i = 0; i < WORDSIZE; ++i) if (FIRSTBIT(BITT[i]) != i) { printf("\n ***** FIRSTBIT(BITT) error %d *****\n\n",i); ++bad; } if (FIRSTBIT((setword)0) != WORDSIZE) { printf("\n ***** FIRSTBIT(0) error *****\n\n"); ++bad; } for (i = 0; i < WORDSIZE; ++i) if (POPCOUNT(BITT[i]) != 1) { printf("\n ***** POPCOUNT(BITT) error %d *****\n\n",i); ++bad; } for (i = 0; i < WORDSIZE; ++i) { w = 0; for (j = 1; j <= WORDSIZE; ++j) { w |= BITT[(j*97+i)%WORDSIZE]; if (POPCOUNT(w) != j) { printf("\n ***** POPCOUNT(w) error %d %d *****\n\n",i,j); ++bad; } } } if (!bad) printf("\nNo errors found\n"); else printf("\nXXXXXXX %d errors found XXXXXXX\n",bad); exit(0); }
int conncontent(graph *g, int m, int n) /* number of connected spanning subgraphs with an even number of edges minus the number with an odd number of edges */ { graph h[WORDSIZE]; setword gj; int i,j,v1,v2,x,y; int minv,mindeg,deg,goodv; long ne; if (m > 1) ABORT("conncontent only implemented for m=1"); /* First handle tiny graphs */ if (n <= 3) { if (n == 1) return 1; if (n == 2) return (g[0] ? -1 : 0); if (!g[0] || !g[1] || !g[2]) return 0; /* disconnected */ if (g[0]^g[1]^g[2]) return 1; /* path */ return 2; /* triangle */ } /* Now compute ne = number of edges mindeg = minimum degree minv = a vertex of minimum degree goodv = a vertex with a clique neighbourhood (-1 if none) */ mindeg = n; ne = 0; goodv = -1; for (j = 0; j < n; ++j) { gj = g[j]; deg = POPCOUNT(gj); ne += deg; if (deg < mindeg) { mindeg = deg; minv = j; if (deg == 1) goodv = j; } if (deg >= 3 && deg <= 4 && goodv < 0) { while (gj) { TAKEBIT(i,gj); if (gj & ~g[i]) break; } if (!gj) goodv = j; } } ne /= 2; /* Cases of isolated vertex or tree */ if (mindeg == 0) return 0; #if 0 if (mindeg == 1 && ne == n-1) { if (isconnected1(g,n)) return ((n&1) ? 1 : -1); else return 0; } #endif /* Cases of clique and near-clique */ if (mindeg == n-1) { j = -1; for (i = 2; i < n; ++i) j *= -i; return j; } if (mindeg == n-2 && n < 16) { if (!knm_computed) { knm_computed = TRUE; knm[1][0] = 1; for (i = 2; i < 16; ++i) { knm[i][0] = -knm[i-1][0] * (i-1); for (j = 1; j+j <= i; ++j) knm[i][j] = knm[i][j-1] + knm[i-1][j-1]; } } return knm[n][(n*n-n)/2-ne]; } /* Case of vertex with clique neighbourhood */ if (goodv >= 0) { delete1(g,h,goodv,n); return -POPCOUNT(g[goodv]) * conncontent(h,m,n-1); } /* Case of minimum degree 2 */ if (mindeg == 2) { x = FIRSTBIT(g[minv]); y = FIRSTBIT(g[minv]^bit[x]); if (x > minv) --x; if (y > minv) --y; delete1(g,h,minv,n); v1 = conncontent(h,m,n-1); if (h[x] & bit[y]) return -2*v1; /* adjacent neighbours */ h[x] |= bit[y]; h[y] |= bit[x]; v2 = conncontent(h,m,n-1); return -v1 - v2; } /* Case of more than 2/3 dense but not complete */ if (3*ne > n*n-n) { j = FIRSTBIT(g[minv] ^ bit[minv] ^ ALLMASK(n)); /* non-neighbour */ g[minv] ^= bit[j]; g[j] ^= bit[minv]; v1 = conncontent(g,m,n); g[minv] ^= bit[j]; g[j] ^= bit[minv]; contract1(g,h,minv,j,n); v2 = conncontent(h,m,n-1); return v1 + v2; } /* All remaining cases */ j = FIRSTBIT(g[minv]); /* neighbour */ g[minv] ^= bit[j]; g[j] ^= bit[minv]; v1 = conncontent(g,m,n); g[minv] ^= bit[j]; g[j] ^= bit[minv]; contract1(g,h,minv,j,n); v2 = conncontent(h,m,n-1); return v1 - v2; }