Example #1
0
/* sets ports that represent connections to subclusters */
static void subclustports(Agraph_t *ug)
{
	Agraph_t	*model, *clustmodel;
	Agnode_t	*x;
	Agedge_t	*e;
	vpath_t		*p;
	Dict_t		*d;
	double		frac;

	/* walk all the paths */
	model = GD_model(ug);
	d = repdict(model);
	for (p = dtfirst(d); p; p = dtnext(d,p)) {
		if ((ND_type(p->v[p->low])) == NODETYPE_CNODE) {
			x = p->v[p->low];
			clustmodel = GD_model(ND_cluster(x));
			frac = (ND_order(x) + 1) / GD_rank(clustmodel)[ND_rank(x)].n;
			e = p->e[p->low];
			ED_tailport(e).p.x = 2 * PORTCLAMP * (frac - 0.5) + p->tailport;
		}
		if ((ND_type(p->v[p->high])) == NODETYPE_CNODE) {
			x = p->v[p->high];
			clustmodel = GD_model(ND_cluster(x));
			frac = (ND_order(x) + 1) / GD_rank(clustmodel)[ND_rank(x)].n;
			e = p->e[p->high-1];
			ED_headport(e).p.x = 2 * PORTCLAMP * (frac - 0.5) + p->headport;
		}
	}
}
Example #2
0
/* determine canonical order of n0, n1 */
static void getlowhigh(Agnode_t **n0, Agnode_t **n1)
{
	Agnode_t	*temp;
	int				d;
	d =  ND_rank(*n0) - ND_rank(*n1);
	if ((d < 0) || ((d == 0) && ((*n0)->id > (*n1)->id)))
		{temp = *n0; *n0 = *n1; *n1 = temp;}
}
Example #3
0
static void infuse(graph_t * g, node_t * n)
{
    node_t *lead;

    lead = GD_rankleader(g)[ND_rank(n)];
    if ((lead == NULL) || (ND_order(lead) > ND_order(n)))
	GD_rankleader(g)[ND_rank(n)] = n;
}
Example #4
0
static void 
set_minmax(graph_t * g)
{
    int c;

    GD_minrank(g) += ND_rank(GD_leader(g));
    GD_maxrank(g) += ND_rank(GD_leader(g));
    for (c = 1; c <= GD_n_cluster(g); c++)
	set_minmax(GD_clust(g)[c]);
}
Example #5
0
static void rebuild_vlists(graph_t * g)
{
    int c, i, r, maxi;
    node_t *n, *lead;
    edge_t *e, *rep;

    for (r = GD_minrank(g); r <= GD_maxrank(g); r++)
	GD_rankleader(g)[r] = NULL;

    for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
	infuse(g, n);
	for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
	    for (rep = e; ED_to_virt(rep); rep = ED_to_virt(rep));
	    while (ND_rank(rep->head) < ND_rank(e->head)) {
		infuse(g, rep->head);
		rep = ND_out(rep->head).list[0];
	    }
	}
    }

    for (r = GD_minrank(g); r <= GD_maxrank(g); r++) {
	lead = GD_rankleader(g)[r];
	if (ND_rank(g->root)[r].v[ND_order(lead)] != lead)
	    abort();
	GD_rank(g)[r].v =
	    ND_rank(g->root)[r].v + GD_rankleader(g)[r]->u.order;
	maxi = -1;
	for (i = 0; i < GD_rank(g)[r].n; i++) {
	    if ((n = GD_rank(g)[r].v[i]) == NULL)
		break;
	    if (ND_node_type(n) == NORMAL) {
		if (agcontains(g, n))
		    maxi = i;
		else
		    break;
	    } else {
		edge_t *e;
		for (e = ND_in(n).list[0]; e && ED_to_orig(e);
		     e = ED_to_orig(e));
		if (e && (agcontains(g, e->tail))
		    && agcontains(g, e->head))
		    maxi = i;
	    }
	}
	if (maxi == -1)
	    agerr(AGWARN, "degenerate concentrated rank %s,%d\n", g->name,
		  r);
	GD_rank(g)[r].n = maxi + 1;
    }

    for (c = 1; c <= GD_n_cluster(g); c++)
	rebuild_vlists(GD_clust(g)[c]);
}
Example #6
0
/* a given edge can have several other edges (forward or backward)
   between the same endpoints.  here, we choose one of these to be
	 the canonical representative of those edges. */
