22 static int init_graph(
graph_t *);
27 static void check_cycles(
graph_t * g);
30 #define LENGTH(e) (ND_rank(aghead(e)) - ND_rank(agtail(e)))
31 #define SLACK(e) (LENGTH(e) - ED_minlen(e))
32 #define SEQ(a,b,c) (((a) <= (b)) && ((b) <= (c)))
33 #define TREE_EDGE(e) (ED_tree_index(e) >= 0)
37 static int N_nodes, N_edges;
38 static int Minrank, Maxrank;
40 static int Search_size;
43 static elist Tree_edge;
45 static void add_tree_edge(
edge_t * e)
50 agerr(
AGERR,
"add_tree_edge: missing tree edge\n");
54 Tree_edge.
list[Tree_edge.
size++] = e;
64 agerr(
AGERR,
"add_tree_edge: empty outedge list\n");
72 agerr(
AGERR,
"add_tree_edge: empty inedge list\n");
88 for (j = 0; j <= i; j++)
95 for (j = 0; j <= i; j++)
128 for (i = 0; (e =
ND_in(v).list[i]); i++)
130 for (i = 0; (e =
ND_out(v).list[i]); i++) {
135 if (ctr != N_nodes) {
144 static edge_t *leave_edge(
void)
150 while (S_i < Tree_edge.
size) {
156 rv = Tree_edge.
list[S_i];
157 if (++cnt >= Search_size)
170 rv = Tree_edge.
list[S_i];
171 if (++cnt >= Search_size)
181 static int Low, Lim, Slack;
183 static void dfs_enter_outedge(
node_t * v)
188 for (i = 0; (e =
ND_out(v).list[i]); i++) {
192 if ((slack < Slack) || (Enter ==
NULL)) {
198 dfs_enter_outedge(
aghead(e));
200 for (i = 0; (e =
ND_tree_in(v).list[i]) && (Slack > 0); i++)
202 dfs_enter_outedge(
agtail(e));
205 static void dfs_enter_inedge(
node_t * v)
210 for (i = 0; (e =
ND_in(v).list[i]); i++) {
214 if ((slack < Slack) || (Enter ==
NULL)) {
220 dfs_enter_inedge(
agtail(e));
222 for (i = 0; (e =
ND_tree_out(v).list[i]) && (Slack > 0); i++)
224 dfs_enter_inedge(
aghead(e));
245 dfs_enter_outedge(v);
251 static void init_cutvalues(
void)
259 #define ND_subtree(n) (subtree_t*)ND_par(n)
260 #define ND_subtree_set(n,value) (ND_par(n) = (edge_t*)value)
278 for (i = 0; (e =
ND_in(v).list[i]); i++) {
282 rv += tight_subtree_search(
agtail(e),st);
285 for (i = 0; (e =
ND_out(v).list[i]); i++) {
289 rv += tight_subtree_search(
aghead(e),st);
300 rv->
size = tight_subtree_search(v,rv);
313 while (s0->
par && (s0->
par != s0)) {
324 for (r0 = s0; r0->
par && (r0->
par != r0); r0 = r0->
par);
325 for (r1 = s1; r1->
par && (r1->
par != r1); r1 = r1->
par);
326 if (r0 == r1)
return r0;
330 else if (r1->
size < r0->
size) r = r0;
339 #define INCIDENT(e,treeset) ((STsetFind(agtail(e),treeset)) != STsetFind(aghead(e),treeset))
347 if (best &&
SLACK(best) == 0)
return best;
348 for (i = 0; (e =
ND_out(v).list[i]); i++) {
350 if (
aghead(e) == from)
continue;
351 best = inter_tree_edge_search(
aghead(e),v,best);
354 if (STsetFind(
aghead(e)) != ts) {
355 if ((best == 0) || (
SLACK(e) <
SLACK(best))) best = e;
361 for (i = 0; (e =
ND_in(v).list[i]); i++) {
363 if (
agtail(e) == from)
continue;
364 best = inter_tree_edge_search(
agtail(e),v,best);
367 if (STsetFind(
agtail(e)) != ts) {
368 if ((best == 0) || (
SLACK(e) <
SLACK(best))) best = e;
393 if ((left < heap->size) && (elt[
left]->
size < elt[i]->
size)) smallest =
left;
395 if ((right < heap->size) && (elt[
right]->
size < elt[smallest]->
size)) smallest =
right;
400 elt[i] = elt[smallest];
401 elt[smallest] = temp;
407 }
while (i < heap->size);
419 for (i = heap->
size/2; i >= 0; i--)
445 for (i = 0; (e =
ND_tree_in(v).list[i]); i++) {
448 tree_adjust(w, v, delta);
453 tree_adjust(w, v, delta);
465 t0 = STsetFind(
agtail(e));
466 t1 = STsetFind(
aghead(e));
476 tree_adjust(t1->
rep,0,delta);
479 rv = STsetUnion(t0,t1);
490 int feasible_tree(
void)
495 int i, subtree_count = 0;
508 tree[subtree_count] = find_tight_subtree(n);
514 heap = STbuildheap(tree,subtree_count);
515 while (STheapsize(heap) > 1) {
516 tree0 = STextractmin(heap);
517 if (!(ee = inter_tree_edge(tree0))) {
521 tree1 = merge_trees(ee);
526 for (i = 0; i < subtree_count; i++) free(tree[i]);
564 static void rerank(
Agnode_t * v,
int delta)
597 rerank(
aghead(e), -delta);
602 rerank(
aghead(e), -delta);
609 if (treeupdate(
aghead(f),
agtail(f), cutvalue, 0) != lca) {
610 agerr(
AGERR,
"update: mismatched lca in treeupdates\n");
615 exchange_tree_edges(e, f);
619 static void scan_and_normalize(
void)
650 static void LR_balance(
void)
655 for (i = 0; i < Tree_edge.
size; i++) {
656 e = Tree_edge.
list[i];
665 rerank(
agtail(e), delta / 2);
667 rerank(
aghead(e), -delta / 2);
673 static void TB_balance(
void)
677 int i, low, high, choice, *nrank;
678 int inweight, outweight;
680 scan_and_normalize();
683 nrank =
N_NEW(Maxrank + 1,
int);
684 for (i = 0; i <= Maxrank; i++)
692 inweight = outweight = 0;
695 for (i = 0; (e =
ND_in(n).list[i]); i++) {
699 for (i = 0; (e =
ND_out(n).list[i]); i++) {
705 if (inweight == outweight) {
707 for (i = low + 1; i <= high; i++)
708 if (nrank[i] < nrank[choice])
721 static int init_graph(
graph_t * g)
728 N_nodes = N_edges = S_i = 0;
732 for (i = 0; (e =
ND_out(n).list[i]); i++)
744 for (i = 0; (e =
ND_in(n).list[i]); i++) {
754 for (i = 0; (e =
ND_out(n).list[i]); i++);
765 graphSize (
graph_t * g,
int* nn,
int* ne)
767 int i, nnodes, nedges;
774 for (i = 0; (e =
ND_out(n).list[i]); i++) {
796 int iter = 0, feasible;
797 char *ns =
"network simplex: ";
805 graphSize (g, &nn, &ne);
806 fprintf(stderr,
"%s %d nodes %d edges maxiter=%d balance=%d\n", ns,
807 nn, ne, maxiter, balance);
810 feasible = init_graph(g);
818 if (search_size >= 0)
819 Search_size = search_size;
827 if (feasible_tree()) {
831 while ((e = leave_edge())) {
835 if (
Verbose && (iter % 100 == 0)) {
836 if (iter % 1000 == 100)
838 fprintf(stderr,
"%d ", iter);
839 if (iter % 1000 == 0)
853 scan_and_normalize();
860 fprintf(stderr,
"%s%d nodes %d edges %d iter %.2f sec\n",
871 if ((s =
agget(g,
"searchsize")))
872 search_size = atoi(s);
876 return rank2 (g, balance, maxiter, search_size);
880 static void x_cutval(
edge_t * f)
896 for (i = 0; (e =
ND_out(v).list[i]); i++)
897 sum += x_val(e, v, dir);
898 for (i = 0; (e =
ND_in(v).list[i]); i++)
899 sum += x_val(e, v, dir);
966 lim = dfs_range(
aghead(e), e, lim);
969 lim = dfs_range(
agtail(e), e, lim);
988 fprintf(stderr,
"not a tight tree %p", e);
991 if ((n_cnt != Tree_node.
size) || (e_cnt != Tree_edge.
size))
992 fprintf(stderr,
"something missing\n");
995 void check_cutvalues(
void)
1011 int check_ranks(
void)
1024 fprintf(stderr,
"rank cost %d\n", cost);
1028 void checktree(
void)
1030 int i, n = 0, m = 0;
1039 for (i = 0; (e =
ND_tree_in(v).list[i]); i++)
1044 fprintf(stderr,
"%d %d %d\n", Tree_edge.
size, n, m);
1047 void check_fast_node(
node_t * n)
1051 while (nptr && nptr != n)
1056 static char* dump_node (
node_t* n)
1058 static char buf[50];
1061 sprintf(buf,
"%p", n);
1068 static void dump_graph (
graph_t* g)
1073 FILE* fp = fopen (
"ns.gv",
"w");
1074 fprintf (fp,
"digraph \"%s\" {\n",
agnameof(g));
1076 fprintf (fp,
" \"%s\"\n", dump_node(n));
1079 for (i = 0; (e =
ND_out(n).list[i]); i++) {
1080 fprintf (fp,
" \"%s\"", dump_node(n));
1082 fprintf (fp,
" -> \"%s\"\n", dump_node(w));
1086 fprintf (fp,
"}\n");
1100 for (i = 0; (e =
ND_out(n).list[i]); i++) {
1104 fprintf(stderr,
"cycle: last edge %lx %s(%lx) %s(%lx)\n",
1114 fprintf(stderr,
"unwind %lx %s(%lx)\n",
1117 if (x != n)
return x;
1118 fprintf(stderr,
"unwound to root\n");
1130 void check_cycles(
graph_t * g)
void s1(graph_t *, node_t *)
#define ALLOC(size, ptr, type)
int agerr(agerrlevel_t level, const char *fmt,...)
CGRAPH_API Agedge_t * agfstout(Agraph_t *g, Agnode_t *n)
void enqueue(nodequeue *q, node_t *n)
char * agget(void *obj, char *name)
CGRAPH_API Agraph_t * agraphof(void *obj)
CGRAPH_API Agnode_t * agtail(Agedge_t *e)
nodequeue * new_queue(int sz)
int rank(graph_t *g, int balance, int maxiter)
CGRAPH_API Agnode_t * agnxtnode(Agraph_t *g, Agnode_t *n)
CGRAPH_API Agnode_t * aghead(Agedge_t *e)
CGRAPH_API char * agnameof(void *)
#define ND_subtree_set(n, value)
struct subtree_s subtree_t
node_t * dequeue(nodequeue *q)
CGRAPH_API Agnode_t * agfstnode(Agraph_t *g)
void free_queue(nodequeue *q)
EXTERN unsigned char Verbose
int rank2(graph_t *g, int balance, int maxiter, int search_size)
CGRAPH_API Agedge_t * agnxtout(Agraph_t *g, Agedge_t *e)