00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "dot.h"
00024
00025
00026 int nonconstraint_edge(edge_t * e)
00027 {
00028 char *constr;
00029
00030 if (E_constr && (constr = agxget(e, E_constr->index))) {
00031 if (constr[0] && mapbool(constr) == FALSE)
00032 return TRUE;
00033 }
00034 return FALSE;
00035 }
00036
00037 static void
00038 interclust1(graph_t * g, node_t * t, node_t * h, edge_t * e)
00039 {
00040 node_t *v, *t0, *h0;
00041 int offset, t_len, h_len, t_rank, h_rank;
00042 edge_t *rt, *rh;
00043
00044 if (ND_clust(e->tail))
00045 t_rank = ND_rank(e->tail) - ND_rank(GD_leader(ND_clust(e->tail)));
00046 else
00047 t_rank = 0;
00048 if (ND_clust(e->head))
00049 h_rank = ND_rank(e->head) - ND_rank(GD_leader(ND_clust(e->head)));
00050 else
00051 h_rank = 0;
00052 offset = ED_minlen(e) + t_rank - h_rank;
00053 if (offset > 0) {
00054 t_len = 0;
00055 h_len = offset;
00056 } else {
00057 t_len = -offset;
00058 h_len = 0;
00059 }
00060
00061 v = virtual_node(g);
00062 ND_node_type(v) = SLACKNODE;
00063 t0 = UF_find(t);
00064 h0 = UF_find(h);
00065 rt = make_aux_edge(v, t0, t_len, CL_BACK * ED_weight(e));
00066 rh = make_aux_edge(v, h0, h_len, ED_weight(e));
00067 ED_to_orig(rt) = ED_to_orig(rh) = e;
00068 }
00069 void class1(graph_t * g)
00070 {
00071 node_t *n, *t, *h;
00072 edge_t *e, *rep;
00073
00074 mark_clusters(g);
00075 for (n = agfstnode(g); n; n = agnxtnode(g, n)) {
00076 for (e = agfstout(g, n); e; e = agnxtout(g, e)) {
00077
00078
00079 if (ED_to_virt(e))
00080 continue;
00081
00082
00083 if (nonconstraint_edge(e))
00084 continue;
00085
00086 t = UF_find(e->tail);
00087 h = UF_find(e->head);
00088
00089
00090 if (t == h)
00091 continue;
00092
00093
00094
00095 if (ND_clust(t) || ND_clust(h)) {
00096 interclust1(g, e->tail, e->head, e);
00097 continue;
00098 }
00099
00100 if ((rep = find_fast_edge(t, h)))
00101 merge_oneway(e, rep);
00102 else
00103 virtual_edge(t, h, e);
00104
00105 #ifdef NOTDEF
00106 if ((t == e->tail) && (h == e->head)) {
00107 if (rep = find_fast_edge(t, h))
00108 merge_oneway(e, rep);
00109 else
00110 virtual_edge(t, h, e);
00111 } else {
00112 f = agfindedge(g, t, h);
00113 if (f && (ED_to_virt(f) == NULL))
00114 rep = virtual_edge(t, h, f);
00115 else
00116 rep = find_fast_edge(t, h);
00117 if (rep)
00118 merge_oneway(e, rep);
00119 else
00120 virtual_edge(t, h, e);
00121 }
00122 #endif
00123 }
00124 }
00125 }
00126