static Agedge_t* canonical_edge(Agedge_t* e)
{
	Agraph_t	*g;
	Agedge_t	*canon;

	g = e->tail->graph;
	if (ND_rank(e->head) > ND_rank(e->tail))
		canon = agfindedge(g,e->tail,e->head);
	else {
		if 
	}
}
Example #7
0
static void 
merge_ranks(graph_t * subg)
{
    int i, d, r, pos, ipos;
    node_t *v;
    graph_t *root;

    root = agroot(subg);
    if (GD_minrank(subg) > 0)
#ifndef WITH_CGRAPH
	ND_rank(root)[GD_minrank(subg) - 1].valid = FALSE;
#else /* WITH_CGRAPH */
	GD_rank(root)[GD_minrank(subg) - 1].valid = FALSE;
#endif /* WITH_CGRAPH */
    for (r = GD_minrank(subg); r <= GD_maxrank(subg); r++) {
	d = GD_rank(subg)[r].n;
#ifndef WITH_CGRAPH
	ipos = pos = GD_rankleader(subg)[r]->u.order;
#else /* WITH_CGRAPH */
	ipos = pos = ND_order(GD_rankleader(subg)[r]);
#endif /* WITH_CGRAPH */
	make_slots(root, r, pos, d);
	for (i = 0; i < GD_rank(subg)[r].n; i++) {
#ifndef WITH_CGRAPH
	    v = ND_rank(root)[r].v[pos] = GD_rank(subg)[r].v[i];
#else /* WITH_CGRAPH */
	    v = GD_rank(root)[r].v[pos] = GD_rank(subg)[r].v[i];
#endif /* WITH_CGRAPH */
	    ND_order(v) = pos++;
#ifndef WITH_CGRAPH
	    v->graph = subg->root;
#else /* WITH_CGRAPH */
	/* real nodes automatically have v->root = root graph */
	    if (ND_node_type(v) == VIRTUAL)
		v->root = root;
#endif /* WITH_CGRAPH */
	    delete_fast_node(subg, v);
	    fast_node(agroot(subg), v);
	    GD_n_nodes(agroot(subg))++;
	}
#ifndef WITH_CGRAPH
	GD_rank(subg)[r].v = ND_rank(root)[r].v + ipos;
	ND_rank(root)[r].valid = FALSE;
#else /* WITH_CGRAPH */
	GD_rank(subg)[r].v = GD_rank(root)[r].v + ipos;
	GD_rank(root)[r].valid = FALSE;
#endif /* WITH_CGRAPH */
    }
    if (r < GD_maxrank(root))
	GD_rank(root)[r].valid = FALSE;
    GD_expanded(subg) = TRUE;
}
Example #8
0
static bool samedir(edge_t * e, edge_t * f)
{
    edge_t *e0, *f0;

    for (e0 = e; ED_edge_type(e0) != NORMAL; e0 = ED_to_orig(e0));
    for (f0 = f; ED_edge_type(f0) != NORMAL; f0 = ED_to_orig(f0));
    if (ED_conc_opp_flag(e0))
	return FALSE;
    if (ED_conc_opp_flag(f0))
	return FALSE;
    return ((ND_rank(f0->tail) - ND_rank(f0->head))
	    * (ND_rank(e0->tail) - ND_rank(e0->head)) > 0);
}
Example #9
0
/* constrainY:
 * See constrainX.
 */
