Exemplo n.º 1
0
static void
makeprism_sg(sparsegraph *sg, sparsegraph *sh)
/* Make the cartesian product sh = sg x K2.
   sh must be initialized. */
{
    size_t *v,*vv,vi,vvi;
    int *d,*dd,*e,*ee;
    int i,j,n;

    SG_VDE(sg,v,d,e);
    n = sg->nv;

    SG_ALLOC(*sh,2*sg->nv,2*(n+sg->nde),"makeprism_sg");
    sh->nv = 2*n;
    sh->nde = 2*(n+sg->nde);
    SG_VDE(sh,vv,dd,ee);
 
    vvi = 0;
    for (i = 0; i < n; ++i)
    {
	vi = v[i];
	dd[2*i] = dd[2*i+1] = d[i] + 1;
	vv[2*i] = vvi;
	for (j = 0; j < d[i]; ++j) ee[vvi++] = 2*e[vi++];
	ee[vvi++] = 2*i+1;
	vi = v[i];
	vv[2*i+1] = vvi;
	for (j = 0; j < d[i]; ++j) ee[vvi++] = 2*e[vi++]+1;
	ee[vvi++] = 2*i;
    }
}
Exemplo n.º 2
0
static void
subdivisiongraph(sparsegraph *g, int k, sparsegraph *h)
/* h := subdivision graph of g, k new vertices per edge */
{
    DYNALLSTAT(size_t,eno,eno_sz);   /* edge number */
    int *ge,*gd,*he,*hd;
    size_t *gv,*hv;
    int gnv,hnv;
    size_t i,j,l,gnde,hnde,num;
    size_t hi,lo,mid,w;

    if (k == 0)
    {
	copy_sg(g,h);
	return;
    }

    sortlists_sg(g);
    SG_VDE(g,gv,gd,ge);
    gnv = g->nv;
    gnde = g->nde;
    DYNALLOC1(size_t,eno,eno_sz,gnde,"subdivideg");

    hnv = gnv + k*(gnde/2);
    if (hnv <= 0 || (gnde > 0 && ((size_t)(hnv-gnv))/(gnde/2) != k))
        gt_abort(">E subdivideg: output graph too large\n");
    hnde = gnde * (k+1);
    if (hnde/(k+1) != gnde)
        gt_abort(">E subdivideg: output graph too large\n");

    num = 0;
    for (i = 0; i < gnv; ++i)
    {
        for (j = gv[i]; j < gv[i]+gd[i]; ++j)
        {
            if (ge[j] == i)
                gt_abort(">E subdivideg can't handle undirected loops\n");
            else if (ge[j] > i)
                eno[j] = num++;
            else
            {
                lo = gv[ge[j]];
                hi = lo + gd[ge[j]] - 1;
                while (lo <= hi)
                {
                    mid = lo + (hi-lo)/2;
                    if (ge[mid] == i) break;
                    else if  (ge[mid] < i) lo = mid+1;
                    else hi = mid-1;
                }
		if (lo > hi)
		    gt_abort(">E subdivideg : binary search failed\n");
                eno[j] = eno[mid];
            }
        }
    }

    SG_ALLOC(*h,hnv,hnde,"subdivideg");
    h->nv = hnv;
    h->nde = hnde;
    SG_VDE(h,hv,hd,he);

    for (i = 0; i < gnv; ++i)
    {
        hd[i] = gd[i];
        hv[i] = gv[i];
    }
    for (i = gnv; i < hnv; ++i)
    {
	hd[i] = 2;
        hv[i] = gnde + 2*(i-gnv);
    }

    for (i = 0; i < gnv; ++i)
    {
        for (j = gv[i]; j < gv[i]+gd[i]; ++j)
            if (ge[j] > i)
	    {
		w = gnv + k*eno[j];
		he[j] = w;
		he[hv[w]] = i;
		for (l = 1; l < k; ++l)
		{
		    he[hv[w]+1] = w+1;
		    he[hv[w+1]] = w;
		    ++w;
		}
	    }
	    else
	    {
		w = gnv + k*eno[j] + k - 1;
		he[j] = w;
		he[hv[w]+1] = i;
	    }
    }
}
Exemplo n.º 3
0
static int
hamheur(sparsegraph *sg, unsigned long limit, int *cyc)
/* Try up to limit, fill cyc if YES and cyc!=NULL */
{
    DYNALLSTAT(int,path,path_sz);
    DYNALLSTAT(int,work,work_sz);
    DYNALLSTAT(int,pos,pos_sz);  /* position on path or -1 */
    int end0,end1,v0,v1;
    size_t *v;
    int n,*e,*d,len,d0,*e0,d1,*e1,dx,*ex;
    int i,ix,x,j,w,vext,exts;
    unsigned long count;
    boolean left,cycle;
    long ran;
 
    SG_VDE(sg,v,d,e);
    n = sg->nv;
    if (n < 3) return NO;

    DYNALLOC1(int,path,path_sz,2*n+4,"malloc");
    DYNALLOC1(int,pos,pos_sz,n,"malloc");
    DYNALLOC1(int,work,work_sz,n,"malloc");

    for (i = 0; i < n; ++i)
    {
	if (d[i] < 2) return NO;
	pos[i] = -1;
    }
    count = 0;
 
    v0 = KRAN(n);
    v1 = e[v[v0]+KRAN(d[v0])];
    end0 = n+1;
    end1 = n+2;
    path[end0] = v0; pos[v0] = end0;
    path[end1] = v1; pos[v1] = end1;
    len = 2;

    for (; count < limit;)
    {
     /* First look for an extension, but note if cycle */

	v0 = path[end0];
	v1 = path[end1];

	exts = 0;
	d0 = d[v0];
        e0 = e + v[v0];
	cycle = FALSE;
        ran = NEXTRAN;
	for (i = 0; i < d0; ++i)
	{
	    w = e0[i];
	    if (pos[w] < 0)
	    {
		++exts;
		if (ran%exts == 0) {left = TRUE; vext = w;}
	    }
	    else if (w == v1) cycle = TRUE;
        }
	d1 = d[v1];
        e1 = e + v[v1];
        ran = NEXTRAN;
	for (i = 0; i < d1; ++i)
	{
	    w = e1[i];
	    if (pos[w] < 0) 
            {
                ++exts;
                if (ran%exts == 0) {left = FALSE; vext = w;}
            }
	}

	if (exts > 0)
	{
	    if (left)
	    {
		--end0;
		path[end0] = vext;
		pos[vext] = end0;
	    }
	    else
	    {
		++end1;
		path[end1] = vext;
		pos[vext] = end1;
	    }
	    ++len;
	    continue;
	}

     /* Can't extend but a cycle was found */

	if (cycle)
        {
	    if (len == n)
	    {
		if (cyc)
		{
		    j = 0;
		    for (i = pos[0]; i <= end1; ++i) cyc[j++] = path[i];
		    for (i = end0; i < pos[0]; ++i) cyc[j++] = path[i];
		}
		return YES;
	    }

	    ix = end0 + KRAN(len);
	    for (i = 0; i < len; ++i)      
            {
	        x = path[ix];

	        exts = 0;
	        dx = d[x];
	        ex = e + v[x];
		ran = NEXTRAN;
	        for (j = 0; j < dx; ++j)
	        {
		    w = ex[j];
		    if (pos[w] < 0) 
                    {
                        ++exts;
                        if (ran%exts == 0) vext = w;
                    }
	        }
		if (exts > 0) break;
		if (ix == end1) ix = end0; else ++ix;
            }
	    if (i == len) return NO;    /* isolated component */

	    work[0] = vext;
	    j = 1;
	    for (i = ix; i <= end1; ++i) work[j++] = path[i];
	    for (i = end0; i < ix; ++i) work[j++] = path[i];

	    for (i = 0; i < j; ++i)
	    {
		path[end0+i] = work[i];
                pos[work[i]] = end0+i;
	    }
	    ++end1;
	    ++len;
	    continue;
        }

     /* In the last resort, do a sideways move. */
    
	exts = 0;
	d0 = d[v0];
        e0 = e + v[v0];
        ran = NEXTRAN;
	for (i = 0; i < d0; ++i)
	{
	    w = e0[i];
	    if (pos[w] >= 0 && w != path[end0+1])
	    {
		++exts;
		if (ran%exts == 0) {left = TRUE; vext = w;}
	    }
        }
	d1 = d[v1];
        e1 = e + v[v1];
        ran = NEXTRAN;
	for (i = 0; i < d1; ++i)
	{
	    w = e1[i];
	    if (pos[w] >= 0 && w != path[end1-1]) 
            {
                ++exts;
                if (ran%exts == 0) {left = FALSE; vext = w;}
            }
	}

	if (left)
	{
	    i = end0;
            j = pos[vext]-1;
	}
	else
	{
	    i = pos[vext]+1;
	    j = end1;
	}
	for (; i < j; ++i, --j)
	{
	    w = path[i];
	    path[i] = path[j];
	    path[j] = w;
	    pos[path[i]] = i;
	    pos[path[j]] = j;
	}

	++count;
    }

    return TIMEOUT;
}
Exemplo n.º 4
0
static void
linegraph(sparsegraph *g, sparsegraph *h)
/* h := linegraph of g */
{
    DYNALLSTAT(size_t,eno,eno_sz);   /* edge number */
    int *ge,*gd,*he,*hd;
    size_t *gv,*hv;
    int gnv,hnv;
    size_t i,j,k,gnde,hnde,xhnde,num;
    size_t hi,lo,mid,v,w;

    sortlists_sg(g);
    SG_VDE(g,gv,gd,ge);
    gnv = g->nv;
    gnde = g->nde;
    DYNALLOC1(size_t,eno,eno_sz,gnde,"linegraphg");

    hnv = gnde/2;
    if (hnv != gnde/2) gt_abort(">E linegraphg: too many input edges\n");

    hnde = 0;
    num = 0;
    for (i = 0; i < gnv; ++i)
    {
        xhnde = hnde;
        hnde += gd[i]*((size_t)gd[i]-1);
        if (hnde < xhnde) gt_abort(">E linegraphg: too many output edges\n");

        for (j = gv[i]; j < gv[i]+gd[i]; ++j)
        {
            if (ge[j] == i)
                gt_abort(">E linegraphg can't handle loops\n");
            else if (ge[j] > i)
                eno[j] = num++;
            else
            {
                lo = gv[ge[j]];
                hi = lo + gd[ge[j]] - 1;
                while (lo <= hi)
                {
                    mid = lo + (hi-lo)/2;
                    if (ge[mid] == i) break;
                    else if  (ge[mid] < i) lo = mid+1;
                    else hi = mid-1;
                }
		if (lo > hi)
		    gt_abort(">E linegraphg : binary search failed\n");
                eno[j] = eno[mid];
            }
        }
    }

    SG_ALLOC(*h,hnv,hnde,"linegraphg");
    h->nv = hnv;
    h->nde = hnde;
    SG_VDE(h,hv,hd,he);

    for (i = 0; i < hnv; ++i) hd[i] = 0;
    for (i = 0; i < gnv; ++i)
    {
        for (j = gv[i]; j < gv[i]+gd[i]; ++j)
            hd[eno[j]] += gd[i]-1;
    }

    hv[0] = 0;
    for (i = 1; i < hnv; ++i) hv[i] = hv[i-1] + hd[i-1];
    for (i = 0; i < hnv; ++i) hd[i] = 0;

    for (i = 0; i < gnv; ++i)
    {
        for (j = gv[i]; j < gv[i]+gd[i]-1; ++j)
        for (k = j+1; k < gv[i]+gd[i]; ++k)
        {
            v = eno[j]; w = eno[k];
            he[hv[v]+(hd[v]++)] = w;
            he[hv[w]+(hd[w]++)] = v;
        }
    }
}