Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #if 0
00047
00048 #include <sys/types.h>
00049 #include <sys/times.h>
00050
00051 #include "mfmc_defs.h"
00052
00053 #define GLOB_UPDT_FREQ 1.0
00054
00055
00056
00057 static INT32 n;
00058 static MFMC_NODE *nodes;
00059 static MFMC_ARC *arcs;
00060 static MFMC_LAYER *layers;
00061 static INT64 *cap;
00062 static MFMC_NODE *source;
00063 static MFMC_NODE *sink;
00064 static MFMC_STATS *stats;
00065 static MFMC_NODE **queue;
00066 static MFMC_NODE **q_read, **q_write;
00067
00068 static INT32 lmax;
00069 static INT32 lmax_push;
00070 static INT32 lmin_push;
00071
00072 static INT64 biggest_flow;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 float timer(void)
00085 {
00086 struct tms hold;
00087
00088 times(&hold);
00089 return (float) hold.tms_utime / 60.0;
00090 }
00091
00092 static BOOL
00093 pr_init(INT32 n_p,
00094 MFMC_NODE *nodes_p,
00095 MFMC_ARC *arcs_p,
00096 INT64 *cap_p,
00097 MFMC_NODE *source_p,
00098 MFMC_NODE *sink_p,
00099 MFMC_NODE **queue_p,
00100 MFMC_LAYER *layers_p,
00101 MFMC_STATS *stats_p,
00102 INT64 flow_upper_bound)
00103
00104 {
00105 MFMC_NODE *i;
00106
00107 n = n_p;
00108 nodes = nodes_p;
00109 arcs = arcs_p;
00110 cap = cap_p;
00111 source = source_p;
00112 sink = sink_p;
00113 stats = stats_p;
00114 queue = queue_p;
00115 layers = layers_p;
00116
00117 for (i = nodes; i < nodes + n; i++) {
00118 i->excess = 0;
00119 }
00120
00121 source->excess = biggest_flow = flow_upper_bound;
00122
00123 lmax = n - 1;
00124
00125 return MFMC_NO_ERROR;
00126 }
00127
00128
00129
00130
00131 static void
00132 def_ranks (void)
00133
00134 {
00135 MFMC_NODE *i, *j, *jn;
00136 MFMC_ARC *a;
00137 MFMC_LAYER *l;
00138 INT32 j_rank;
00139
00140 stats->n_up++;
00141
00142
00143 for (i = nodes; i < nodes + n; i++) {
00144 i->rank = n;
00145 }
00146
00147 sink->rank = 0;
00148
00149 *queue = sink;
00150
00151 for (l = layers; l <= layers + lmax; l++) {
00152 l->push_first = NULL;
00153 l->trans_first = NULL;
00154 }
00155
00156 lmax = lmax_push = 0;
00157 lmin_push = n;
00158
00159
00160 for (q_read = queue, q_write = queue + 1;
00161 q_read != q_write;
00162 q_read++) {
00163
00164 i = *q_read;
00165 j_rank = i->rank + 1;
00166
00167 for (a = i->first; a != NULL; a = a->next) {
00168 j = a->head;
00169
00170 if (j->rank == n) {
00171
00172 if (a->reverse->r_cap > 0 ) {
00173
00174 j->rank = j_rank;
00175 j->current = j->first;
00176
00177 l = layers + j_rank;
00178 if (j_rank > lmax) lmax = j_rank;
00179
00180 if (j->excess > 0) {
00181 j->nl_next = l->push_first;
00182 l->push_first = j;
00183 if (j_rank > lmax_push) lmax_push = j_rank;
00184 if (j_rank < lmin_push) lmin_push = j_rank;
00185 }
00186 else {
00187
00188 jn = l->trans_first;
00189 j->nl_next = jn;
00190 if (jn != NULL) jn->nl_prev = j;
00191 l->trans_first = j;
00192 }
00193
00194
00195 *q_write = j;
00196 q_write++;
00197 }
00198 }
00199 }
00200 }
00201 }
00202
00203
00204
00205 static void
00206 prefl_to_flow (void)
00207
00208 {
00209 MFMC_NODE *i,*j, *ir, *is, *it, *front;
00210 MFMC_ARC *a;
00211 INT64 path_cap;
00212 BOOL path, out_of_path;
00213
00214
00215 for (i = nodes + n; i >= nodes; i--) {
00216 i->current = i->first;
00217 i->nl_next = NULL;
00218 }
00219
00220
00221 for (i = nodes; i < nodes + n; i ++) {
00222 if (i->excess <= 0 || i == source || i == sink) continue;
00223
00224
00225 for (front = i; i->excess > 0;) {
00226
00227
00228
00229 while (front != source) {
00230 for (a = front->current; ; a = a->next) {
00231 if (cap[a - arcs] == 0 &&
00232 a->r_cap > 0)
00233 break;
00234 }
00235 front->current = a;
00236
00237 j = a->head;
00238
00239 front->nl_next = j;
00240 front = j;
00241
00242 if (j->nl_next != NULL)
00243
00244 break;
00245 }
00246
00247
00248
00249 if (front == source) {
00250 path = TRUE;
00251 is = i;
00252 path_cap = i->excess;
00253 }
00254 else {
00255 path = FALSE;
00256 is = j;
00257 path_cap = biggest_flow;
00258 }
00259
00260
00261
00262 front = ir = is;
00263
00264 do {
00265 a = ir->current;
00266
00267 if (a->r_cap < path_cap) {
00268 front = ir;
00269 path_cap = a ->r_cap;
00270 }
00271 ir = ir->nl_next;
00272
00273 } while (ir != j);
00274
00275 if (path) i->excess -= path_cap;
00276
00277
00278
00279 ir = is;
00280 out_of_path = 0;
00281
00282 do {
00283 a = ir->current;
00284 a->r_cap -= path_cap;
00285 a->reverse->r_cap += path_cap;
00286
00287 it = ir->nl_next;
00288
00289 if (ir == front) out_of_path = 1;
00290 if (out_of_path) ir->nl_next = NULL;
00291
00292 ir = it;
00293
00294 } while (ir != j);
00295
00296 }
00297 }
00298 }
00299
00300
00301
00302 static BOOL
00303 gap (MFMC_LAYER *le)
00304
00305 {
00306 MFMC_LAYER *l;
00307 MFMC_NODE *i;
00308 INT32 r;
00309 BOOL cc;
00310
00311
00312 stats->n_gap++;
00313
00314 r = (le - layers) - 1;
00315
00316
00317
00318 for (l = le + 1; l <= layers + lmax; l++) {
00319 for (i = l->push_first; i != NULL; i = i->nl_next) {
00320 i->rank = n;
00321 stats->n_gnode ++;
00322 }
00323
00324 for (i = l->trans_first; i != NULL; i = i->nl_next) {
00325 i->rank = n;
00326 stats->n_gnode ++;
00327 }
00328
00329 l->push_first = l->trans_first = NULL;
00330 }
00331
00332 cc = (lmin_push > r) ? TRUE : FALSE;
00333
00334 lmax = r;
00335 lmax_push = r;
00336
00337 return cc;
00338 }
00339
00340
00341
00342
00343 static BOOL
00344 push (MFMC_NODE *i)
00345
00346 {
00347 MFMC_NODE *j;
00348 MFMC_NODE *j_next, *j_prev;
00349 INT32 j_rank;
00350 MFMC_LAYER *lj;
00351 MFMC_ARC *a;
00352 INT64 fl;
00353
00354 j_rank = i->rank - 1;
00355
00356
00357
00358 for (a = i->current; a != NULL; a = a->next) {
00359 if (a->r_cap > 0) {
00360
00361
00362 j = a->head;
00363 if (j->rank == j_rank) {
00364
00365
00366 fl = MIN(i->excess, a->r_cap);
00367
00368 a->r_cap -= fl;
00369 a->reverse->r_cap += fl;
00370 stats->n_push ++;
00371
00372 if (j_rank > 0) {
00373 lj = layers + j_rank;
00374
00375 if (j->excess == 0) {
00376
00377
00378
00379 j_next = j->nl_next;
00380
00381 if (lj->trans_first == j)
00382
00383 lj->trans_first = j_next;
00384 else {
00385
00386 j_prev = j->nl_prev;
00387 j_prev->nl_next = j_next;
00388 if (j_next != NULL)
00389 j_next->nl_prev = j_prev;
00390 }
00391
00392
00393 j->nl_next = lj->push_first;
00394 lj->push_first = j;
00395
00396 if (j_rank < lmin_push)
00397 lmin_push = j_rank;
00398 }
00399 }
00400
00401 j->excess += fl;
00402 i->excess -= fl;
00403
00404 if (i->excess == 0) break;
00405
00406 }
00407 }
00408 }
00409
00410 i->current = a;
00411
00412 return a == NULL;
00413 }
00414
00415
00416
00417 static INT32
00418 relabel (MFMC_NODE *i)
00419
00420 {
00421 MFMC_NODE *j;
00422 INT32 j_rank;
00423 MFMC_ARC *a;
00424 MFMC_ARC *a_j;
00425 MFMC_LAYER *l;
00426
00427 stats->n_rel++;
00428
00429 i->rank = j_rank = n;
00430
00431
00432
00433 for (a = i->first; a != NULL; a = a->next) {
00434 if (a->r_cap > 0) {
00435 j = a->head;
00436
00437 if (j->rank < j_rank)
00438 {
00439 j_rank = j->rank;
00440 a_j = a;
00441 }
00442 }
00443 }
00444
00445 if (j_rank < n) {
00446 i->rank = ++j_rank;
00447 i->current = a_j;
00448
00449 l = layers + j_rank;
00450
00451 if (i->excess > 0) {
00452 i->nl_next = l->push_first;
00453 l->push_first = i;
00454 if (j_rank > lmax_push) lmax_push = j_rank;
00455 if (j_rank < lmin_push) lmin_push = j_rank;
00456 }
00457 else {
00458 j = l->trans_first;
00459 i->nl_next = j;
00460 if (j != 0) j->nl_prev = i;
00461 l->trans_first = i;
00462 }
00463
00464 if (j_rank > lmax) lmax = j_rank;
00465 }
00466
00467 return j_rank;
00468 }
00469
00470
00471
00472
00473 BOOL
00474 MFMC_Find_max_flow_min_cut(INT32 n_p,
00475 MFMC_NODE *nodes_p,
00476 MFMC_ARC *arcs_p,
00477 INT64 *cap_p,
00478 MFMC_NODE *source_p,
00479 MFMC_NODE *sink_p,
00480 MFMC_NODE **queue_p,
00481 MFMC_LAYER *layers_p,
00482 INT64 flow_upper_bound,
00483 MFMC_STATS *stats_p,
00484 INT64 *fl)
00485
00486 {
00487 MFMC_NODE *i;
00488 MFMC_NODE *j;
00489 INT32 i_rank;
00490 MFMC_LAYER *l;
00491 INT32 n_r;
00492 BOOL cc;
00493 MFMC_STATS stat_buf;
00494
00495 if (stats_p != NULL) {
00496 stats_p->time = timer();
00497 }
00498 cc = pr_init(n_p, nodes_p, arcs_p, cap_p, source_p, sink_p,
00499 queue_p, layers_p,
00500 (stats_p != NULL ? stats_p : &stat_buf),
00501 flow_upper_bound);
00502
00503 if (cc != MFMC_NO_ERROR) return cc;
00504
00505 def_ranks();
00506
00507 n_r = 0;
00508
00509
00510
00511 while (lmax_push >= lmin_push) {
00512
00513 l = layers + lmax_push;
00514
00515 i = l->push_first;
00516
00517 if (i == NULL) {
00518
00519 lmax_push --;
00520 }
00521 else {
00522 l->push_first = i->nl_next;
00523
00524 cc = push(i);
00525
00526 if (cc) {
00527
00528 relabel(i);
00529 n_r ++;
00530
00531 if (l->push_first == NULL &&
00532 l->trans_first == NULL) {
00533
00534 gap ( l );
00535 }
00536
00537
00538 if (n_r > GLOB_UPDT_FREQ * (float) n) {
00539
00540 def_ranks ();
00541 n_r = 0;
00542 }
00543 }
00544 else {
00545 j = l->trans_first;
00546 i->nl_next = j;
00547 l->trans_first = i;
00548 if (j != NULL) j->nl_prev = i;
00549 }
00550 }
00551 }
00552
00553 #if 1
00554 *fl = sink->excess;
00555 #else
00556 *fl += sink->excess;
00557 #endif
00558
00559 prefl_to_flow();
00560
00561 if (stats_p != NULL) {
00562 stats_p->time = timer() - stats_p->time;
00563 }
00564
00565 return MFMC_NO_ERROR;
00566 }
00567
00568 #endif