Exemplo n.º 1
0
/* 
 * attach and install edges between clusters.
 * essentially, class2() for interclust edges.
 */
void interclexp(graph_t* subg)
{
	graph_t		*g;
	node_t		*n;
	edge_t		*e,*prev;

	g = subg->root;
	for (n = agfstnode(subg); n; n = agnxtnode(subg,n)) {

		/* N.B. n may be in a sub-cluster of subg */
		prev = NULL;
		for (e = agfstedge(subg->root,n); e; e = agnxtedge(subg->root,e,n)) {
			if (agcontains(subg,e)) continue;

			/* short/flat multi edges */
			if (mergeable(prev,e)) {
					if (e->tail->u.rank == e->head->u.rank) e->u.to_virt = prev;
					else e->u.to_virt = NULL;
					if (prev->u.to_virt == NULL) continue;	/* internal edge */
					merge_chain(subg,e,prev->u.to_virt,FALSE);
					safe_other_edge(e);
					continue;
			}

				/* flat edges */
			if (e->tail->u.rank == e->head->u.rank) {
				if (find_flat_edge(e->tail,e->head) == NULL) {
					flat_edge(g,e); prev = e;
				}
				else prev = NULL;
				continue;
			}

			assert (e->u.to_virt != NULL);

				/* forward edges */
			if (e->head->u.rank > e->tail->u.rank) {
				make_interclust_chain(g,e->tail,e->head,e);
				prev = e;
				continue;
			}

				/* backward edges */
			else {
/*
I think that make_interclust_chain should create call other_edge(e) anyway 
				if (agcontains(subg,e->tail)
					&& agfindedge(subg->root,e->head,e->tail)) other_edge(e);
*/
				make_interclust_chain(g,e->head,e->tail,e);
				prev = e;
			}
		}
	}
}
Exemplo n.º 2
0
/* 
 * attach and install edges between clusters.
 * essentially, class2() for interclust edges.
 */
void interclexp(graph_t * subg)
{
    graph_t *g;
    node_t *n;
    edge_t *e, *prev, *next;

    g = agroot(subg);
    for (n = agfstnode(subg); n; n = agnxtnode(subg, n)) {

	/* N.B. n may be in a sub-cluster of subg */
	prev = NULL;
	for (e = agfstedge(agroot(subg), n); e; e = next) {
	    next = agnxtedge(agroot(subg), e, n);
	    if (agcontains(subg, e))
		continue;

#ifdef WITH_CGRAPH
		/* canonicalize edge */
	    e = AGMKOUT(e);
#endif
	    /* short/flat multi edges */
	    if (mergeable(prev, e)) {
		if (ND_rank(agtail(e)) == ND_rank(aghead(e)))
		    ED_to_virt(e) = prev;
		else
		    ED_to_virt(e) = NULL;
		if (ED_to_virt(prev) == NULL)
		    continue;	/* internal edge */
		merge_chain(subg, e, ED_to_virt(prev), FALSE);
		safe_other_edge(e);
		continue;
	    }

	    /* flat edges */
	    if (ND_rank(agtail(e)) == ND_rank(aghead(e))) {
		edge_t* fe;
		if ((fe = find_flat_edge(agtail(e), aghead(e))) == NULL) {
		    flat_edge(g, e);
		    prev = e;
		} else if (e != fe) {
		    safe_other_edge(e);
		    if (!ED_to_virt(e)) merge_oneway(e, fe);
		}
		continue;
	    }

/* This assertion is still valid if the new ranking is not used */
#ifndef WITH_CGRAPH
	    assert(ED_to_virt(e) != NULL);
#endif

	    /* forward edges */
	    if (ND_rank(aghead(e)) > ND_rank(agtail(e))) {
		make_interclust_chain(g, agtail(e), aghead(e), e);
		prev = e;
		continue;
	    }

	    /* backward edges */
	    else {
/*
I think that make_interclust_chain should create call other_edge(e) anyway 
				if (agcontains(subg,agtail(e))
					&& agfindedge(subg->root,aghead(e),agtail(e))) other_edge(e);
*/
		make_interclust_chain(g, aghead(e), agtail(e), e);
		prev = e;
	    }
	}
    }
}