static void constrainY(graph_t* g, nitem* nlist, int nnodes, intersectfn ifn,
                       int ortho)
{
    Dt_t *list = dtopen(&constr, Dtobag);
    nitem *p = nlist;
    graph_t *cg;
    int i;

    for (i = 0; i < nnodes; i++) {
	p->val = p->pos.y;
	dtinsert(list, p);
	p++;
    }
    if (ortho)
	cg = mkConstraintG(g, list, ifn, distY);
    else
	cg = mkNConstraintG(g, list, ifn, distY);
    rank(cg, 2, INT_MAX);
#ifdef DEBUG
    {
	Agsym_t *mlsym = agedgeattr(cg, "minlen", "");
	Agsym_t *rksym = agnodeattr(cg, "rank", "");
	char buf[100];
	node_t *n;
	edge_t *e;
	for (n = agfstnode(cg); n; n = agnxtnode(cg, n)) {
	    sprintf(buf, "%d", ND_rank(n));
	    agxset(n, rksym->index, buf);
	    for (e = agfstedge(cg, n); e; e = agnxtedge(cg, e, n)) {
		sprintf(buf, "%d", ED_minlen(e));
		agxset(e, mlsym->index, buf);
	    }
	}
    }
#endif

    p = nlist;
    for (i = 0; i < nnodes; i++) {
	int newpos, oldpos, delta;
	oldpos = p->pos.y;
	newpos = ND_rank(p->cnode);
	delta = newpos - oldpos;
	p->pos.y = newpos;
	p->bb.LL.y += delta;
	p->bb.UR.y += delta;
	p++;
    }

    closeGraph(cg);
    dtclose(list);
}
Example #10
0
/* bind/construct representative of an external endpoint to a model graph */
static rep_t model_extnode(Agraph_t *model, Agnode_t *orig)
{
	Agnode_t	*v;
	rep_t		rep;

	rep = association(model,orig);
	if (rep.type) return rep;

	/* assume endpoint is represented by one node, even if orig is multi-rank */
	rep.p = v = agnode(model,orig->name);
	rep.type = EXTNODE;
	ND_rank(v) = ND_rank(orig);	/* should be ND_rank(orig)+ranksize(orig)? */
	associate(model,orig,rep);
	return rep;
}
Example #11
0
static int presort_cmpf(const void *arg0, const void *arg1)
{
	Agnode_t	*n0, *n1;
	Agraph_t	*c0, *c1;

	n0 = *(Agnode_t**)arg0;
	n1 = *(Agnode_t**)arg1;
	c0 = ND_cluster(n0);
	c1 = ND_cluster(n1);
	if (c0 == c1) return 0;
	assert(ND_rank(n0) == ND_rank(n1));
	n0 = GD_skel(c0)->v[ND_rank(n0)];
	n1 = GD_skel(c1)->v[ND_rank(n1)];
	return ND_order(n0) - ND_order(n1);
}
Example #12
0
void fastgr(graph_t * g)
{
    int i, j;
    node_t *n, *w;
    edge_t *e, *f;

    for (n = GD_nlist(g); n; n = ND_next(n)) {
	fprintf(stderr, "%s %d: (", NAME(n), ND_rank(n));
	for (i = 0; e = ND_out(n).list[i]; i++) {
	    fprintf(stderr, " %s:%d", NAME(e->head), ED_count(e));
	    w = e->head;
	    if (g == g->root) {
		for (j = 0; f = ND_in(w).list[j]; j++)
		    if (e == f)
			break;
		assert(f != NULL);
	    }
	}
	fprintf(stderr, " ) (");
	for (i = 0; e = ND_in(n).list[i]; i++) {
	    fprintf(stderr, " %s:%d", NAME(e->tail), ED_count(e));
	    w = e->tail;
	    if (g == g->root) {
		for (j = 0; f = ND_out(w).list[j]; j++)
		    if (e == f)
			break;
		assert(f != NULL);
	    }
	}
	fprintf(stderr, " )\n");
    }
}
Example #13
0
/* constrainX:
 * Create the X constrains and solve. We use a linear objective function
 * (absolute values rather than squares), so we can reuse network simplex.
 * The constraints are encoded as a dag with edges having a minimum length.
 */
