Пример #1
0
void class1(graph_t * g)
{
    node_t *n, *t, *h;
    edge_t *e, *rep;

    mark_clusters(g);
    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {

	    /* skip edges already processed */
	    if (ED_to_virt(e))
		continue;

	    /* skip edges that we want to ignore in this phase */
	    if (nonconstraint_edge(e))
		continue;

	    t = UF_find(agtail(e));
	    h = UF_find(aghead(e));

	    /* skip self, flat, and intra-cluster edges */
	    if (t == h)
		continue;


	    /* inter-cluster edges require special treatment */
	    if (ND_clust(t) || ND_clust(h)) {
		interclust1(g, agtail(e), aghead(e), e);
		continue;
	    }

	    if ((rep = find_fast_edge(t, h)))
		merge_oneway(e, rep);
	    else
		virtual_edge(t, h, e);

#ifdef NOTDEF
	    if ((t == agtail(e)) && (h == aghead(e))) {
		if (rep = find_fast_edge(t, h))
		    merge_oneway(e, rep);
		else
		    virtual_edge(t, h, e);
	    } else {
		f = agfindedge(g, t, h);
		if (f && (ED_to_virt(f) == NULL))
		    rep = virtual_edge(t, h, f);
		else
		    rep = find_fast_edge(t, h);
		if (rep)
		    merge_oneway(e, rep);
		else
		    virtual_edge(t, h, e);
	    }
#endif
	}
    }
}
Пример #2
0
static void mergevirtual(graph_t * g, int r, int lpos, int rpos, int dir)
{
    int i, k;
    node_t *left, *right;
    edge_t *e, *f, *e0;

    left = GD_rank(g)[r].v[lpos];
    /* merge all right nodes into the leftmost one */
    for (i = lpos + 1; i <= rpos; i++) {
	right = GD_rank(g)[r].v[i];
	if (dir == DOWN) {
	    while ((e = ND_out(right).list[0])) {
		for (k = 0; (f = ND_out(left).list[k]); k++)
		    if (f->head == e->head)
			break;
		if (f == NULL)
		    f = virtual_edge(left, e->head, e);
		while ((e0 = ND_in(right).list[0])) {
		    merge_oneway(e0, f);
		    /*ED_weight(f) += ED_weight(e0); */
		    delete_fast_edge(e0);
		}
		delete_fast_edge(e);
	    }
	} else {
	    while ((e = ND_in(right).list[0])) {
		for (k = 0; (f = ND_in(left).list[k]); k++)
		    if (f->tail == e->tail)
			break;
		if (f == NULL)
		    f = virtual_edge(e->tail, left, e);
		while ((e0 = ND_out(right).list[0])) {
		    merge_oneway(e0, f);
		    delete_fast_edge(e0);
		}
		delete_fast_edge(e);
	    }
	}
	assert(ND_in(right).size + ND_out(right).size == 0);
	delete_fast_node(g, right);
    }
    k = lpos + 1;
    i = rpos + 1;
    while (i < GD_rank(g)[r].n) {
	node_t *n;
	n = GD_rank(g)[r].v[k] = GD_rank(g)[r].v[i];
	ND_order(n) = k;
	k++;
	i++;
    }
    GD_rank(g)[r].n = k;
    GD_rank(g)[r].v[k] = NULL;
}
Пример #3
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--;
	}
}
Пример #4
0
static int 
minmax_edges2(graph_t * g, point slen)
{
    node_t *n;
    edge_t *e = 0;

    if ((GD_maxset(g)) || (GD_minset(g))) {
	for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	    if (n != UF_find(n))
		continue;
	    if ((ND_out(n).size == 0) && GD_maxset(g) && (n != GD_maxset(g))) {
		e = virtual_edge(n, GD_maxset(g), NULL);
		ED_minlen(e) = slen.y;
	    }
	    if ((ND_in(n).size == 0) && GD_minset(g) && (n != GD_minset(g))) {
		e = virtual_edge(GD_minset(g), n, NULL);
		ED_minlen(e) = slen.x;
	    }
	}
    }
    return (e != 0);
}
Пример #5
0
static void
restoreVirtualEdges(graph_t *g)
{
    int i;
    edge_t e;

    for (i = 0; i < nVirtualEdges; i++) {
	if (virtualEdgeTailList[i] && virtualEdgeHeadList[i]) {
	    if (Verbose)
		printf("restoring virtual edge: %s->%s\n", 
		    virtualEdgeTailList[i]->name, virtualEdgeHeadList[i]->name);
	    virtual_edge(virtualEdgeTailList[i], virtualEdgeHeadList[i], NULL);
	}
    }
    if (Verbose)
	printf("restored %d virt edges\n", nVirtualEdges);
}
Пример #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)--;
    }
}
Пример #7
0
static void 
map_path(node_t * from, node_t * to, edge_t * orig, edge_t * ve, int type)
{
    int r;
    node_t *u, *v;
    edge_t *e;

    assert(ND_rank(from) < ND_rank(to));

    if ((agtail(ve) == from) && (aghead(ve) == to))
	return;

    if (ED_count(ve) > 1) {
	ED_to_virt(orig) = NULL;
	if (ND_rank(to) - ND_rank(from) == 1) {
	    if ((e = find_fast_edge(from, to)) && (ports_eq(orig, e))) {
		merge_oneway(orig, e);
		if ((ND_node_type(from) == NORMAL)
		    && (ND_node_type(to) == NORMAL))
		    other_edge(orig);
		return;
	    }
	}
	u = from;
	for (r = ND_rank(from); r < ND_rank(to); r++) {
	    if (r < ND_rank(to) - 1)
		v = clone_vn(agraphof(from), aghead(ve));
	    else
		v = to;
	    e = virtual_edge(u, v, orig);
	    ED_edge_type(e) = type;
	    u = v;
	    ED_count(ve)--;
	    ve = ND_out(aghead(ve)).list[0];
	}
    } else {
	if (ND_rank(to) - ND_rank(from) == 1) {
	    if ((ve = find_fast_edge(from, to)) && (ports_eq(orig, ve))) {
		/*ED_to_orig(ve) = orig; */
		ED_to_virt(orig) = ve;
		ED_edge_type(ve) = type;
		ED_count(ve)++;
		if ((ND_node_type(from) == NORMAL)
		    && (ND_node_type(to) == NORMAL))
		    other_edge(orig);
	    } else {
		ED_to_virt(orig) = NULL;
		ve = virtual_edge(from, to, orig);
		ED_edge_type(ve) = type;
	    }
	}
	if (ND_rank(to) - ND_rank(from) > 1) {
	    e = ve;
	    if (agtail(ve) != from) {
		ED_to_virt(orig) = NULL;
		e = ED_to_virt(orig) = virtual_edge(from, aghead(ve), orig);
		delete_fast_edge(ve);
	    } else
		e = ve;
	    while (ND_rank(aghead(e)) != ND_rank(to))
		e = ND_out(aghead(e)).list[0];
	    if (aghead(e) != to) {
		ve = e;
		e = virtual_edge(agtail(e), to, orig);
		ED_edge_type(e) = type;
		delete_fast_edge(ve);
	    }
	}
    }
}
Пример #8
0
void map_path(node_t *from, node_t *to, edge_t *orig, edge_t *ve, int type)
{
	int			r;
	node_t		*u,*v;
	edge_t		*e;

	assert(from->u.rank < to->u.rank);

	if ((ve->tail == from) && (ve->head == to)) return;

	if (ve->u.count > 1)  {
		orig->u.to_virt = NULL;
		if (to->u.rank - from->u.rank == 1) {
			if ((e = find_fast_edge(from,to)) && (ports_eq(orig,e))) {
				merge_oneway(orig,e);
				if ((from->u.node_type == NORMAL)
					&& (to->u.node_type == NORMAL))
						other_edge(orig);
				return;
			}
		}
		u = from;
		for (r = from->u.rank; r < to->u.rank; r++) {
			if (r < to->u.rank - 1) v = clone_vn(from->graph,ve->head);
			else v = to;
			e = virtual_edge(u,v,orig);
			e->u.edge_type = type;
			u = v;
			ve->u.count--;
			ve = ve->head->u.out.list[0];
		}
	}
	else {
		if (to->u.rank - from->u.rank == 1) {
			if ((ve = find_fast_edge(from,to)) && (ports_eq(orig,ve))) {
				/*ve->u.to_orig = orig;*/
				orig->u.to_virt = ve;
				ve->u.edge_type = type;
				ve->u.count++;
				if ((from->u.node_type == NORMAL)
					&& (to->u.node_type == NORMAL))
						other_edge(orig);
			}
			else {
				orig->u.to_virt = NULL;
				ve = virtual_edge(from,to,orig);
				ve->u.edge_type = type;
			}
		}
		if (to->u.rank - from->u.rank > 1) {
			e = ve;
			if (ve->tail != from) {
				orig->u.to_virt = NULL;
				e = orig->u.to_virt = virtual_edge(from,ve->head,orig);
				delete_fast_edge(ve);
			}
			else e = ve;
			while (e->head->u.rank != to->u.rank) e = e->head->u.out.list[0];
			if (e->head != to) {
				ve = e;
				e = virtual_edge(e->tail,to,orig);
				e->u.edge_type = type;
				delete_fast_edge(ve);
			}
		}
	}
}