コード例 #1
0
ファイル: genbg.c プロジェクト: dimpase/nauty_sagemath
static boolean
accept2(graph *g, int n2, int x, graph *gx, int *deg, boolean nuniq)
/* decide if n in theta(g+x) -- version for n+1 == maxn */
{
    int i,n;
    int lab[MAXN],ptn[MAXN],orbits[MAXN];
    int degx[MAXN],invar[MAXN];
    setword vmax,gv;
    int qn,qv;
    int count[MAXN];
    int xw;
    int nx,numcells,code;
    int degn,i0,i1,j,j0,j1;
    set active[MAXM];
    statsblk stats;
    static DEFAULTOPTIONS_GRAPH(options);
    setword workspace[50];

#ifdef INSTRUMENT
    ++a2calls;
    if (nuniq) ++a2uniq;
#endif
    n = n1 + n2;
    nx = n + 1;
    for (i = 0; i < n; ++i)
    {
        gx[i] = g[i];
        degx[i] = deg[i];
    }
    gx[n] = 0;
    degx[n] = degn = XPOPCOUNT(x);

    xw = x;
    while (xw)
    {
        i = XNEXTBIT(xw);
        xw &= ~xbit[i];
        gx[i] |= bit[n];
        gx[n] |= bit[i];
        ++degx[i];
    }
#ifdef PRUNE1
    if (PRUNE1(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif

    if (nuniq)
    {
#ifdef INSTRUMENT
        ++a2succs;
#endif
#ifdef PRUNE2
        if (PRUNE2(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif
        if (canonise) makecanon(gx,gcan,n1,n2+1);
        return TRUE;
    }

    for (i = 0; i < n1; ++i)
    {
        lab[i] = i;
        ptn[i] = 1;
    }
    ptn[n1-1] = 0;

    i0 = n1;
    i1 = n;
    for (i = n1; i < nx; ++i)
    {
        if (degx[i] == degn) lab[i1--] = i;
        else                 lab[i0++] = i;
        ptn[i] = 1;
    }

    ptn[n] = 0;

    if (i0 == n1)
    {
        numcells = 2;
        active[0] = bit[0] | bit[n1];

        if (!distinvar(gx,invar,n1,n2+1)) return FALSE;
        qn = invar[n];
        j0 = n1;
        j1 = n;
        while (j0 <= j1)
        {
            j = lab[j0];
            qv = invar[j];
            if (qv < qn)
                ++j0;
            else
            {
                lab[j0] = lab[j1];
                lab[j1] = j;
                --j1;
            }
        }
        if (j0 > n1)
        {
            if (j0 == n)
            {
#ifdef INSTRUMENT
                ++a2succs;
#endif
#ifdef PRUNE2
                if (PRUNE2(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif
                if (canonise) makecanon(gx,gcan,n1,n2+1);
                return TRUE;
            }
            ptn[j1] = 0;
            ++numcells;
            active[0] |= bit[j0];
        }
    }
    else
    {
        numcells = 3;
        ptn[i1] = 0;
        active[0] = bit[0] | bit[n1] | bit[i1+1];

        vmax = 0;
        j = MAXN;
        for (i = 0; i < n1; ++i)
            if (degx[i] < j && degx[i] > 0)
            {
                j = degx[i];
                vmax = bit[i];
            }
            else if (degx[i] == j)
                vmax |= bit[i];

        gv = gx[n] & vmax;
        qn = POPCOUNT(gv);

        j0 = i1+1;
        j1 = n;
        while (j0 <= j1)
        {
            j = lab[j0];
            gv = gx[j] & vmax;
            qv = POPCOUNT(gv);
            if (qv > qn)
                return FALSE;
            else if (qv < qn)
                ++j0;
            else
            {
                lab[j0] = lab[j1];
                lab[j1] = j;
                --j1;
            }
        }
        if (j0 > i1+1)
        {
            if (j0 == n)
            {
#ifdef INSTRUMENT
                ++a2succs;
#endif
#ifdef PRUNE2
                if (PRUNE2(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif
                if (canonise) makecanon(gx,gcan,n1,n2+1);
                return TRUE;
            }
            ptn[j1] = 0;
            ++numcells;
            active[0] |= bit[j0];
        }
    }

    refinex(gx,lab,ptn,0,&numcells,count,active,TRUE,&code,1,nx);

    if (code < 0)
        return FALSE;
    else if (code > 0 || numcells >= nx-4)
    {
#ifdef INSTRUMENT
        ++a2succs;
#endif
#ifdef PRUNE2
        if (PRUNE2(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif
        if (canonise) makecanon(gx,gcan,n1,n2+1);
        return TRUE;
    }

    options.writemarkers = FALSE;
    options.writeautoms = FALSE;
    options.getcanon = TRUE;
    options.defaultptn = FALSE;

    active[0] = 0;
#ifdef INSTRUMENT
    ++a2nauty;
#endif
    nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,gcan);

    if (orbits[lab[n]] == orbits[n])
    {
#ifdef INSTRUMENT
        ++a2succs;
#endif
#ifdef PRUNE2
    if (PRUNE2(gx,degx,n1,n2+1,maxn2)) return FALSE;
#endif
        if (canonise) makecanon(gx,gcan,n1,n2+1);
        return TRUE;
    }
    else
        return FALSE;
}
コード例 #2
0
ファイル: genbg.c プロジェクト: dimpase/nauty_sagemath
static void
makeleveldata(void)
/* make the level data for each level */
{
    int i,j,h;
    int nn,nxsets,tttn;
    long ncj;
    leveldata *d;
    int xw,cw;

    nn = maxdeg2 <= n1 ? maxdeg2 : n1;
    ncj = nxsets = 1;
    for (j = 1; j <= nn; ++j)
    {
        ncj = (ncj * (n1 - j + 1)) / j;
        nxsets += ncj;
    }

    tttn = 1 << n1;
    xset = (int*) ALLOCS(nxsets,sizeof(int));
    xcard = (int*) ALLOCS(nxsets,sizeof(int));
    xinv = (int*) ALLOCS(tttn,sizeof(int));
    if (xset==NULL || xcard==NULL || xinv==NULL)
    {
        fprintf(stderr,">E genbg: malloc failed in makeleveldata()\n");
        exit(2);
    }

    j = 0;
    for (i = 0; i < tttn; ++i)
        if ((h = XPOPCOUNT(i)) <= maxdeg2)
        {
            xset[j] = i;
            xcard[j] = h;
            ++j;
        }

    if (j != nxsets)
    {
        fprintf(stderr,">E genbg: j=%d mxsets=%d\n",j,nxsets);
        exit(2);
    }

    /* The following is not SORT_OF_SORT 1, 2 or 3 */

    h = 1;
    do
        h = 3 * h + 1;
    while (h < nxsets);

    do
    {
        for (i = h; i < nxsets; ++i)
        {
            xw = xset[i];
            cw = xcard[i];
            for (j = i; xcard[j-h] > cw ||
                        (xcard[j-h] == cw && xset[j-h] > xw); )
            {
                xset[j] = xset[j-h];
                xcard[j] = xcard[j-h];
                if ((j -= h) < h) break;
            }
            xset[j] = xw;
            xcard[j] = cw;
        }
        h /= 3;
    }
    while (h > 0);

    for (i = 0; i < nxsets; ++i) xinv[xset[i]] = i;

    xstart[0] = 0;
    for (i = 1; i < nxsets; ++i)
        if (xcard[i] > xcard[i-1]) xstart[xcard[i]] = i;
    xstart[xcard[nxsets-1]+1] = nxsets;

    for (i = 0; i < maxn2; ++i)
    {

        d = &data[i];

        d->xorb = (int*) ALLOCS(nxsets,sizeof(int));

        if (d->xorb==NULL)
        {
            fprintf(stderr,">E genbg: malloc failed in makeleveldata()\n");
            exit(2);
        }

        d->ne = d->dmax = d->xlb = d->xub = -1;
    }
}
コード例 #3
0
ファイル: genbg.c プロジェクト: dimpase/nauty_sagemath
static boolean
accept1(graph *g, int n2, int x, graph *gx, int *deg, boolean *rigid)
 /* decide if n2 in theta(g+x) -- version for n2+1 < maxn2 */
{
    int i,n;
    int lab[MAXN],ptn[MAXN],orbits[MAXN];
    int count[MAXN];
    graph h[MAXN];
    int xw;
    int nx,numcells,code;
    int i0,i1,degn;
    set active[MAXM];
    statsblk stats;
    static DEFAULTOPTIONS_GRAPH(options);
    setword workspace[50];

#ifdef INSTRUMENT
    ++a1calls;
#endif

    n = n1 + n2;
    nx = n + 1;
    for (i = 0; i < n; ++i) gx[i] = g[i];
    gx[n] = 0;
    deg[n] = degn = XPOPCOUNT(x);

    xw = x;
    while (xw)
    {
        i = XNEXTBIT(xw);
        xw &= ~xbit[i];
        gx[i] |= bit[n];
        gx[n] |= bit[i];
        ++deg[i];
    }
#ifdef PRUNE1
    if (PRUNE1(gx,deg,n1,n2+1,maxn2)) return FALSE;
#endif

    for (i = 0; i < n1; ++i)
    {
        lab[i] = i;
        ptn[i] = 1;
    }
    ptn[n1-1] = 0;

    i0 = n1;
    i1 = n;
    for (i = n1; i < nx; ++i)
    {
        if (deg[i] == degn) lab[i1--] = i;
        else                lab[i0++] = i;
        ptn[i] = 1;
    }

    ptn[n] = 0;

    if (i0 == n1)
    {
        numcells = 2;
        active[0] = bit[0] | bit[n1];
    }
    else
    {
        numcells = 3;
        active[0] = bit[0] | bit[n1] | bit[i1+1];
        ptn[i1] = 0;
    }
    refinex(gx,lab,ptn,0,&numcells,count,active,FALSE,&code,1,nx);

    if (code < 0) return FALSE;

    if (numcells == nx)
    {
        *rigid = TRUE;
#ifdef INSTRUMENT
        ++a1succs;
#endif
#ifdef PRUNE2
        if (PRUNE2(gx,deg,n1,n2+1,maxn2)) return FALSE;
#endif
        return TRUE;
    }

    options.writemarkers = FALSE;
    options.writeautoms = FALSE;
    options.getcanon = TRUE;
    options.defaultptn = FALSE;
    options.userautomproc = userautomproc;

    active[0] = 0;
#ifdef INSTRUMENT
    ++a1nauty;
#endif
    nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,h);

    if (orbits[lab[n]] == orbits[n])
    {
        *rigid = stats.numorbits == nx;
#ifdef INSTRUMENT
        ++a1succs;
#endif
#ifdef PRUNE2
        if (PRUNE2(gx,deg,n1,n2+1,maxn2)) return FALSE;
#endif
        return TRUE;
    }
    else
        return FALSE;
}
コード例 #4
0
ファイル: genbg.c プロジェクト: dimpase/nauty_sagemath
static void
genextend(graph *g, int n2, int *deg, int ne, boolean rigid, int xlb, int xub)
/* extend from n2 to n2+1 */
{
    int x,y,d;
    int *xorb,xc;
    int nx,i,j,imin,imax,dmax;
    int xlbx,xubx,n;
    graph gx[MAXN];
    int degx[MAXN];
    boolean rigidx;
    int dneed,need,nfeet,hideg,deg1,ft[MAXN],nfrag,frag[MAXN];

#ifdef INSTRUMENT
    boolean haschild;

    haschild = FALSE;
    ++nodes[n2];
    if (rigid) ++rigidnodes[n2];
#endif

    n = n1 + n2;
    nx = n2 + 1;
    dmax = deg[n-1];

    d = 0;
    dneed = mindeg1 - maxn2 + n2;
    need = 0;
    hideg = 0;
    deg1 = 0;
    for (i = 0; i < n1; ++i)
    {
        if (deg[i] == maxdeg1) d |= xbit[i];
        if (deg[i] <= dneed) need |= xbit[i];
        if (deg[i] >= 2) hideg |= xbit[i];
        if (deg[i] == 1) deg1 |= xbit[i];
    }

    if (xlb < XPOPCOUNT(need)) xlb = XPOPCOUNT(need);
    if (xlb > xub) return;

    imin = xstart[xlb];
    imax = xstart[xub+1];
    xorb = data[n2].xorb;

    if (nx == maxn2)
    {
        if (footfree)
        {
            nfeet = 0;
            for (j = 0; j < n2; ++j)
            {
                x = xval[j] & hideg;
                IFLE1BITS(x) ft[nfeet++] = xval[j] & deg1;
            }
        }
        if (cutfree) fragments(xval,n2,frag,&nfrag);

        for (i = imin; i < imax; ++i)
        {
            if (!rigid && xorb[i] != i) continue;
            x = xset[i];
            xc = xcard[i];
            if ((x & d) != 0) continue;
            if ((need & ~x) != 0) continue;

            if (simple)
            {
                for (j = n2; --j >= 0;)
                    if (x == xval[j]) break;
                if (j >= 0) continue;
            }
            if (maxcommon >= 0)
            {
                for (j = n2; --j >= 0;)
                {
                    y = x & xval[j];
                    if (XPOPCOUNT(y) > maxcommon) break;
                }
                if (j >= 0) continue;
            }
	    if (antichain)
	    {
		for (j = 0; j < n2; ++j)
		    if ((xval[j] & ~x) == 0) break;
		if (j < n2) continue;
	    }
            if (footfree)
            {
                y = x & (hideg | deg1);
                IFLE1BITS(y) continue;
                for (j = 0; j < nfeet; ++j)
                    if ((x & ft[j]) == 0) break;
                if (j < nfeet) continue;
            }
            if (cutfree)
            {
                y = x & (hideg | deg1);
                IFLE1BITS(y) continue;
                for (j = 0; j < nfrag; ++j)
                    if ((x & frag[j]) == 0) break;
                if (j < nfrag) continue;
            }

            xval[n2] = x;

            if (nx == nprune)
            {
                if (curres == 0) curres = mod;
#ifdef SPLITTEST
                --curres;
                ++splitcases;
                continue;
#else
                if (--curres != 0) continue;
#endif
            }
            if (accept2(g,n2,x,gx,deg,xc > dmax))
                if (!connec || isconnected(gx,n+1))
                {
                    ADDBIG(ecount[ne+xc],1);
#ifdef INSTRUMENT
                    haschild = TRUE;
#endif
                    (*outproc)(outfile,canonise ? gcan : gx,n1,n2+1);
                }
        }
    }
    else
    {
        for (i = imin; i < imax; ++i)
コード例 #5
0
ファイル: gentourng.c プロジェクト: igraph/nautier
static boolean
accept2(graph *g, int n, xword x, graph *gx, int *deg, boolean nuniq)
/* decide if n in theta(g+x)  --  version for n+1 == maxn */
{
        int i;
        int lab[MAXN],ptn[MAXN],orbits[MAXN];
        int degx[MAXN],invar[MAXN];
        setword vmax,gv,gxn;
        int qn,qv;
        int count[MAXN];
        int nx,numcells,code;
        int degn,i0,i1,j,j0,j1;
        set active[MAXM];
        statsblk stats;
        static DEFAULTOPTIONS_GRAPH(options);
        setword workspace[50];
	boolean cheapacc;

#ifdef INSTRUMENT
        ++a2calls;
        if (nuniq) ++a2uniq;
#endif
        nx = n + 1;
        gxn = 0;

        for (i = 0; i < n; ++i)
	{
	    if ((xbit[i] & x))
	    {
		gxn |= bit[i];
		gx[i] = g[i];
		degx[i] = deg[i];
	    }
	    else
	    {
		gx[i] = g[i] | bit[n];
		degx[i] = deg[i] + 1;
	    }
	}
	gx[n] = gxn;
        degx[n] = degn = XPOPCOUNT(x);
	    
#ifdef PREPRUNE
        if (PREPRUNE(gx,n+1,maxn)) return FALSE;
#endif

        if (nuniq)
        {
#ifdef INSTRUMENT
            ++a2succs;
#endif
            if (canonise) makecanon(gx,gcan,nx);
            return TRUE;
        }

        i0 = 0;
        i1 = n;
        for (i = 0; i < nx; ++i)
        {
            if (degx[i] == degn) lab[i1--] = i;
            else                 lab[i0++] = i;
            ptn[i] = 1;
        }
        ptn[n] = 0;
        if (i0 == 0)
        {
            numcells = 1;
            active[0] = bit[0];
            if (!hitinvar(gx,invar,nx)) return FALSE;
            qn = invar[n];
            j0 = 0;
            j1 = n;
            while (j0 <= j1)
            {
                j = lab[j0];
                qv = invar[j];
                if (qv < qn)
                    ++j0;
                else
                {
                    lab[j0] = lab[j1];
                    lab[j1] = j;
                    --j1;
                }
            }
            if (j0 > 0)
            {
                if (j0 == n)
                {
#ifdef INSTRUMENT
                    ++a2succs;
#endif
                    if (canonise) makecanon(gx,gcan,nx);
                    return TRUE;
                }
                ptn[j1] = 0;
                ++numcells;
                active[0] |= bit[j0];
            }
        }
        else
        {
            numcells = 2;
            ptn[i1] = 0;
            active[0] = bit[0] | bit[i1+1];

            vmax = 0;
            for (i = i1+1; i < nx; ++i) vmax |= bit[lab[i]];

            gv = gx[n] & vmax;
            qn = POPCOUNT(gv);

            j0 = i1+1;
            j1 = n;
            while (j0 <= j1)
            {
                j = lab[j0];
                gv = gx[j] & vmax;
                qv = POPCOUNT(gv);
                if (qv > qn)
                    return FALSE;
                else if (qv < qn)
                    ++j0;
                else
                {
                    lab[j0] = lab[j1];
                    lab[j1] = j;
                    --j1;
                }
            }
            if (j0 > i1+1)
            {
                if (j0 == n)
                {
#ifdef INSTRUMENT
                    ++a2succs;
#endif
                    if (canonise) makecanon(gx,gcan,nx);
                    return TRUE;
                }
                ptn[j1] = 0;
                ++numcells;
                active[0] |= bit[j0];
            }
        }

        refinex(gx,lab,ptn,0,&numcells,count,active,TRUE,&code,1,nx);

        if (code < 0) return FALSE;

	cheapacc = FALSE;
	if (code > 0) cheapacc = TRUE;
    
        if (cheapacc)
        {
#ifdef INSTRUMENT
            ++a2succs;
#endif
            if (canonise) makecanon(gx,gcan,nx);
            return TRUE;
        }

        options.getcanon = TRUE;
        options.digraph = TRUE;
        options.defaultptn = FALSE;

        active[0] = 0;
#ifdef INSTRUMENT
        ++a2nauty;
#endif
        nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,gcan);

        if (orbits[lab[n]] == orbits[n])
        {
#ifdef INSTRUMENT
            ++a2succs;
#endif
            if (canonise) makecanon(gx,gcan,nx);
            return TRUE;
        }
        else
            return FALSE;
}
コード例 #6
0
ファイル: gentourng.c プロジェクト: igraph/nautier
static boolean
accept1(graph *g, int n, xword x, graph *gx, int *deg, boolean *rigid)
/* decide if n in theta(g+x) -  version for n+1 < maxn */
{
        int i;
        int lab[MAXN],ptn[MAXN],orbits[MAXN];
        int count[MAXN];
        graph h[MAXN];
        int nx,numcells,code;
        int i0,i1,degn;
        set active[MAXM];
        statsblk stats;
        static DEFAULTOPTIONS_GRAPH(options);
        setword workspace[50];

#ifdef INSTRUMENT
        ++a1calls;
#endif

        nx = n + 1;
        for (i = 0; i < n; ++i) gx[i] = g[i];
        gx[n] = 0;
        deg[n] = degn = XPOPCOUNT(x);

        for (i = 0; i < n; ++i)
	{
	    if ((xbit[i] & x))
		gx[n] |= bit[i];
	    else
	    {
		gx[i] |= bit[n];
		++deg[i];
	    }
	}

#ifdef PREPRUNE
	if (PREPRUNE(gx,n+1,maxn)) return FALSE;
#endif

        i0 = 0;
        i1 = n;
        for (i = 0; i < nx; ++i)
        {
            if (deg[i] == degn) lab[i1--] = i;
            else                lab[i0++] = i;
            ptn[i] = 1;
        }
        ptn[n] = 0;
        if (i0 == 0)
        {
            numcells = 1;
            active[0] = bit[0];
        }
        else
        {
            numcells = 2;
            active[0] = bit[0] | bit[i1+1];
            ptn[i1] = 0;
        }
        refinex(gx,lab,ptn,0,&numcells,count,active,FALSE,&code,1,nx);

        if (code < 0) return FALSE;

        if (numcells == nx)
        {
            *rigid = TRUE;
#ifdef INSTRUMENT
            ++a1succs;
#endif
            return TRUE;
        }

        options.getcanon = TRUE;
        options.digraph = TRUE;
        options.defaultptn = FALSE;
	options.userautomproc = userautomproc;
     /*
        if (!regular || nx != maxn-1) options.userautomproc = userautomproc;
	else                          options.userautomproc = NULL;
     */

        active[0] = 0;
#ifdef INSTRUMENT
        ++a1nauty;
#endif
        nauty(gx,lab,ptn,active,orbits,&options,&stats,workspace,50,1,nx,h);

        if (orbits[lab[n]] == orbits[n])
        {
            *rigid = stats.numorbits == nx;
#ifdef INSTRUMENT
            ++a1succs;
#endif
            return TRUE;
        }
        else
            return FALSE;
}
コード例 #7
0
ファイル: gentourng.c プロジェクト: igraph/nautier
static void
makeleveldata(void)
/* make the level data for each level */
{
        long h;
        int n,dmax,dmin;
        long ncj;
        leveldata *d;
	xword *xcard,*xinv;
	xword *xset,xw,tttn,nxsets;
	xword cw;
	xword i,j;

        for (n = 1; n < maxn; ++n)
        {
            dmax = n/2; 
	    if (maxdeg < dmax) dmax = maxdeg;
            dmin = mindeg - maxn + n + 1;
	    if (dmin < 0) dmin = 0;
            ncj = 1;
	    nxsets = (dmin == 0 ? 1 : 0);
            for (j = 1; j <= dmax; ++j)
            {
                ncj = (ncj * (n-j+1)) / j;
                if (j >= dmin) nxsets += ncj;
            }
            tttn = 1L << n;

            d = &data[n];

            d->xset = xset = (xword*) calloc(nxsets,sizeof(xword));
            d->xcard = xcard = (xword*) calloc(nxsets,sizeof(xword));
            d->xinv = xinv = (xword*) calloc(tttn,sizeof(xword));
            d->xorb = (xword*) calloc(nxsets,sizeof(xword));

            if (xset==NULL || xcard==NULL || xinv==NULL || d->xorb==NULL)
            {
                fprintf(stderr,
			">E gentourng: calloc failed in makeleveldata()\n");
                exit(2);
            }

            j = 0;

            for (i = 0;; ++i)
	    {
                if ((h = XPOPCOUNT(i)) <= dmax && h >= dmin)
                {
                    xset[j] = i;
                    xcard[j] = h;
                    ++j;
                }
		if (i == (xword)((1L<<n)-1)) break;
	    }

            if (j != nxsets)
            {
                fprintf(stderr,">E gentourng: j=%u mxsets=%u\n",
                        j,(unsigned)nxsets);
                exit(2);
            }

            h = 1;
            do
                h = 3 * h + 1;
            while (h < nxsets);

            do
            {
                for (i = h; i < nxsets; ++i)
                {
                    xw = xset[i];
                    cw = xcard[i];
                    for (j = i; xcard[j-h] > cw ||
                                (xcard[j-h] == cw && xset[j-h] > xw); )
                    {
                        xset[j] = xset[j-h];
                        xcard[j] = xcard[j-h];
                        if ((j -= h) < h) break;
                    }
                    xset[j] = xw;
                    xcard[j] = cw;
                }
                h /= 3;
            }
            while (h > 0);

            for (i = 0; i < nxsets; ++i) xinv[xset[i]] = i;

            d->xstart[0] = 0;
            for (i = 1; i < nxsets; ++i)
                if (xcard[i] > xcard[i-1]) d->xstart[xcard[i]] = i;
            d->xstart[xcard[nxsets-1]+1] = nxsets;
        }
}
コード例 #8
0
ファイル: gentourng.c プロジェクト: igraph/nautier
static void
genextend(graph *g, int n, int *deg, boolean rigid)
/* extend from n to n+1 -- version for general graphs */
{
        xword x,dlow,dhigh,dcrit;
        xword *xset,*xcard,*xorb;
	xword i,imin,imax;
        int nx,xc,j,dmax;
        int xlb,xub,xlbx,xubx;
        graph gx[MAXN];
        int degx[MAXN];
        boolean rigidx;
	boolean subconnec;

#ifdef INSTRUMENT
        boolean haschild;

        haschild = FALSE;
        if (rigid) ++rigidnodes[n];
#endif
        nx = n + 1;
        ADDBIG(nodes[n],1);

	if (regular && nx == maxn)
	{
	    x = 0;
	    for (i = 0; i < n; ++i)
		if (deg[i] == maxdeg) x |= xbit[i];

            if (accept2(g,n,x,gx,deg,FALSE))
            {
#ifdef PRUNE
                if (!PRUNE(gx,nx,maxn))
#endif
		{
#ifdef INSTRUMENT
                    haschild = TRUE;
#endif
		    ADDBIG(nout,1);
                    (*outproc)(outfile,canonise ? gcan : gx,nx);
		}
            }
#ifdef INSTRUMENT
            if (haschild) ++fertilenodes[n];
#endif
	    return;
	}

        dmax = deg[n-1];

	xlb = mindeg + n + 1 - maxn;
	if (0 > xlb) xlb = 0;
	xub = dmax+1;
	if (n/2 < xub) xub = n/2;
	if (maxdeg < xub) xub = maxdeg;

	if (xlb > xub) return;

        dlow = dcrit = dhigh = 0;
        for (i = 0; i < n; ++i)
	{
            if (deg[i] == dmax) dlow |= xbit[i];
	    if (deg[i] == maxdeg) dhigh |= xbit[i];
	    if (deg[i] == mindeg + n - maxn) dcrit |= xbit[i];
	}

        if (XPOPCOUNT(dhigh) > xlb) xlb = XPOPCOUNT(dhigh);
	if (n-XPOPCOUNT(dcrit) < xub) xub = n - XPOPCOUNT(dcrit);
	if (xub == dmax+1 && XPOPCOUNT(dlow)+dmax >= n) --xub;
        if (xlb > xub) return;

#ifdef PRUNE 
        if (PRUNE(g,n,maxn)) return; 
#endif 

        imin = data[n].xstart[xlb];
        imax = data[n].xstart[xub+1];
        xset = data[n].xset;
        xcard = data[n].xcard;
        xorb = data[n].xorb;

        if (nx == maxn)
	{
	    subconnec = connec && isstrong(g,n);
            for (i = imin; i < imax; ++i)
            {
                if (!rigid && xorb[i] != i) continue;
                x = xset[i];
                xc = xcard[i];
                if (xc == dmax+1 && (x & dlow) != 0) continue;
 		if ((dhigh & ~x) != 0) continue;
		if ((dcrit & x) != 0) continue;

                if (accept2(g,n,x,gx,deg,
                            xc < dmax || (xc == dmax && (x & dlow) == 0)))
                    if (!connec || (subconnec && x != 0) || isstrong(gx,nx))
                    {
#ifdef PRUNE
                        if (!PRUNE(gx,nx,maxn))
#endif
			{
#ifdef INSTRUMENT
                            haschild = TRUE;
#endif
			    ADDBIG(nout,1);
                            (*outproc)(outfile,canonise ? gcan : gx,nx);
			}
                    }
            }
	}
        else
	{
            for (i = imin; i < imax; ++i)
            {
                if (!rigid && xorb[i] != i) continue;
                x = xset[i];
                xc = xcard[i];
                if (xc == dmax+1 && (x & dlow) != 0) continue;
 		if ((dhigh & ~x) != 0) continue;
		if ((dcrit & x) != 0) continue;
                if (nx == splitlevel)
                {
                    if (odometer-- != 0) continue;
                    odometer = mod - 1;
                }

                for (j = 0; j < n; ++j) degx[j] = deg[j];
                xlbx = mindeg+nx+1-maxn;
		if (xlbx < 0) xlbx = 0;
		xubx = xc + 1;
		if (maxdeg < xubx) xubx = maxdeg;
		if (nx/2 < xubx) xubx = nx/2;
                if (xlbx > xubx) continue;

                data[nx].lo = data[nx].xstart[xlbx];
                data[nx].hi = data[nx].xstart[xubx+1];
                if (accept1(g,n,x,gx,degx,&rigidx))
                {
#ifdef INSTRUMENT
                    haschild = TRUE;
#endif
                    genextend(gx,nx,degx,rigidx);
                }
            }
	}

        if (n == splitlevel-1 && n >= min_splitlevel
                && ISASBIG(nodes[n],multiplicity))
            --splitlevel;
#ifdef INSTRUMENT
        if (haschild) ++fertilenodes[n];
#endif
}