static void constrainX(graph_t* g, nitem* nlist, int nnodes, intersectfn ifn,
                       int ortho)
{
    Dt_t *list = dtopen(&constr, Dtobag);
    nitem *p = nlist;
    graph_t *cg;
    int i;

    for (i = 0; i < nnodes; i++) {
	p->val = p->pos.x;
	dtinsert(list, p);
	p++;
    }
    if (ortho)
	cg = mkConstraintG(g, list, ifn, distX);
    else
	cg = mkNConstraintG(g, list, ifn, distX);
    rank(cg, 2, INT_MAX);

    p = nlist;
    for (i = 0; i < nnodes; i++) {
	int newpos, oldpos, delta;
	oldpos = p->pos.x;
	newpos = ND_rank(p->cnode);
	delta = newpos - oldpos;
	p->pos.x = newpos;
	p->bb.LL.x += delta;
	p->bb.UR.x += delta;
	p++;
    }

    closeGraph(cg);
    dtclose(list);
}
Example #14
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;
}
Example #15
0
static void model_edge(Agraph_t *model, Agedge_t *orig)
{
	Agedge_t	*e;
	Agnode_t	*low, *high, *u, *v;
	port_t		lowport, highport;
	vpath_t		*path;
	rep_t			rep;
	int				i;

	rep = association(model,orig);
	if (rep.type == 0) {
		low = orig->tail; high = orig->head;
		getlowhigh(&low,&high);
		u = association(model,low).p; assert(u);
		v = association(model,high).p; assert(v);
		path = newpath(model,u,ND_rank(low),v,ND_rank(high));
		rep.type = PATH;
		rep.p = path;
		associate(model,orig,rep);
	}
	else path = rep.p;

	/* merge the attributes of orig */
	for (i = path->low; i < path->high; i++) {
		e = path->e[i];
		ED_xpenalty(e) += ED_xpenalty(orig);
		ED_weight(e) += ED_weight(orig);
	}

	/* deal with ports.  note that ends could be swapped! */
	if (ND_rank(orig->tail) <= ND_rank(orig->head)) {
		lowport = ED_tailport(orig);
		highport = ED_headport(orig);
	}
	else {
		highport = ED_tailport(orig);
		lowport = ED_headport(orig);
	}
	if (lowport.defined)
		path->avgtailport = ((path->weight * path->avgtailport) + ED_weight(orig) * lowport.p.x) / (path->weight + ED_weight(orig));
	if (highport.defined)
		path->avgheadport = ((path->weight * path->avgheadport) + ED_weight(orig) * highport.p.x) / (path->weight + ED_weight(orig));
	path->weight += ED_weight(orig);
}
Example #16
0
/* swaps two nodes in the same level */
static void exchange(Agraph_t *g, Agnode_t *u, Agnode_t *v)
{
	rank_t	*r;
	int			ui,vi,rank;

	assert(ND_rank(u) == ND_rank(v));
	rank = ND_rank(u);
	r = &GD_rank(g)[rank];
	ui = ND_order(u);
	vi = ND_order(v);
	ND_order(v) = ui;
	ND_order(u) = vi;
	r->v[ND_order(u)] = u;
	r->v[ND_order(v)] = v;
	r->crossing_cache.valid = FALSE;
	r->changed = TRUE;
	r->candidate = TRUE;	/* old dot had this.  i have qualms. sn */
	invalidate(g,rank);
}
Example #17
0
static void install(Agraph_t *g, Agnode_t *n)
{
	int				rank;
	rank_t		*r;

	rank = ND_rank(n);
	r = &GD_rank(g)[rank];
	r->v[r->n] = n;
	ND_order(n) = r->n++;
}
Example #18
0
static void countup(Agraph_t *g, rank_t *globr)
{
	Agnode_t	*n;
	Agedge_t	*e;
	int				r0, r1, low, high, i;

	for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
			for (i = 0; i < ND_ranksize(n); i++)
				globr[ND_rank(n)+i].n += 1;
			for (e = agfstout(g,n); e; e = agnxtout(g,e)) {
				r0 = ND_rank(e->tail);
				r1 = ND_rank(e->head);
				low = MIN(r0,r1);
				high = MAX(r0,r1);
				for (i = low + 1; i < high; i++)
					globr[i].n += 1;
			}
	}
}
Example #19
0
static node_t*
map_interclust_node(node_t * n)
{
    node_t *rv;

#ifndef WITH_CGRAPH
    if ((ND_clust(n) == NULL) || (ND_clust(n)->u.expanded))
#else /* WITH_CGRAPH */
    if ((ND_clust(n) == NULL) || (  GD_expanded(ND_clust(n))) )
#endif /* WITH_CGRAPH */
	rv = n;
    else
#ifndef WITH_CGRAPH
	rv = ND_clust(n)->u.rankleader[ND_rank(n)];
#else /* WITH_CGRAPH */
	rv = GD_rankleader(ND_clust(n))[ND_rank(n)];
#endif /* WITH_CGRAPH */
    return rv;
}
Example #20
0
/* setSizes:
 * Use rankings to determine cell dimensions. The rank values
 * give the coordinate, so to get the width/height, we have
 * to subtract the previous value.
 */
void setSizes(htmltbl_t * tbl, graph_t * rowg, graph_t * colg)
{
    int i;
    node_t *n;
    int prev;

    prev = 0;
    n = GD_nlist(rowg);
    for (i = 0, n = ND_next(n); n; i++, n = ND_next(n)) {
	tbl->heights[i] = ND_rank(n) - prev;
	prev = ND_rank(n);
    }
    prev = 0;
    n = GD_nlist(colg);
    for (i = 0, n = ND_next(n); n; i++, n = ND_next(n)) {
	tbl->widths[i] = ND_rank(n) - prev;
	prev = ND_rank(n);
    }

}
Example #21
0
/* interpolate_zcoord:
 * Given 2 points in 3D p = (fst.x,fst.y,fstz) and q = (snd.x, snd.y, sndz),
 * and a point p1 in the xy plane lying on the line segment connecting 
 * the projections of the p and q, find the z coordinate of p1 when it
 * is projected up onto the segment (p,q) in 3-space. 
 *
 * Why the special case for ranks? Is the arithmetic really correct?
 */
