/* clone_graph: * Create two copies of the argument graph * One is a subgraph, the other is an actual copy since we will be * adding edges to it. */ static Agraph_t* clone_graph(Agraph_t* ing, Agraph_t** xg) { Agraph_t* clone; Agraph_t* xclone; Agnode_t* n; Agnode_t* xn; Agnode_t* xh; Agedge_t* e; Agedge_t* xe; char gname[SMALLBUF]; static int id = 0; sprintf (gname, "_clone_%d", id++); clone = agsubg(ing, gname); sprintf (gname, "_clone_%d", id++); xclone = agopen(gname, ing->kind); for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) { aginsert (clone, n); xn = agnode (xclone, n->name); CLONE(n) = xn; } for(n = agfstnode(ing); n; n = agnxtnode(ing, n)) { xn = CLONE(n); for(e = agfstout(ing, n); e; e = agnxtout(ing, e)) { aginsert (clone, e); xh = CLONE(e->head); xe = agedge (xclone, xn, xh); ORIGE(xe) = e; DEGREE(xn) += 1; DEGREE(xh) += 1; } } *xg = xclone; #ifdef OLD clone = agopen("clone", root->kind); for(n = agfstnode(root); n; n = agnxtnode(root, n)) { cn = agnode(clone, n->name); ND_alg(cn) = DATA(n); BCDONE(cn) = 0; } for(n = agfstnode(root); n; n = agnxtnode(root, n)) { Agnode_t *t = agnode(clone, n); for(e = agfstout(root, n); e; e = agnxtout(root, e)) { Agnode_t *h = agnode(clone, e->head->name); agedge(clone, t, h); } } #endif return clone; }
/* find_pair_edges: */ static void find_pair_edges(Agraph_t * g, Agnode_t * n, Agraph_t * outg) { Agnode_t **neighbors_with; Agnode_t **neighbors_without; Agedge_t *e; Agedge_t *ep; Agedge_t *ex; Agnode_t *n1; Agnode_t *n2; int has_pair_edge; int diff; int has_pair_count = 0; int no_pair_count = 0; int node_degree; int edge_cnt = 0; node_degree = DEGREE(n); neighbors_with = N_GNEW(node_degree, Agnode_t *); neighbors_without = N_GNEW(node_degree, Agnode_t *); for (e = agfstedge(g, n); e; e = agnxtedge(g, e, n)) { n1 = e->head; if (n1 == n) n1 = e->tail; has_pair_edge = 0; for (ep = agfstedge(g, n); ep; ep = agnxtedge(g, ep, n)) { if (ep == e) continue; n2 = ep->head; if (n2 == n) n2 = ep->tail; ex = agfindedge(g, n1, n2); if (ex) { has_pair_edge = 1; if (n1 < n2) { /* count edge only once */ edge_cnt++; if (ORIGE(ex)) { agdelete(outg, ORIGE(ex)); ORIGE(ex) = 0; /* delete only once */ } } } } if (has_pair_edge) { neighbors_with[has_pair_count] = n1; has_pair_count++; } else { neighbors_without[no_pair_count] = n1; no_pair_count++; } } diff = node_degree - 1 - edge_cnt; if (diff > 0) { int mark; Agnode_t *hp; Agnode_t *tp; if (diff < no_pair_count) { for (mark = 0; mark < no_pair_count; mark += 2) { if ((mark + 1) >= no_pair_count) break; tp = neighbors_without[mark]; hp = neighbors_without[mark + 1]; agedge(g, tp, hp); DEGREE(tp)++; DEGREE(hp)++; diff--; } mark = 2; while (diff > 0) { tp = neighbors_without[0]; hp = neighbors_without[mark]; agedge(g, tp, hp); DEGREE(tp)++; DEGREE(hp)++; mark++; diff--; } } else if (diff == no_pair_count) { tp = neighbors_with[0]; for (mark = 0; mark < no_pair_count; mark++) { hp = neighbors_without[mark]; agedge(g, tp, hp); DEGREE(tp)++; DEGREE(hp)++; } } } free(neighbors_without); free(neighbors_with); }