void merge_ranks(graph_t* subg) { int i,d,r,pos,ipos; node_t *v; graph_t *root; root = subg->root; if (subg->u.minrank > 0) root->u.rank[subg->u.minrank-1].valid = FALSE; for (r = subg->u.minrank; r <= subg->u.maxrank; r++) { d = subg->u.rank[r].n; ipos = pos = subg->u.rankleader[r]->u.order; make_slots(root,r,pos,d); for (i = 0; i < subg->u.rank[r].n; i++) { v = root->u.rank[r].v[pos] = subg->u.rank[r].v[i]; v->u.order = pos++; v->graph = subg->root; delete_fast_node(subg,v); fast_node(subg->root,v); subg->root->u.n_nodes++; } subg->u.rank[r].v = root->u.rank[r].v + ipos; root->u.rank[r].valid = FALSE; } if (r < root->u.maxrank) root->u.rank[r].valid = FALSE; subg->u.expanded = TRUE; }
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; }
node_t *virtual_node(graph_t * g) { node_t *n; n = NEW(node_t); n->name = "virtual"; n->graph = g; ND_node_type(n) = VIRTUAL; ND_lw_i(n) = ND_rw_i(n) = 1; ND_ht_i(n) = 1; ND_UF_size(n) = 1; alloc_elist(4, ND_in(n)); alloc_elist(4, ND_out(n)); fast_node(g, n); GD_n_nodes(g)++; return n; }
void class2(graph_t* g) { int c; node_t *n,*t,*h; edge_t *e,*prev,*opp; g->u.nlist = NULL; g->u.n_nodes = 0; /* new */ mark_clusters(g); for (c = 1; c <= g->u.n_cluster; c++) build_skeleton(g,g->u.clust[c]); for (n = agfstnode(g); n; n = agnxtnode(g,n)) for (e = agfstout(g,n); e; e = agnxtout(g,e)) { if (e->head->u.weight_class <= 2) e->head->u.weight_class++; if (e->tail->u.weight_class <= 2) e->tail->u.weight_class++; } for (n = agfstnode(g); n; n = agnxtnode(g,n)) { if ((n->u.clust == NULL) && (n == UF_find(n))) {fast_node(g,n); g->u.n_nodes++;} prev = NULL; for (e = agfstout(g,n); e; e = agnxtout(g,e)) { /* already processed */ if (e->u.to_virt) continue; /* edges involving sub-clusters of g */ if (is_cluster_edge(e)) { /* following is new cluster multi-edge code */ if (mergeable(prev,e)) { if (prev->u.to_virt) { merge_chain(g,e,prev->u.to_virt,FALSE); other_edge(e); } else if (e->tail->u.rank == e->head->u.rank) { merge_oneway(e,prev); other_edge(e); } /* else is an intra-cluster edge */ continue; } interclrep(g,e); prev = e; continue; } /* merge multi-edges */ if (prev && (e->tail == prev->tail) && (e->head == prev->head)) { if (e->tail->u.rank == e->head->u.rank) { merge_oneway(e,prev); other_edge(e); continue; } if ((e->u.label == NULL) && (prev->u.label == NULL) && ports_eq(e,prev)) { if (Concentrate) e->u.edge_type = IGNORED; else{ merge_chain(g,e,prev->u.to_virt,TRUE); other_edge(e); } continue; } /* parallel edges with different labels fall through here */ } /* self edges */ if (e->tail == e->head) { other_edge(e); prev = e; continue; } t = UF_find(e->tail); h = UF_find(e->head); /* non-leader leaf nodes */ if ((e->tail != t) || (e->head != h)) { /* ### need to merge stuff */ continue; } /* flat edges */ if (e->tail->u.rank == e->head->u.rank) { flat_edge(g,e); prev = e; continue; } /* forward edges */ if (e->head->u.rank > e->tail->u.rank) { make_chain(g,e->tail,e->head,e); prev = e; continue; } /* backward edges */ else { /*other_edge(e);*/ if ((opp = agfindedge(g,e->head,e->tail))) { /* shadows a forward edge */ if (opp->u.to_virt == NULL) make_chain(g,opp->tail,opp->head,opp); if ((e->u.label == NULL) && (opp->u.label == NULL) && ports_eq(e,opp)) { if (Concentrate) { e->u.edge_type = IGNORED; opp->u.conc_opp_flag = TRUE; } else{ /* see above. this is getting out of hand */ other_edge(e); merge_chain(g,e,opp->u.to_virt,TRUE); } continue; } } make_chain(g,e->head,e->tail,e); prev = e; } } } /* since decompose() is not called on subgraphs */ if (g != g->root) { g->u.comp.list = ALLOC(1,g->u.comp.list,node_t*); g->u.comp.list[0] = g->u.nlist; }