void delete_flat_edge(edge_t * e) { assert(e != NULL); if (ED_to_orig(e) && ED_to_virt(ED_to_orig(e)) == e) ED_to_virt(ED_to_orig(e)) = NULL; zapinlist(&(ND_flat_out(e->tail)), e); zapinlist(&(ND_flat_in(e->head)), e); }
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]); }
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); }
/* 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; }
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; }
static void cleanup1(graph_t * g) { node_t *n; edge_t *e, *f; int c; for (c = 0; c < GD_comp(g).size; c++) { GD_nlist(g) = GD_comp(g).list[c]; for (n = GD_nlist(g); n; n = ND_next(n)) { renewlist(&ND_in(n)); renewlist(&ND_out(n)); ND_mark(n) = FALSE; } } for (n = agfstnode(g); n; n = agnxtnode(g, n)) { for (e = agfstout(g, n); e; e = agnxtout(g, e)) { f = ED_to_virt(e); /* Null out any other references to f to make sure we don't * handle it a second time. For example, parallel multiedges * share a virtual edge. */ if (f && (e == ED_to_orig(f))) { edge_t *e1, *f1; #ifndef WITH_CGRAPH for (e1 = agfstout(g, n); e1; e1 = agnxtout(g, e1)) { if (e != e1) { f1 = ED_to_virt(e1); if (f1 && (f == f1)) { ED_to_virt(e1) = NULL; } } } #else node_t *n1; for (n1 = agfstnode(g); n1; n1 = agnxtnode(g, n1)) { for (e1 = agfstout(g, n1); e1; e1 = agnxtout(g, e1)) { if (e != e1) { f1 = ED_to_virt(e1); if (f1 && (f == f1)) { ED_to_virt(e1) = NULL; } } } } free(f->base.data); #endif free(f); } ED_to_virt(e) = NULL; } } free(GD_comp(g).list); GD_comp(g).list = NULL; GD_comp(g).size = 0; }