Beispiel #1
0
static void
fragments(int *x, int nx, int *frag, int *nfrag)
/* For each v in union(x[0..nx-1]), find the components of the
   hypergraph x - v and add them to frag if there are more than one. */
/* This implementation is shocking.  Improve it! */
{
    int allx,i,j,v;
    int vbit,nw,w[MAXN];
    boolean done;

    allx = 0;
    for (i = 0; i < nx; ++i) allx |= x[i];

    *nfrag = 0;
    
    while (allx)
    {
        v = XNEXTBIT(allx);
        vbit = xbit[v];
        allx &= ~vbit;

        for (i = 0; i < nx; ++i) w[i] = x[i] & ~vbit;
        nw = nx;

        done = FALSE;
        while (!done && nw > 1)
        {
            done = TRUE;
            for (i = 0; i < nw-1; ++i)
            for (j = i+1; j < nw; )
                if ((w[i] & w[j]) != 0)
                {
                    w[i] |= w[j];
                    w[j] = w[nw-1];
                    --nw;
                    done = FALSE;
                }
                else
                    ++j;
        }
    
        if (nw > 1)
            for (i = 0; i < nw; ++i)
                frag[(*nfrag)++] = w[i];
    }
}
Beispiel #2
0
static UPROC
userautomproc(int count, int *p, int *orbits, int numorbits,
          int stabvertex, int n)
/* Automorphism procedure called by nauty
   Form orbits on powerset of VG
   Operates on data[n-n1] */
{
    int i,j1,j2;
    int moved,pxi,pi;
    int w,lo,hi;
    int *xorb;

    xorb = data[n-n1].xorb;
    lo = data[n-n1].lo;
    hi = data[n-n1].hi;

    if (count == 1)                         /* first automorphism */
        for (i = lo; i < hi; ++i) xorb[i] = i;

    moved = 0;
    for (i = 0; i < n; ++i)
        if (p[i] != i) moved |= xbit[i];

    for (i = lo; i < hi; ++i)
    {
        if ((w = xset[i] & moved) == 0) continue;
        pxi = xset[i] & ~moved;
        while (w)
        {
            j1 = XNEXTBIT(w);
            w &= ~xbit[j1];
            pxi |= xbit[p[j1]];
        }
        pi = xinv[pxi];

        j1 = xorb[i];
        while (xorb[j1] != j1) j1 = xorb[j1];
        j2 = xorb[pi];
        while (xorb[j2] != j2) j2 = xorb[j2];

        if      (j1 < j2) xorb[j2] = xorb[i] = xorb[pi] = j1;
        else if (j1 > j2) xorb[j1] = xorb[i] = xorb[pi] = j2;
    }
}
Beispiel #3
0
static void
userautomproc(int count, int *p, int *orbits,
              int numorbits, int stabvertex, int n)
/* form orbits on powerset of VG
   called by nauty;  operates on data[n] */
{
	xword i,j1,j2,moved,pi,pxi;
        xword lo,hi;
        xword *xorb,*xinv,*xset,w;

        xorb = data[n].xorb;
        xset = data[n].xset;
        xinv = data[n].xinv;
        lo = data[n].lo;
        hi = data[n].hi;

        if (count == 1)                         /* first automorphism */
            for (i = lo; i < hi; ++i) xorb[i] = i;

        moved = 0;
        for (i = 0; i < n; ++i)
            if (p[i] != i) moved |= xbit[i];

        for (i = lo; i < hi; ++i)
        {
            if ((w = xset[i] & moved) == 0) continue;
            pxi = xset[i] & ~moved;
            while (w)
            {
                j1 = XNEXTBIT(w);
                w ^= xbit[j1];
                pxi |= xbit[p[j1]];
            }
            pi = xinv[pxi];

            j1 = xorb[i];
            while (xorb[j1] != j1) j1 = xorb[j1];
            j2 = xorb[pi];
            while (xorb[j2] != j2) j2 = xorb[j2];

            if      (j1 < j2) xorb[j2] = xorb[i] = xorb[pi] = j1;
            else if (j1 > j2) xorb[j1] = xorb[i] = xorb[pi] = j2;
        }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}