#define ELT(M,i,j) (M->data[((i)*M->ncols)+(j)])
-static void
-init_mccomp(graph_t * g, int c)
+static void init_mccomp(graph_t * g, int c)
{
int r;
return (ND_clust(e->tail) != ND_clust(e->head));
}
-static void
-do_ordering(graph_t * g, int outflag)
+static void do_ordering(graph_t * g, int outflag)
{
int i, ne;
node_t *n, *u, *v;
/* ordered_edges:
* handle case where graph specifies edge ordering
*/
-static void
-ordered_edges(graph_t * g)
+static void ordered_edges(graph_t * g)
{
char *ordering;
}
}
-static int
-mincross_clust(graph_t * par, graph_t * g)
+static int mincross_clust(graph_t * par, graph_t * g)
{
int c, nc;
return nc;
}
-static int
-left2right(graph_t * g, node_t * v, node_t * w)
+static int left2right(graph_t * g, node_t * v, node_t * w)
{
adjmatrix_t *M;
int rv;
return rv;
}
-static int
-in_cross(node_t * v, node_t * w)
+static int in_cross(node_t * v, node_t * w)
{
register edge_t **e1, **e2;
register int inv, cross = 0, t;
return cross;
}
-static int
-out_cross(node_t * v, node_t * w)
+static int out_cross(node_t * v, node_t * w)
{
register edge_t **e1, **e2;
register int inv, cross = 0, t;
}
-static void
-exchange(node_t * v, node_t * w)
+static void exchange(node_t * v, node_t * w)
{
int vi, wi, r;
GD_rank(Root)[r].v[vi] = w;
}
-static int
-transpose_step(graph_t * g, int r, int reverse)
+static int transpose_step(graph_t * g, int r, int reverse)
{
int i, c0, c1, rv;
node_t *v, *w;
return rv;
}
-static void
-transpose(graph_t * g, int reverse)
+static void transpose(graph_t * g, int reverse)
{
int r, delta;
}
/* merges the connected components of g */
-static void
-merge_components(graph_t * g)
+static void merge_components(graph_t * g)
{
int c;
node_t *u, *v;
ND_order(v) = i;
if (ND_flat_out(v).list) {
for (j = 0; (e = ND_flat_out(v).list[j]); j++)
- if ((ED_edge_type(e) == FLATORDER) ||
- (ED_edge_type(e) == REVERSED)) {
+ if (ED_edge_type(e) == FLATORDER) {
delete_flat_edge(e);
free(e);
j--;
return rv;
}
-static int
-is_a_normal_node_of(graph_t * g, node_t * v)
+static int is_a_normal_node_of(graph_t * g, node_t * v)
{
return ((ND_node_type(v) == NORMAL) && agcontains(g, v));
}
-static int
-is_a_vnode_of_an_edge_of(graph_t * g, node_t * v)
+static int is_a_vnode_of_an_edge_of(graph_t * g, node_t * v)
{
if ((ND_node_type(v) == VIRTUAL)
&& (ND_in(v).size == 1) && (ND_out(v).size == 1)) {
return FALSE;
}
-static int
-inside_cluster(graph_t * g, node_t * v)
+static int inside_cluster(graph_t * g, node_t * v)
{
return (is_a_normal_node_of(g, v) | is_a_vnode_of_an_edge_of(g, v));
}
GlobalMaxRank = GD_maxrank(g);
}
-void flat_rev(Agraph_t *g, Agedge_t *e)
+void flat_rev(Agraph_t * g, Agedge_t * e)
{
int j;
Agedge_t *rev;
elist_append(e, ND_other(e->tail));
} else {
rev = new_virtual_edge(e->head, e->tail, e);
- ED_edge_type(rev) = REVERSED;
+ if (ED_edge_type(e) == FLATORDER)
+ ED_edge_type(rev) = FLATORDER;
+ else
+ ED_edge_type(rev) = REVERSED;
ED_label(rev) = ED_label(e);
flat_edge(g, rev);
}
i--;
if (ED_edge_type(e) == FLATORDER)
continue;
- flat_rev(g,e);
+ flat_rev(g, e);
} else {
assert(flatindex(e->head) < M->nrows);
assert(flatindex(e->tail) < M->ncols);
* Allocate rank structure, determining number of nodes per rank.
* Note that no nodes are put into the structure yet.
*/
-void
-allocate_ranks(graph_t * g)
+void allocate_ranks(graph_t * g)
{
int r, low, high, *cn;
node_t *n;
GD_rank(g)[r].an = GD_rank(g)[r].n = cn[r];
GD_rank(g)[r].av = GD_rank(g)[r].v = N_NEW(cn[r] + 1, node_t *);
}
- free (cn);
+ free(cn);
}
/* install a node at the current right end of its rank */
}
#endif
-for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
- GD_rank(g)[i].n = 0;
-
-for (n = GD_nlist(g); n; n = ND_next(n)) {
- otheredges = ((pass == 0) ? ND_in(n).list : ND_out(n).list);
- if (otheredges[0] != NULL)
- continue;
- if (MARK(n) == FALSE) {
- MARK(n) = TRUE;
- enqueue(q, n);
- while ((n0 = dequeue(q))) {
- if (ND_ranktype(n0) != CLUSTER) {
- install_in_rank(g, n0);
- enqueue_neighbors(q, n0, pass);
- } else {
- install_cluster(g, n0, pass, q);
+ for (i = GD_minrank(g); i <= GD_maxrank(g); i++)
+ GD_rank(g)[i].n = 0;
+
+ for (n = GD_nlist(g); n; n = ND_next(n)) {
+ otheredges = ((pass == 0) ? ND_in(n).list : ND_out(n).list);
+ if (otheredges[0] != NULL)
+ continue;
+ if (MARK(n) == FALSE) {
+ MARK(n) = TRUE;
+ enqueue(q, n);
+ while ((n0 = dequeue(q))) {
+ if (ND_ranktype(n0) != CLUSTER) {
+ install_in_rank(g, n0);
+ enqueue_neighbors(q, n0, pass);
+ } else {
+ install_cluster(g, n0, pass, q);
+ }
}
}
}
-}
-if (dequeue(q))
- agerr(AGERR, "surprise\n");
-for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
- GD_rank(Root)[i].valid = FALSE;
- if (GD_flip(g) && (GD_rank(g)[i].n > 0)) {
- int n, ndiv2;
- node_t **vlist = GD_rank(g)[i].v;
- n = GD_rank(g)[i].n - 1;
- ndiv2 = n / 2;
- for (j = 0; j <= ndiv2; j++)
- exchange(vlist[j], vlist[n - j]);
+ if (dequeue(q))
+ agerr(AGERR, "surprise\n");
+ for (i = GD_minrank(g); i <= GD_maxrank(g); i++) {
+ GD_rank(Root)[i].valid = FALSE;
+ if (GD_flip(g) && (GD_rank(g)[i].n > 0)) {
+ int n, ndiv2;
+ node_t **vlist = GD_rank(g)[i].v;
+ n = GD_rank(g)[i].n - 1;
+ ndiv2 = n / 2;
+ for (j = 0; j <= ndiv2; j++)
+ exchange(vlist[j], vlist[n - j]);
+ }
}
-}
-if ((g == g->root) && ncross(g) > 0)
- transpose(g, FALSE);
-free_queue(q);
+ if ((g == g->root) && ncross(g) > 0)
+ transpose(g, FALSE);
+ free_queue(q);
}
void enqueue_neighbors(nodequeue * q, node_t * n0, int pass)
{
-int i;
-edge_t *e;
-
-if (pass == 0) {
- for (i = 0; i < ND_out(n0).size; i++) {
- e = ND_out(n0).list[i];
- if ((MARK(e->head)) == FALSE) {
- MARK(e->head) = TRUE;
- enqueue(q, e->head);
+ int i;
+ edge_t *e;
+
+ if (pass == 0) {
+ for (i = 0; i < ND_out(n0).size; i++) {
+ e = ND_out(n0).list[i];
+ if ((MARK(e->head)) == FALSE) {
+ MARK(e->head) = TRUE;
+ enqueue(q, e->head);
+ }
}
- }
-} else {
- for (i = 0; i < ND_in(n0).size; i++) {
- e = ND_in(n0).list[i];
- if ((MARK(e->tail)) == FALSE) {
- MARK(e->tail) = TRUE;
- enqueue(q, e->tail);
+ } else {
+ for (i = 0; i < ND_in(n0).size; i++) {
+ e = ND_in(n0).list[i];
+ if ((MARK(e->tail)) == FALSE) {
+ MARK(e->tail) = TRUE;
+ enqueue(q, e->tail);
+ }
}
}
}
-}
/* construct nodes reachable from 'here' in post-order.
* This is the same as doing a topological sort in reverse order.
*/
static int postorder(graph_t * g, node_t * v, node_t ** list, int r)
{
-edge_t *e;
-int i, cnt = 0;
-
-MARK(v) = TRUE;
-if (ND_flat_out(v).size > 0) {
- for (i = 0; (e = ND_flat_out(v).list[i]); i++) {
- if (ED_weight(e) == 0) continue;
- if ((ND_node_type(e->head) == NORMAL) &
- (NOT(agcontains(g, e->head))))
- continue;
- if (ND_clust(e->head) != ND_clust(e->tail))
- continue;
+ edge_t *e;
+ int i, cnt = 0;
+
+ MARK(v) = TRUE;
+ if (ND_flat_out(v).size > 0) {
+ for (i = 0; (e = ND_flat_out(v).list[i]); i++) {
+ if (ED_weight(e) == 0)
+ continue;
+ if ((ND_node_type(e->head) == NORMAL) &
+ (NOT(agcontains(g, e->head))))
+ continue;
+ if (ND_clust(e->head) != ND_clust(e->tail))
+ continue;
- if (MARK(e->head) == FALSE)
- cnt += postorder(g, e->head, list + cnt, r);
+ if (MARK(e->head) == FALSE)
+ cnt += postorder(g, e->head, list + cnt, r);
+ }
}
-}
-assert(ND_rank(v) == r);
-list[cnt++] = v;
-return cnt;
+ assert(ND_rank(v) == r);
+ list[cnt++] = v;
+ return cnt;
}
static void flat_reorder(graph_t * g)
{
-int i, j, r, pos, n_search, local_in_cnt, local_out_cnt;
-node_t *v, **left, **right, *t;
-node_t **temprank = NULL;
-edge_t *flat_e, *e;
-
-if (GD_has_flat_edges(g) == FALSE)
- return;
-for (r = GD_minrank(g); r <= GD_maxrank(g); r++) {
- for (i = 0; i < GD_rank(g)[r].n; i++)
- MARK(GD_rank(g)[r].v[i]) = FALSE;
- temprank = ALLOC(i + 1, temprank, node_t *);
- pos = 0;
- for (i = 0; i < GD_rank(g)[r].n; i++) {
- v = GD_rank(g)[r].v[i];
+ int i, j, r, pos, n_search, local_in_cnt, local_out_cnt;
+ node_t *v, **left, **right, *t;
+ node_t **temprank = NULL;
+ edge_t *flat_e, *e;
- local_in_cnt = local_out_cnt = 0;
- for (j = 0; j < ND_flat_in(v).size; j++) {
- flat_e = ND_flat_in(v).list[j];
- if ((ED_weight(flat_e) > 0) && (inside_cluster(g, flat_e->tail)))
- local_in_cnt++;
- }
- for (j = 0; j < ND_flat_out(v).size; j++) {
- flat_e = ND_flat_out(v).list[j];
- if ((ED_weight(flat_e) > 0) && (inside_cluster(g, flat_e->head)))
- local_out_cnt++;
- }
- if ((local_in_cnt == 0) && (local_out_cnt == 0))
- temprank[pos++] = v;
- else {
- if ((MARK(v) == FALSE) && (local_in_cnt == 0)) {
- left = temprank + pos;
- n_search = postorder(g, v, left, r);
- if (GD_flip(g) == FALSE) {
- right = left + n_search - 1;
- while (left < right) {
- t = *left;
- *left = *right;
- *right = t;
- left++;
- right--;
+ if (GD_has_flat_edges(g) == FALSE)
+ return;
+ for (r = GD_minrank(g); r <= GD_maxrank(g); r++) {
+ for (i = 0; i < GD_rank(g)[r].n; i++)
+ MARK(GD_rank(g)[r].v[i]) = FALSE;
+ temprank = ALLOC(i + 1, temprank, node_t *);
+ pos = 0;
+ for (i = 0; i < GD_rank(g)[r].n; i++) {
+ v = GD_rank(g)[r].v[i];
+
+ local_in_cnt = local_out_cnt = 0;
+ for (j = 0; j < ND_flat_in(v).size; j++) {
+ flat_e = ND_flat_in(v).list[j];
+ if ((ED_weight(flat_e) > 0)
+ && (inside_cluster(g, flat_e->tail)))
+ local_in_cnt++;
+ }
+ for (j = 0; j < ND_flat_out(v).size; j++) {
+ flat_e = ND_flat_out(v).list[j];
+ if ((ED_weight(flat_e) > 0)
+ && (inside_cluster(g, flat_e->head)))
+ local_out_cnt++;
+ }
+ if ((local_in_cnt == 0) && (local_out_cnt == 0))
+ temprank[pos++] = v;
+ else {
+ if ((MARK(v) == FALSE) && (local_in_cnt == 0)) {
+ left = temprank + pos;
+ n_search = postorder(g, v, left, r);
+ if (GD_flip(g) == FALSE) {
+ right = left + n_search - 1;
+ while (left < right) {
+ t = *left;
+ *left = *right;
+ *right = t;
+ left++;
+ right--;
+ }
}
+ pos += n_search;
}
- pos += n_search;
}
}
- }
- if (pos) {
- for (i = 0; i < GD_rank(g)[r].n; i++) {
- v = GD_rank(g)[r].v[i] = temprank[i];
- ND_order(v) = i + (GD_rank(g)[r].v - GD_rank(Root)[r].v);
- }
-
+ if (pos) {
+ for (i = 0; i < GD_rank(g)[r].n; i++) {
+ v = GD_rank(g)[r].v[i] = temprank[i];
+ ND_order(v) = i + (GD_rank(g)[r].v - GD_rank(Root)[r].v);
+ }
+
/* nonconstraint flat edges must be made LR */
for (i = 0; i < GD_rank(g)[r].n; i++) {
- v = GD_rank(g)[r].v[i];
- if (ND_flat_out(v).list) {
- for (j = 0; (e = ND_flat_out(v).list[j]); j++) {
- if (ND_order(e->head) < ND_order(e->tail)) {
- /*assert(ED_weight(e) == 0);*/
- delete_flat_edge(e);
- j--;
- flat_rev(g,e);
- }
- }
+ v = GD_rank(g)[r].v[i];
+ if (ND_flat_out(v).list) {
+ for (j = 0; (e = ND_flat_out(v).list[j]); j++) {
+ if (ND_order(e->head) < ND_order(e->tail)) {
+ /*assert(ED_weight(e) == 0); */
+ delete_flat_edge(e);
+ j--;
+ flat_rev(g, e);
}
+ }
+ }
}
}
/* else do no harm! */
free(temprank);
}
-static void
-reorder(graph_t * g, int r, int reverse, int hasfixed)
+static void reorder(graph_t * g, int r, int reverse, int hasfixed)
{
int changed = 0, nelt;
boolean muststay, sawclust;
}
}
-static void
-mincross_step(graph_t * g, int pass)
+static void mincross_step(graph_t * g, int pass)
{
int r, other, first, last, dir;
int hasfixed, reverse;
transpose(g, NOT(reverse));
}
-static int
-local_cross(elist l, int dir)
+static int local_cross(elist l, int dir)
{
int i, j, is_out;
int cross = 0;
return cross;
}
-static int
-rcross(graph_t * g, int r)
+static int rcross(graph_t * g, int r)
{
static int *Count, C;
int top, bot, cross, max, i, k;
return count;
}
-static int
-ordercmpf(int *i0, int *i1)
+static int ordercmpf(int *i0, int *i1)
{
return (*i0) - (*i1);
}
* a.mval is > 0.
* Return true if n.mval is left -1, indicating a fixed node for sorting.
*/
-static int
-flat_mval(node_t * n)
+static int flat_mval(node_t * n)
{
int i;
edge_t *e, **fl;