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 #if 0
00040
00041 #include "errors.h"
00042 #include "mfmc.h"
00043 #include "mfmc_defs.h"
00044
00045 MFMC_HANDLE
00046 MFMC_Init_problem(MEM_POOL *mem_pool,
00047 BOOL trace,
00048 INT32 n,
00049 INT32 m,
00050 INT32 n_sources,
00051 INT32 n_sinks)
00052 {
00053 INT32 i;
00054
00055
00056 MFMC_HANDLE handle = (MFMC_HANDLE) MEM_POOL_Alloc(mem_pool,
00057 sizeof(*handle));
00058
00059 if (handle == NULL) {
00060 return NULL;
00061 }
00062
00063 handle->mem_pool = mem_pool;
00064 handle->trace = trace;
00065
00066 handle->n = handle->user_n = n;
00067 handle->m = handle->user_m = m;
00068
00069 handle->n_sources = n_sources;
00070 handle->n_sinks = n_sinks;
00071
00072 handle->pos_current = 0;
00073
00074 if (n_sources > 1) {
00075
00076
00077 handle->n++;
00078 handle->m += n_sources;
00079 }
00080
00081 if (n_sinks > 1) {
00082
00083
00084 handle->n++;
00085 handle->m += n_sinks;
00086 }
00087
00088
00089
00090
00091
00092 handle->nodes = TYPE_MEM_POOL_ALLOC_N(MFMC_NODE,
00093 mem_pool,
00094 handle->n + 2);
00095 handle->arcs = TYPE_MEM_POOL_ALLOC_N(MFMC_ARC,
00096 mem_pool,
00097 2 * handle->m + 1);
00098 handle->acap = TYPE_MEM_POOL_ALLOC_N(INT64,
00099 mem_pool,
00100 2 * handle->m);
00101
00102
00103
00104
00105
00106 MEM_POOL_Push(mem_pool);
00107
00108 handle->queue = TYPE_MEM_POOL_ALLOC_N(MFMC_NODE *,
00109 mem_pool,
00110 handle->n);
00111 handle->layers = TYPE_MEM_POOL_ALLOC_N(MFMC_LAYER,
00112 mem_pool,
00113 handle->n + 2);
00114
00115
00116
00117
00118 MEM_POOL_Push(handle->mem_pool);
00119
00120 handle->arc_tail = TYPE_MEM_POOL_ALLOC_N(INT32,
00121 mem_pool,
00122 2 * handle->m);
00123 handle->arc_first = TYPE_MEM_POOL_ALLOC_N(INT32,
00124 mem_pool,
00125 handle->n + 2);
00126
00127 if (handle->nodes == NULL || handle->arcs == NULL ||
00128 handle->arc_first == NULL || handle->arc_tail == NULL) {
00129 return NULL;
00130 }
00131
00132 for (i = 0; i < n; i++) {
00133 handle->nodes[i].node_type = TRANSSHIPMENT;
00134 }
00135
00136 for (i = 0; i < m; i++) {
00137 handle->arc_first[i] = 0;
00138 }
00139
00140 if (n_sources > 1) {
00141 handle->the_source = &handle->nodes[handle->user_n];
00142 }
00143 else {
00144 handle->the_source = NULL;
00145 }
00146
00147 if (n_sinks > 1) {
00148 handle->the_sink = &handle->nodes[handle->n - 1];
00149 }
00150 else {
00151 handle->the_sink = NULL;
00152 }
00153
00154
00155 handle->arc_current = handle->arcs;
00156
00157 handle->n_sources_set = 0;
00158 handle->n_sinks_set = 0;
00159 handle->max_cap = 0;
00160
00161 return handle;
00162 }
00163
00164 MFMC_EC
00165 MFMC_Place_arc(MFMC_HANDLE handle,
00166 INT32 tail,
00167 INT32 head,
00168 INT64 lower_cap,
00169 INT64 upper_cap,
00170 MFMC_ARC_HANDLE *arc_handle)
00171
00172 {
00173 FmtAssert(tail >= 0 && tail < handle->n,
00174 ("Tail node out of range"));
00175 FmtAssert(head >= 0 && head < handle->n,
00176 ("Head node out of range"));
00177
00178 if (upper_cap < lower_cap) {
00179 return MFMC_INFEASIBLE;
00180 }
00181
00182 if (upper_cap < 0 || lower_cap > 0) {
00183 return MFMC_ZERO_INFEASIBLE;
00184 }
00185
00186
00187
00188
00189
00190 if (handle->pos_current + 1 >= 2 * handle->user_m) {
00191 return MFMC_BAD_ARC_COUNT;
00192 }
00193
00194
00195 handle->arc_first[tail + 1] ++;
00196 handle->arc_first[head + 1] ++;
00197
00198
00199 handle->arc_tail[handle->pos_current] = tail;
00200 handle->arc_tail[handle->pos_current+1] = head;
00201
00202 handle->arc_current->head = handle->nodes + head;
00203 handle->arc_current->r_cap = upper_cap;
00204 handle->arc_current->reverse = handle->arc_current + 1;
00205
00206 (handle->arc_current + 1)->head = handle->nodes + tail;
00207 (handle->arc_current + 1)->r_cap = -lower_cap;
00208 (handle->arc_current + 1)->reverse = handle->arc_current;
00209
00210
00211 handle->arc_current += 2;
00212 handle->pos_current += 2;
00213
00214 if (upper_cap > handle->max_cap) {
00215 handle->max_cap = upper_cap;
00216 }
00217 if (-lower_cap > handle->max_cap) {
00218 handle->max_cap = -lower_cap;
00219 }
00220
00221 if (arc_handle != NULL) {
00222
00223 return MFMC_NOT_IMPLEMENTED;
00224 }
00225
00226 return MFMC_NO_ERROR;
00227 }
00228
00229 MFMC_EC
00230 MFMC_Set_source(MFMC_HANDLE handle, INT32 s)
00231 {
00232 FmtAssert(s >= 0 && s < handle->n,
00233 ("Source node out of range"));
00234
00235 if (handle->nodes[s].node_type == TRANSSHIPMENT) {
00236 if (handle->n_sources == 1) {
00237 handle->nodes[s].node_type = SOURCE;
00238 handle->the_source = &handle->nodes[s];
00239 }
00240 else {
00241 handle->nodes[s].node_type = USER_SOURCE;
00242
00243
00244
00245 }
00246 handle->n_sources_set++;
00247 return MFMC_NO_ERROR;
00248 }
00249 else {
00250 return MFMC_S_T_OVERLAP;
00251 }
00252 }
00253
00254 MFMC_EC
00255 MFMC_Set_sink(MFMC_HANDLE handle, INT32 t)
00256 {
00257 FmtAssert(t >= 0 && t < handle->n,
00258 ("Sink node out of range"));
00259
00260 if (handle->nodes[t].node_type != SOURCE) {
00261 if (handle->n_sinks == 1) {
00262 handle->nodes[t].node_type = SINK;
00263 handle->the_sink = &handle->nodes[t];
00264 }
00265 else {
00266 handle->nodes[t].node_type = USER_SINK;
00267
00268
00269
00270 }
00271 handle->n_sinks_set++;
00272 return MFMC_NO_ERROR;
00273 }
00274 else {
00275 return MFMC_S_T_OVERLAP;
00276 }
00277 }
00278
00279
00280
00281
00282
00283
00284 MFMC_EC
00285 MFMC_Solve_problem(MFMC_HANDLE handle)
00286 {
00287 INT64 big_cap = handle->max_cap * handle->m;
00288 INT32 i;
00289 INT32 tail,
00290 last,
00291 arc_num,
00292 arc_new_num;
00293 INT64 cap;
00294 MFMC_ARC *arc_current,
00295 *arc_new,
00296 *arc_tmp;
00297 MFMC_NODE *head_p,
00298 *ndp;
00299
00300 if (handle->n_sources != handle->n_sources_set ||
00301 handle->n_sinks != handle->n_sinks_set) {
00302 return MFMC_UNSEEN_S_T;
00303 }
00304
00305 if (handle->pos_current != 2 * handle->user_m) {
00306 return MFMC_BAD_ARC_COUNT;
00307 }
00308
00309
00310
00311
00312 handle->user_m = handle->m;
00313
00314 if (handle->n_sources > 1) {
00315
00316
00317
00318 for (i = 0; i < handle->user_n; i++) {
00319 if (handle->nodes[i].node_type == USER_SOURCE) {
00320 MFMC_Place_arc(handle, handle->the_source - handle->nodes, i,
00321 0, big_cap, NULL);
00322 }
00323 }
00324 }
00325
00326 if (handle->n_sinks > 1) {
00327
00328
00329
00330 for (i = handle->user_n; i >= 0; i--) {
00331 if (handle->nodes[i].node_type == USER_SINK) {
00332 MFMC_Place_arc(handle, i, handle->the_sink - handle->nodes,
00333 0, big_cap, NULL);
00334 }
00335 }
00336 }
00337
00338 FmtAssert(handle->pos_current == 2 * handle->m,
00339 ("Arc count mismatch in auxiliary source/sink placement"));
00340
00341
00342
00343
00344
00345
00346
00347 handle->nodes[0].first = handle->arcs;
00348
00349
00350
00351
00352
00353
00354
00355 for (i = 1; i <= handle->n + 1; i++) {
00356 handle->arc_first[i] += handle->arc_first[i - 1];
00357 handle->nodes[i].first = handle->arcs + handle->arc_first[i];
00358 }
00359
00360
00361 for ( i = 0; i < handle->n; i++) {
00362 last = handle->nodes[i + 1].first - handle->arcs;
00363
00364
00365
00366
00367
00368 for (arc_num = handle->arc_first[i];
00369 arc_num < last;
00370 arc_num++) {
00371 tail = handle->arc_tail[arc_num];
00372
00373
00374
00375
00376
00377
00378 while ( tail != i ) {
00379 arc_new_num = handle->arc_first[tail];
00380 arc_current = handle->arcs + arc_num;
00381 arc_new = handle->arcs + arc_new_num;
00382
00383
00384
00385
00386 head_p = arc_new->head;
00387 arc_new->head = arc_current->head;
00388 arc_current->head = head_p;
00389
00390 cap = arc_new->r_cap;
00391 arc_new->r_cap = arc_current->r_cap;
00392 arc_current->r_cap = cap;
00393
00394 if (arc_new != arc_current->reverse) {
00395 arc_tmp = arc_new->reverse;
00396 arc_new->reverse = arc_current->reverse;
00397 arc_current->reverse = arc_tmp;
00398
00399 (arc_current->reverse)->reverse = arc_current;
00400 (arc_new->reverse)->reverse = arc_new;
00401 }
00402
00403 handle->arc_tail[arc_num] = handle->arc_tail[arc_new_num];
00404 handle->arc_tail[arc_new_num] = tail;
00405
00406
00407 handle->arc_first[tail] ++ ;
00408
00409 tail = handle->arc_tail[arc_num];
00410 }
00411 }
00412
00413 }
00414
00415
00416
00417
00418
00419
00420 for (ndp = handle->nodes;
00421 ndp <= handle->nodes + handle->n;
00422 ndp++) {
00423 ndp->first = NULL;
00424 }
00425
00426
00427
00428
00429 for (arc_current = handle->arcs + (2 * handle->m - 1);
00430 arc_current >= handle->arcs;
00431 arc_current--) {
00432 arc_num = arc_current - handle->arcs;
00433 handle->acap[arc_num] = arc_current->r_cap;
00434 tail = handle->arc_tail[arc_num];
00435 ndp = handle->nodes + tail;
00436 arc_current->next = ndp->first;
00437 ndp->first = arc_current;
00438 }
00439
00440
00441 MEM_POOL_Pop(handle->mem_pool);
00442
00443
00444 MFMC_Find_max_flow_min_cut(handle->n,
00445 handle->nodes,
00446 handle->arcs,
00447 handle->acap,
00448 handle->the_source,
00449 handle->the_sink,
00450 handle->queue,
00451 handle->layers,
00452 big_cap,
00453 &handle->stats,
00454 &handle->flow_value);
00455
00456
00457 MEM_POOL_Pop(handle->mem_pool);
00458
00459 return MFMC_NO_ERROR;
00460 }
00461
00462 #endif