static double 
interpolate_zcoord(GVJ_t *job, pointf p1, pointf fst, double fstz, pointf snd, double sndz)
{
    obj_state_t *obj = job->obj;
    edge_t *e = obj->u.e;
    double len, d, rv;

    if (fstz == sndz)
	return fstz;
    if (ND_rank(e->tail) != ND_rank(e->head)) {
	if (snd.y == fst.y)
	    rv = (fstz + sndz) / 2.0;
	else
	    rv = fstz + (sndz - fstz) * (p1.y - fst.y) / (snd.y - fst.y);
    } 
    else {
	len = DIST(fst, snd);
	d = DIST(p1, fst)/len;
	rv = fstz + d*(sndz - fstz);
    }
    return rv;
}
Example #22
0
/* bind/construct representative of an internal node in a model graph */
static rep_t model_intnode(Agraph_t *model, Agnode_t *orig)
{
	int				nr;
	rep_t			rep;
	Agnode_t	*v;
	
	rep = association(model,orig);
	if (rep.type) return rep;
	
	nr = ND_ranksize(orig);
	if (nr <= 1) {			/* simple case */
		v = rep.p = agnode(model,orig->name);
		rep.type = NODE;
		ND_rank(v) = ND_rank(orig);
	}
	else {							/* multi-rank node case */
		rep.p = newpath(model,NILnode,ND_rank(orig),NILnode,ND_rank(orig)+nr-1);
		rep.type = TALLNODE;
	}
	associate(model,orig,rep);
	return rep;
}
Example #23
0
static void
cluster_leader(graph_t * clust)
{
    node_t *leader, *n;
    int maxrank = 0;

    /* find number of ranks and select a leader */
    leader = NULL;
    for (n = GD_nlist(clust); n; n = ND_next(n)) {
	if ((ND_rank(n) == 0) && (ND_node_type(n) == NORMAL))
	    leader = n;
	if (maxrank < ND_rank(n))
	    maxrank = ND_rank(n);
    }
    assert(leader != NULL);
    GD_leader(clust) = leader;

    for (n = agfstnode(clust); n; n = agnxtnode(clust, n)) {
	assert((ND_UF_size(n) <= 1) || (n == leader));
	UF_union(n, leader);
	ND_ranktype(n) = CLUSTER;
    }
}
Example #24
0
void
setRanks (graph_t* g, attrsym_t* lsym)
{
    node_t* n;
    char*   s;
    char*   ep;
    long    v;

    for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
	s = agxget (n, lsym->index);
	v = strtol (s, &ep, 10);
	if (ep == s)
	    agerr(AGWARN, "no level attribute for node \"%s\"\n", n->name);
	ND_rank(n) = v;
    }
}
Example #25
0
static int left2right(Agraph_t *g, node_t *v, node_t *w)
{
    int         rv;

#ifdef NOTDEF
    adjmatrix_t *M;
    M = GD_rank(g)[ND_rank(v)].flat;
    if (M == NULL) rv = FALSE;
    else {
        if (GD_flip(g)) {node_t *t = v; v = w; w = t;}
        rv = ELT(M,flatindex(v),flatindex(w));
    }
#else
		rv = FALSE;
#endif
    return rv;
}
Example #26
0
/* mkMCGraph:
 * Clone original graph. We only need the nodes, edges and clusters.
 * Copy
 */
