Пример #1
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
}
Пример #2
0
void
writegre(FILE *f, graph *g, int n1, int n2)
/* write graph g (n1+n2 vertices) to file f in Greechie diagram format */
{
    static char atomname[] = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz!\"#$%&'()*-/:;<=>?@[\\]^_`{|}~";
    char grestr[MAXN*MAXN+MAXN+5];
    int i,j,k;
    setword gi;

    k = 0;
    for (i = n1; i < n1+n2; ++i)
    {
        if (i > n1) grestr[k++] = ',';
        gi = g[i];
        while (gi)
        {
            TAKEBIT(j,gi);
            grestr[k++] = atomname[j];
        }
    }
    grestr[k++] = '.';
    grestr[k++] = '\n';
    grestr[k] = '\0';
    if (fputs(grestr,f) == EOF || ferror(f))
    {
        fprintf(stderr,">E genbg : error on writing file\n");
        gt_abort(NULL);
    }
}
Пример #3
0
static boolean
hitinvar(graph *g, int *invar, int n)
/* make hitting invariant
 *    return FALSE if n-1 not maximal else return TRUE */
{
        setword x,y,z;
        int inv,i,v,d;

        for (v = n-1; v >= 0; --v)
        {
            inv = 0;
            x = y = g[v];
	    while (y)
	    {
		TAKEBIT(i,y);
		z = x & g[i];
		d = POPCOUNT(z);
		if (d > inv) inv = d;
	    }

            invar[v] = inv;
            if (v < n-1 && inv > invar[n-1]) return FALSE;
        }
        return TRUE;
}
Пример #4
0
static long
maxclnode1(graph *g, setword cliq, setword cov, int maxv)
/* Internal search node.  cov has all the vertices outside cliq that
 * cover all of cliq.  maxv is the last vertex of cliq.
 */
{
    long ans;
    int i;
    setword w;

    if (cov == 0) return 1;

    ans = 0;
    w = cov & BITMASK(maxv);
    while (w)
    {
        TAKEBIT(i,w);
	ans += maxclnode1(g,cliq|bit[i],cov&g[i]&~bit[i],i);
    }
    return ans;
}
Пример #5
0
long
pathcount1(graph *g, int start, setword body, setword last)
/* Number of paths in g starting at start, lying within body and
   ending in last.  {start} and last should be disjoint subsets of body. */
{
    long count;
    setword gs,w;
    int i;

    gs = g[start];
    w = gs & last;
    count = POPCOUNT(w);

    body &= ~bit[start];
    w = gs & body;
    while (w)
    {
	TAKEBIT(i,w);
	count += pathcount1(g,i,body,last&~bit[i]);
    }

    return count;
}
Пример #6
0
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;
}
Пример #7
0
static void
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;
        setword x,lact;
        int split1,split2,cell1,cell2;
        int cnt,bmin,bmax;
        set *gptr;
        setword workset;
        int workperm[MAXN];
        int bucket[MAXN+2];

        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;

                    c1 = cell1;
                    c2 = cell2;
                    while (c1 <= c2)
                    {
                        labc1 = lab[c1];
                        if (ISELEMENT1(gptr,labc1))
                            ++c1;
                        else
                        {
                            lab[c1] = lab[c2];
                            lab[c2] = labc1;
                            --c2;
                        }
                    }
                    if (c2 >= cell1 && c1 <= cell2)
                    {
                        ptn[c2] = 0;
                        ++*numcells;
			lact |= bit[c1];
                    }
                }
            }

            else        /* nontrivial splitting cell */
            {
                workset = 0;
                for (i = split1; i <= split2; ++i) workset |= bit[lab[i]];

                for (cell1 = 0; cell1 < n; cell1 = cell2 + 1)
                {
                    for (cell2 = cell1; ptn[cell2] > 0; ++cell2) {}
                    if (cell1 == cell2) continue;
                    i = cell1;
                    if ((x = workset & g[lab[i]]) != 0) cnt = POPCOUNT(x);
                    else                                cnt = 0;
                    count[i] = bmin = bmax = cnt;
                    bucket[cnt] = 1;
                    while (++i <= cell2)
                    {
                        if ((x = workset & g[lab[i]]) != 0)
                            cnt = POPCOUNT(x);
                        else
                            cnt = 0;

                        while (bmin > cnt) bucket[--bmin] = 0;
                        while (bmax < cnt) bucket[++bmax] = 0;
                        ++bucket[cnt];
                        count[i] = cnt;
                    }
                    if (bmin == bmax) continue;
                    c1 = cell1;
                    for (i = bmin; i <= bmax; ++i)
                        if (bucket[i])
                        {
                            c2 = c1 + bucket[i];
                            bucket[i] = c1;
                            if (c1 != cell1)
                            {
                                lact |= bit[c1];
                                ++*numcells;
                            }
                            if (c2 <= cell2) ptn[c2-1] = 0;
                            c1 = c2;
                        }
                    for (i = cell1; i <= cell2; ++i)
                        workperm[bucket[count[i]]++] = lab[i];
                    for (i = cell1; i <= cell2; ++i) lab[i] = workperm[i];
                }
            }

            if (ptn[n-2] == 0)
            {
                if (lab[n-1] == n-1)
                {
                    *code = 1;
                    if (goodret) return;
                }
                else
                {
                    *code = -1;
                    return;
                }
            }
            else
            {
                i = n - 1;
                while (TRUE)
                {
                    if (lab[i] == n-1) break;
                    --i;
                    if (ptn[i] == 0)
                    {
                        *code = -1;
                        return;
                    }
                }
            }
        }
}
Пример #8
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;
}