Пример #1
0
void build_skeleton(graph_t *g, graph_t *subg)
{
	int			r;
	node_t		*v,*prev,*rl;
	edge_t		*e;

	prev = NULL;
	subg->u.rankleader = N_NEW(subg->u.maxrank + 2,node_t*);
	for (r = subg->u.minrank; r <= subg->u.maxrank; r++) {
		v = subg->u.rankleader[r] = virtual_node(g);
		v->u.rank = r;
		v->u.ranktype = CLUSTER;
		v->u.clust = subg;
		if (prev) {
			e = virtual_edge(prev,v,NULL);
			e->u.xpenalty *= CL_CROSS;
		}
		prev = v;
	}

	/* set the counts on virtual edges of the cluster skeleton */
	for (v = agfstnode(subg); v; v = agnxtnode(subg,v)) {
		rl = subg->u.rankleader[v->u.rank];
		rl->u.UF_size++;
		for (e = agfstout(subg,v); e; e = agnxtout(subg,e)) {
			for (r = e->tail->u.rank; r < e->head->u.rank; r++) {
				rl->u.out.list[0]->u.count++;
			}
		}
	}
	for (r = subg->u.minrank; r <= subg->u.maxrank; r++) {
		rl = subg->u.rankleader[r];
		if (rl->u.UF_size > 1) rl->u.UF_size--;
	}
}
Пример #2
0
node_t	*
clone_vn(graph_t* g, node_t* vn)
{
	node_t	*rv;
	int		r;

	r = vn->u.rank;
	make_slots(g,r,vn->u.order,2);
	rv = virtual_node(g);
	rv->u.lw = vn->u.lw;
	rv->u.rw = vn->u.rw;
	rv->u.rank = vn->u.rank;
	rv->u.order = vn->u.order + 1;
	g->u.rank[r].v[rv->u.order] = rv;
	return rv;
}
Пример #3
0
int nonconstraint_edge(edge_t * e)
{
    char *constr;

#ifndef WITH_CGRAPH
    if (E_constr && (constr = agxget(e, E_constr->index))) {
#else /* WITH_CGRAPH */
    if (E_constr && (constr = agxget(e, E_constr))) {
#endif /* WITH_CGRAPH */
	if (constr[0] && mapbool(constr) == FALSE)
	    return TRUE;
    }
    return FALSE;
}

static void 
interclust1(graph_t * g, node_t * t, node_t * h, edge_t * e)
{
    node_t *v, *t0, *h0;
    int offset, t_len, h_len, t_rank, h_rank;
    edge_t *rt, *rh;

    if (ND_clust(agtail(e)))
	t_rank = ND_rank(agtail(e)) - ND_rank(GD_leader(ND_clust(agtail(e))));
    else
	t_rank = 0;
    if (ND_clust(aghead(e)))
	h_rank = ND_rank(aghead(e)) - ND_rank(GD_leader(ND_clust(aghead(e))));
    else
	h_rank = 0;
    offset = ED_minlen(e) + t_rank - h_rank;
    if (offset > 0) {
	t_len = 0;
	h_len = offset;
    } else {
	t_len = -offset;
	h_len = 0;
    }

    v = virtual_node(g);
    ND_node_type(v) = SLACKNODE;
    t0 = UF_find(t);
    h0 = UF_find(h);
    rt = make_aux_edge(v, t0, t_len, CL_BACK * ED_weight(e));
    rh = make_aux_edge(v, h0, h_len, ED_weight(e));
    ED_to_orig(rt) = ED_to_orig(rh) = e;
}
Пример #4
0
void interclust1(graph_t *g, node_t *t, node_t *h, edge_t *e)
{
	node_t		*v,*t0,*h0;
	int			offset,t_len,h_len,t_rank,h_rank;
	edge_t		*rt,*rh;

	if (e->tail->u.clust)
		t_rank = e->tail->u.rank - e->tail->u.clust->u.leader->u.rank;
	else t_rank = 0;
	if (e->head->u.clust)
		h_rank = e->head->u.rank - e->head->u.clust->u.leader->u.rank;
	else h_rank = 0;
	offset = e->u.minlen + t_rank - h_rank;
	if (offset > 0) {t_len = 0; h_len = offset;}
	else {t_len = -offset; h_len = 0;}

	v = virtual_node(g);
	v->u.node_type = SLACKNODE;
	t0 = UF_find(t); h0 = UF_find(h);
	rt = make_aux_edge(v,t0,t_len,CL_BACK*e->u.weight);
	rh = make_aux_edge(v,h0,h_len,e->u.weight);
	rt->u.to_orig = rh->u.to_orig = e;
}
Пример #5
0
/* make d slots starting at position pos (where 1 already exists) */
static void 
make_slots(graph_t * root, int r, int pos, int d)
{
    int i;
    node_t *v, **vlist;
#ifndef WITH_CGRAPH
    vlist = ND_rank(root)[r].v;
#else /* WITH_CGRAPH */
    vlist = GD_rank(root)[r].v;
#endif /* WITH_CGRAPH */
    if (d <= 0) {
#ifndef WITH_CGRAPH
	for (i = pos - d + 1; i < ND_rank(root)[r].n; i++) {
#else /* WITH_CGRAPH */
	for (i = pos - d + 1; i < GD_rank(root)[r].n; i++) {
#endif /* WITH_CGRAPH */
	    v = vlist[i];
	    ND_order(v) = i + d - 1;
	    vlist[ND_order(v)] = v;
	}
#ifndef WITH_CGRAPH
	for (i = ND_rank(root)[r].n + d - 1; i < ND_rank(root)[r].n; i++)
#else /* WITH_CGRAPH */
	for (i = GD_rank(root)[r].n + d - 1; i < GD_rank(root)[r].n; i++)
#endif /* WITH_CGRAPH */
	    vlist[i] = NULL;
    } else {
/*assert(ND_rank(root)[r].n + d - 1 <= ND_rank(root)[r].an);*/
#ifndef WITH_CGRAPH
	for (i = ND_rank(root)[r].n - 1; i > pos; i--) {
#else /* WITH_CGRAPH */
	for (i = GD_rank(root)[r].n - 1; i > pos; i--) {
#endif /* WITH_CGRAPH */
	    v = vlist[i];
	    ND_order(v) = i + d - 1;
	    vlist[ND_order(v)] = v;
	}
	for (i = pos + 1; i < pos + d; i++)
	    vlist[i] = NULL;
    }
#ifndef WITH_CGRAPH
    ND_rank(root)[r].n += d - 1;
#else /* WITH_CGRAPH */
    GD_rank(root)[r].n += d - 1;
#endif /* WITH_CGRAPH */
}

static node_t* 
clone_vn(graph_t * g, node_t * vn)
{
    node_t *rv;
    int r;

    r = ND_rank(vn);
    make_slots(g, r, ND_order(vn), 2);
    rv = virtual_node(g);
    ND_lw(rv) = ND_lw(vn);
    ND_rw(rv) = ND_rw(vn);
    ND_rank(rv) = ND_rank(vn);
    ND_order(rv) = ND_order(vn) + 1;
    GD_rank(g)[r].v[ND_order(rv)] = rv;
    return rv;
}
Пример #6
0
/* this function marks every node in <g> with its top-level cluster under <g> */
void mark_clusters(graph_t * g)
{
    int c;
    node_t *n, *nn, *vn;
    edge_t *orig, *e;
    graph_t *clust;

    /* remove sub-clusters below this level */
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	if (ND_ranktype(n) == CLUSTER)
	    UF_singleton(n);
	ND_clust(n) = NULL;
    }

    for (c = 1; c <= GD_n_cluster(g); c++) {
	clust = GD_clust(g)[c];
	for (n = agfstnode(clust); n; n = nn) {
		nn = agnxtnode(clust,n);
	    if (ND_ranktype(n) != NORMAL) {
		agerr(AGWARN,
		      "%s was already in a rankset, deleted from cluster %s\n",
		      agnameof(n), agnameof(g));
		agdelete(clust,n);
		continue;
	    }
	    UF_setname(n, GD_leader(clust));
	    ND_clust(n) = clust;
	    ND_ranktype(n) = CLUSTER;

	    /* here we mark the vnodes of edges in the cluster */
	    for (orig = agfstout(clust, n); orig;
		 orig = agnxtout(clust, orig)) {
		if ((e = ED_to_virt(orig))) {
#ifndef WITH_CGRAPH
		    while (e && (vn = e->head)->u.node_type == VIRTUAL) {
#else /* WITH_CGRAPH */
		    while (e && ND_node_type(vn =aghead(e)) == VIRTUAL) {
#endif /* WITH_CGRAPH */
			ND_clust(vn) = clust;
			e = ND_out(aghead(e)).list[0];
			/* trouble if concentrators and clusters are mixed */
		    }
		}
	    }
	}
    }
}

void build_skeleton(graph_t * g, graph_t * subg)
{
    int r;
    node_t *v, *prev, *rl;
    edge_t *e;

    prev = NULL;
    GD_rankleader(subg) = N_NEW(GD_maxrank(subg) + 2, node_t *);
    for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) {
	v = GD_rankleader(subg)[r] = virtual_node(g);
	ND_rank(v) = r;
	ND_ranktype(v) = CLUSTER;
	ND_clust(v) = subg;
	if (prev) {
	    e = virtual_edge(prev, v, NULL);
	    ED_xpenalty(e) *= CL_CROSS;
	}
	prev = v;
    }

    /* set the counts on virtual edges of the cluster skeleton */
    for (v = agfstnode(subg); v; v = agnxtnode(subg, v)) {
	rl = GD_rankleader(subg)[ND_rank(v)];
	ND_UF_size(rl)++;
	for (e = agfstout(subg, v); e; e = agnxtout(subg, e)) {
	    for (r = ND_rank(agtail(e)); r < ND_rank(aghead(e)); r++) {
		ED_count(ND_out(rl).list[0])++;
	    }
	}
    }
    for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) {
	rl = GD_rankleader(subg)[r];
	if (ND_UF_size(rl) > 1)
	    ND_UF_size(rl)--;
    }
}