Agraph_t* 
mkMCGraph (Agraph_t* g)
{
    Agnode_t* t;
    Agnode_t* newt;
    Agnode_t* newh;
    Agedge_t* e;
    Agedge_t* newe;
    Agraph_t* sg;
    edgepair_t* data;
    edgepair_t* ep;
    Agraph_t* newg = agopen (agnameof(g), g->desc, 0);
    Dt_t* emap = dtopen (&edgepair, Dtoset);;
    data = N_NEW(agnedges(g), edgepair_t);
    ep = data;

    for (t = agfstnode(g); t; t = agnxtnode(g, t)) {
	newt = mkMCNode (newg, STDNODE, agnameof(t));
	assert(newt);
        MND_orig(newt) = t;
        MND_rank(newt) = ND_rank(t);
    }

    for (t = agfstnode(g); t; t = agnxtnode(g, t)) {
        newt = agnode (newg, agnameof(t), 0);
	for (e = agfstout(g, t); e; e = agnxtout(g, e)) {
	    newh = agnode (newg, agnameof(aghead(e)), 0);
	    assert(newh);
            newe = mkMCEdge (newg, newt, newh, agnameof (e), NORMAL, e); 
	    assert(newe);
	    ep->key = e;
	    ep->val = newe;
	    dtinsert (emap, ep++);
	}
    }

    for (sg = agfstsubg(g); sg; sg = agnxtsubg(sg)) {
	cloneSubg(newg, sg, emap);
    }

    dtclose (emap);
    free (data);

    return newg;
}
Example #27
0
static void
remove_from_rank (Agraph_t * g, Agnode_t* n)
{
    Agnode_t* v = NULL;
    int j, rk = ND_rank(n);

    for (j = 0; j < GD_rank(g)[rk].n; j++) {
	v = GD_rank(g)[rk].v[j];
	if (v == n) {
	    for (j++; j < GD_rank(g)[rk].n; j++) {
		GD_rank(g)[rk].v[j-1] = GD_rank(g)[rk].v[j];
	    }
	    GD_rank(g)[rk].n--;
	    break;
	}
    }
    assert (v == n);  /* if found */
}
Example #28
0
static void
attach_phase_attrs (Agraph_t * g, int maxphase)
{
    Agsym_t* rk = agnodeattr(g,"rank","");
    Agsym_t* order = agnodeattr(g,"order","");
    Agnode_t* n;
    char buf[BUFSIZ];

    for (n = agfstnode(g); n; n = agnxtnode(g,n)) {
	if (maxphase >= 1) {
	    sprintf(buf, "%d", ND_rank(n));
	    ag_xset(n,rk,buf);
	}
	if (maxphase >= 2) {
	    sprintf(buf, "%d", ND_order(n));
	    ag_xset(n,order,buf);
	}
    }
}
Example #29
0
static void restorebest(graph_t *g)
{
	Agnode_t	*n;
	int			i;

	for (i = GD_minrank(g); i <= GD_maxrank(g); i++) 
		GD_rank(g)[i].changed = FALSE;
	for (n = agfstnode(g); n; n = agnxtnode(g,n))  {
		if (ND_order(n) != ND_saveorder(n)) {
			invalidate(g,ND_rank(n));
			GD_rank(g)[i].changed = TRUE;
			ND_order(n) = ND_saveorder(n);
		}
	}
	for (i = GD_minrank(g); i <= GD_maxrank(g); i++)  {
		if (GD_rank(g)[i].changed)
			qsort(GD_rank(g)[i].v,GD_rank(g)[i].n,sizeof(Agnode_t*),ND_order_cmpf);
	}
}
Example #30
0
/* 
 * Assigns ranks of non-leader nodes.
 * Expands same, min, max rank sets.
 * Leaf sets and clusters remain merged.
 * Sets minrank and maxrank appropriately.
 */
static void expand_ranksets(graph_t * g, aspect_t* asp)
{
    int c;
    node_t *n, *leader;

    if ((n = agfstnode(g))) {
	GD_minrank(g) = MAXSHORT;
	GD_maxrank(g) = -1;
	while (n) {
	    leader = UF_find(n);
	    /* The following works because ND_rank(n) == 0 if n is not in a
	     * cluster, and ND_rank(n) = the local rank offset if n is in
	     * a cluster. */
	    if ((leader != n) && (!asp || (ND_rank(n) == 0)))
		ND_rank(n) += ND_rank(leader);

	    if (GD_maxrank(g) < ND_rank(n))
		GD_maxrank(g) = ND_rank(n);
	    if (GD_minrank(g) > ND_rank(n))
		GD_minrank(g) = ND_rank(n);

	    if (ND_ranktype(n) && (ND_ranktype(n) != LEAFSET))
		UF_singleton(n);
	    n = agnxtnode(g, n);
	}
	if (g == dot_root(g)) {
	    if (CL_type == LOCAL) {
		for (c = 1; c <= GD_n_cluster(g); c++)
		    set_minmax(GD_clust(g)[c]);
	    } else {
		find_clusters(g);
	    }
	}
    } else {
	GD_minrank(g) = GD_maxrank(g) = 0;
    }
}