static void unrep(edge_t * rep, edge_t * e) { ED_count(rep) -= ED_count(e); ED_xpenalty(rep) -= ED_xpenalty(e); ED_weight(rep) -= ED_weight(e); }
static void dot_init_edge(edge_t * e) { char *tailgroup, *headgroup; #ifdef WITH_CGRAPH agbindrec(e, "Agedgeinfo_t", sizeof(Agedgeinfo_t), TRUE); //graph custom data #endif /* WITH_CGRAPH */ common_init_edge(e); ED_weight(e) = late_double(e, E_weight, 1.0, 0.0); tailgroup = late_string(agtail(e), N_group, ""); headgroup = late_string(aghead(e), N_group, ""); ED_count(e) = ED_xpenalty(e) = 1; if (tailgroup[0] && (tailgroup == headgroup)) { ED_xpenalty(e) = CL_CROSS; ED_weight(e) *= 100; } if (nonconstraint_edge(e)) { ED_xpenalty(e) = 0; ED_weight(e) = 0; } ED_showboxes(e) = late_int(e, E_showboxes, 0, 0); ED_minlen(e) = late_int(e, E_minlen, 1, 0); }
/* new_virtual_edge: * Create and return a new virtual edge e attached to orig. * ED_to_orig(e) = orig * ED_to_virt(orig) = e if e is the first virtual edge attached. * orig might be an input edge, reverse of an input edge, or virtual edge */ edge_t *new_virtual_edge(node_t * u, node_t * v, edge_t * orig) { edge_t *e; e = NEW(edge_t); e->tail = u; e->head = v; ED_edge_type(e) = VIRTUAL; if (orig) { e->id = orig->id; ED_count(e) = ED_count(orig); ED_xpenalty(e) = ED_xpenalty(orig); ED_weight(e) = ED_weight(orig); ED_minlen(e) = ED_minlen(orig); if (e->tail == orig->tail) ED_tail_port(e) = ED_tail_port(orig); else if (e->tail == orig->head) ED_tail_port(e) = ED_head_port(orig); if (e->head == orig->head) ED_head_port(e) = ED_head_port(orig); else if (e->head == orig->tail) ED_head_port(e) = ED_tail_port(orig); if (ED_to_virt(orig) == NULL) ED_to_virt(orig) = e; ED_to_orig(e) = orig; } else ED_minlen(e) = ED_count(e) = ED_xpenalty(e) = ED_weight(e) = 1; return e; }
/* * defines ND_sortweight of each node in r0 w.r.t. r1 * returns... */ static boolean medians(Agraph_t *g, int r0, int r1) { static int *list; static int list_extent; int i,j,lm,rm,lspan,rspan; node_t *n,**v; edge_t *e; boolean hasfixed = FALSE; if (list_extent < GD_maxinoutdeg(g->root)) { list_extent = GD_maxinoutdeg(g->root); if (!list) list = realloc(list,sizeof(list[0])*list_extent); else list = realloc(list,sizeof(list[0])*list_extent); } v = GD_rank(g)[r0].v; for (i = leftmost(g,r0); i <= rightmost(g,r0); i++) { n = v[i]; j = 0; if (r1 > r0) for (e = agfstout(g,n); e; e = agnxtout(g,e)) {if (ED_xpenalty(e) > 0) list[j++] = VAL(e->head,ED_headport(e));} else for (e = agfstin(g,n); e; e = agnxtin(g,e)) {if (ED_xpenalty(e) > 0) list[j++] = VAL(e->tail,ED_tailport(e));} switch(j) { case 0: ND_sortweight(n) = -1; /* no neighbor - median undefined */ break; case 1: ND_sortweight(n) = list[0]; break; case 2: ND_sortweight(n) = (list[0] + list[1])/2; break; default: qsort(list,j,sizeof(int),int_cmpf); if (j % 2) ND_sortweight(n) = list[j/2]; else { /* weighted median */ rm = j/2; lm = rm - 1; rspan = list[j-1] - list[rm]; lspan = list[lm] - list[0]; if (lspan == rspan) ND_sortweight(n) = (list[lm] + list[rm])/2; else { int w = list[lm]*rspan + list[rm]*lspan; ND_sortweight(n) = w / (lspan + rspan); } } } } #ifdef NOTDEF /* this code was in the old mincross */ for (i = 0; i < GD_rank(g)[r0].n; i++) { n = v[i]; if ((ND_out(n).size == 0) && (ND_in(n).size == 0)) hasfixed |= flat_sortweight(n); } #endif return hasfixed; }
void basic_merge(edge_t *e, edge_t *rep) { if (ED_minlen(rep) < ED_minlen(e)) ED_minlen(rep) = ED_minlen(e); while (rep) { ED_count(rep) += ED_count(e); ED_xpenalty(rep) += ED_xpenalty(e); ED_weight(rep) += ED_weight(e); rep = ED_to_virt(rep); } }
static int in_cross(node_t *v,node_t *w) { register edge_t *e1,*e2; register int inv, cross = 0, t; for (e2 = agfstin(w->graph,w); e2; e2 = agnxtin(w->graph,e2)) { register int cnt = ED_xpenalty(e2); inv = ND_order(e2->tail); for (e1 = agfstin(v->graph,v); e1; e1 = agnxtin(v->graph,e1)) { t = ND_order(e1->tail) - inv; if ((t > 0) || ((t == 0) && (ED_tailport(e1).p.x > ED_tailport(e2).p.x))) cross += ED_xpenalty(e1) * cnt; } } return cross; }
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); }
static void dot_init_edge(edge_t * e) { char *tailgroup, *headgroup; common_init_edge(e); ED_weight(e) = late_double(e, E_weight, 1.0, 0.0); tailgroup = late_string(e->tail, N_group, ""); headgroup = late_string(e->head, N_group, ""); ED_count(e) = ED_xpenalty(e) = 1; if (tailgroup[0] && (tailgroup == headgroup)) { ED_xpenalty(e) = CL_CROSS; ED_weight(e) *= 100; } if (nonconstraint_edge(e)) { ED_xpenalty(e) = 0; ED_weight(e) = 0; } ED_showboxes(e) = late_int(e, E_showboxes, 0, 0); ED_minlen(e) = late_int(e, E_minlen, 1, 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)--; } }