00001
00002
00003
00004 #include <stdio.h>
00005 #include "graph.h"
00006
00007
00008
00009
00010
00011 #define TERMINAL ( (arc *) 1 )
00012 #define ORPHAN ( (arc *) 2 )
00013
00014
00015 #define INFINITE_D ((int)(((unsigned)-1)/2))
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 template <typename captype, typename tcaptype, typename flowtype>
00034 inline void Graph<captype,tcaptype,flowtype>::set_active(node *i)
00035 {
00036 if (!i->next)
00037 {
00038
00039 if (queue_last[1]) queue_last[1] -> next = i;
00040 else queue_first[1] = i;
00041 queue_last[1] = i;
00042 i -> next = i;
00043 }
00044 }
00045
00046
00047
00048
00049
00050
00051 template <typename captype, typename tcaptype, typename flowtype>
00052 inline typename Graph<captype,tcaptype,flowtype>::node* Graph<captype,tcaptype,flowtype>::next_active()
00053 {
00054 node *i;
00055
00056 while ( 1 )
00057 {
00058 if (!(i=queue_first[0]))
00059 {
00060 queue_first[0] = i = queue_first[1];
00061 queue_last[0] = queue_last[1];
00062 queue_first[1] = NULL;
00063 queue_last[1] = NULL;
00064 if (!i) return NULL;
00065 }
00066
00067
00068 if (i->next == i) queue_first[0] = queue_last[0] = NULL;
00069 else queue_first[0] = i -> next;
00070 i -> next = NULL;
00071
00072
00073 if (i->parent) return i;
00074 }
00075 }
00076
00077
00078
00079 template <typename captype, typename tcaptype, typename flowtype>
00080 inline void Graph<captype,tcaptype,flowtype>::set_orphan_front(node *i)
00081 {
00082 nodeptr *np;
00083 i -> parent = ORPHAN;
00084 np = nodeptr_block -> New();
00085 np -> ptr = i;
00086 np -> next = orphan_first;
00087 orphan_first = np;
00088 }
00089
00090 template <typename captype, typename tcaptype, typename flowtype>
00091 inline void Graph<captype,tcaptype,flowtype>::set_orphan_rear(node *i)
00092 {
00093 nodeptr *np;
00094 i -> parent = ORPHAN;
00095 np = nodeptr_block -> New();
00096 np -> ptr = i;
00097 if (orphan_last) orphan_last -> next = np;
00098 else orphan_first = np;
00099 orphan_last = np;
00100 np -> next = NULL;
00101 }
00102
00103
00104
00105 template <typename captype, typename tcaptype, typename flowtype>
00106 inline void Graph<captype,tcaptype,flowtype>::add_to_changed_list(node *i)
00107 {
00108 if (changed_list && !i->is_in_changed_list)
00109 {
00110 node_id* ptr = changed_list->New();
00111 *ptr = (node_id)(i - nodes);
00112 i->is_in_changed_list = true;
00113 }
00114 }
00115
00116
00117
00118 template <typename captype, typename tcaptype, typename flowtype>
00119 void Graph<captype,tcaptype,flowtype>::maxflow_init()
00120 {
00121 node *i;
00122
00123 queue_first[0] = queue_last[0] = NULL;
00124 queue_first[1] = queue_last[1] = NULL;
00125 orphan_first = NULL;
00126
00127 TIME = 0;
00128
00129 for (i=nodes; i<node_last; i++)
00130 {
00131 i -> next = NULL;
00132 i -> is_marked = 0;
00133 i -> is_in_changed_list = 0;
00134 i -> TS = TIME;
00135 if (i->tr_cap > 0)
00136 {
00137
00138 i -> is_sink = 0;
00139 i -> parent = TERMINAL;
00140 set_active(i);
00141 i -> DIST = 1;
00142 }
00143 else if (i->tr_cap < 0)
00144 {
00145
00146 i -> is_sink = 1;
00147 i -> parent = TERMINAL;
00148 set_active(i);
00149 i -> DIST = 1;
00150 }
00151 else
00152 {
00153 i -> parent = NULL;
00154 }
00155 }
00156 }
00157
00158 template <typename captype, typename tcaptype, typename flowtype>
00159 void Graph<captype,tcaptype,flowtype>::maxflow_reuse_trees_init()
00160 {
00161 node* i;
00162 node* j;
00163 node* queue = queue_first[1];
00164 arc* a;
00165 nodeptr* np;
00166
00167 queue_first[0] = queue_last[0] = NULL;
00168 queue_first[1] = queue_last[1] = NULL;
00169 orphan_first = orphan_last = NULL;
00170
00171 TIME ++;
00172
00173 while ((i=queue))
00174 {
00175 queue = i->next;
00176 if (queue == i) queue = NULL;
00177 i->next = NULL;
00178 i->is_marked = 0;
00179 set_active(i);
00180
00181 if (i->tr_cap == 0)
00182 {
00183 if (i->parent) set_orphan_rear(i);
00184 continue;
00185 }
00186
00187 if (i->tr_cap > 0)
00188 {
00189 if (!i->parent || i->is_sink)
00190 {
00191 i->is_sink = 0;
00192 for (a=i->first; a; a=a->next)
00193 {
00194 j = a->head;
00195 if (!j->is_marked)
00196 {
00197 if (j->parent == a->sister) set_orphan_rear(j);
00198 if (j->parent && j->is_sink && a->r_cap > 0) set_active(j);
00199 }
00200 }
00201 add_to_changed_list(i);
00202 }
00203 }
00204 else
00205 {
00206 if (!i->parent || !i->is_sink)
00207 {
00208 i->is_sink = 1;
00209 for (a=i->first; a; a=a->next)
00210 {
00211 j = a->head;
00212 if (!j->is_marked)
00213 {
00214 if (j->parent == a->sister) set_orphan_rear(j);
00215 if (j->parent && !j->is_sink && a->sister->r_cap > 0) set_active(j);
00216 }
00217 }
00218 add_to_changed_list(i);
00219 }
00220 }
00221 i->parent = TERMINAL;
00222 i -> TS = TIME;
00223 i -> DIST = 1;
00224 }
00225
00226
00227
00228
00229 while ((np=orphan_first))
00230 {
00231 orphan_first = np -> next;
00232 i = np -> ptr;
00233 nodeptr_block -> Delete(np);
00234 if (!orphan_first) orphan_last = NULL;
00235 if (i->is_sink) process_sink_orphan(i);
00236 else process_source_orphan(i);
00237 }
00238
00239
00240
00241 }
00242
00243 template <typename captype, typename tcaptype, typename flowtype>
00244 void Graph<captype,tcaptype,flowtype>::augment(arc *middle_arc)
00245 {
00246 node *i;
00247 arc *a;
00248 tcaptype bottleneck;
00249
00250
00251
00252
00253 bottleneck = middle_arc -> r_cap;
00254 for (i=middle_arc->sister->head; ; i=a->head)
00255 {
00256 a = i -> parent;
00257 if (a == TERMINAL) break;
00258 if (bottleneck > a->sister->r_cap) bottleneck = a -> sister -> r_cap;
00259 }
00260 if (bottleneck > i->tr_cap) bottleneck = i -> tr_cap;
00261
00262 for (i=middle_arc->head; ; i=a->head)
00263 {
00264 a = i -> parent;
00265 if (a == TERMINAL) break;
00266 if (bottleneck > a->r_cap) bottleneck = a -> r_cap;
00267 }
00268 if (bottleneck > - i->tr_cap) bottleneck = - i -> tr_cap;
00269
00270
00271
00272
00273 middle_arc -> sister -> r_cap += bottleneck;
00274 middle_arc -> r_cap -= bottleneck;
00275 for (i=middle_arc->sister->head; ; i=a->head)
00276 {
00277 a = i -> parent;
00278 if (a == TERMINAL) break;
00279 a -> r_cap += bottleneck;
00280 a -> sister -> r_cap -= bottleneck;
00281 if (!a->sister->r_cap)
00282 {
00283 set_orphan_front(i);
00284 }
00285 }
00286 i -> tr_cap -= bottleneck;
00287 if (!i->tr_cap)
00288 {
00289 set_orphan_front(i);
00290 }
00291
00292 for (i=middle_arc->head; ; i=a->head)
00293 {
00294 a = i -> parent;
00295 if (a == TERMINAL) break;
00296 a -> sister -> r_cap += bottleneck;
00297 a -> r_cap -= bottleneck;
00298 if (!a->r_cap)
00299 {
00300 set_orphan_front(i);
00301 }
00302 }
00303 i -> tr_cap += bottleneck;
00304 if (!i->tr_cap)
00305 {
00306 set_orphan_front(i);
00307 }
00308
00309
00310 flow += bottleneck;
00311 }
00312
00313
00314
00315 template <typename captype, typename tcaptype, typename flowtype>
00316 void Graph<captype,tcaptype,flowtype>::process_source_orphan(node *i)
00317 {
00318 node *j;
00319 arc *a0, *a0_min = NULL, *a;
00320 int d, d_min = INFINITE_D;
00321
00322
00323 for (a0=i->first; a0; a0=a0->next)
00324 if (a0->sister->r_cap)
00325 {
00326 j = a0 -> head;
00327 if (!j->is_sink && (a=j->parent))
00328 {
00329
00330 d = 0;
00331 while ( 1 )
00332 {
00333 if (j->TS == TIME)
00334 {
00335 d += j -> DIST;
00336 break;
00337 }
00338 a = j -> parent;
00339 d ++;
00340 if (a==TERMINAL)
00341 {
00342 j -> TS = TIME;
00343 j -> DIST = 1;
00344 break;
00345 }
00346 if (a==ORPHAN) { d = INFINITE_D; break; }
00347 j = a -> head;
00348 }
00349 if (d<INFINITE_D)
00350 {
00351 if (d<d_min)
00352 {
00353 a0_min = a0;
00354 d_min = d;
00355 }
00356
00357 for (j=a0->head; j->TS!=TIME; j=j->parent->head)
00358 {
00359 j -> TS = TIME;
00360 j -> DIST = d --;
00361 }
00362 }
00363 }
00364 }
00365
00366 if (i->parent = a0_min)
00367 {
00368 i -> TS = TIME;
00369 i -> DIST = d_min + 1;
00370 }
00371 else
00372 {
00373
00374 add_to_changed_list(i);
00375
00376
00377 for (a0=i->first; a0; a0=a0->next)
00378 {
00379 j = a0 -> head;
00380 if (!j->is_sink && (a=j->parent))
00381 {
00382 if (a0->sister->r_cap) set_active(j);
00383 if (a!=TERMINAL && a!=ORPHAN && a->head==i)
00384 {
00385 set_orphan_rear(j);
00386 }
00387 }
00388 }
00389 }
00390 }
00391
00392 template <typename captype, typename tcaptype, typename flowtype>
00393 void Graph<captype,tcaptype,flowtype>::process_sink_orphan(node *i)
00394 {
00395 node *j;
00396 arc *a0, *a0_min = NULL, *a;
00397 int d, d_min = INFINITE_D;
00398
00399
00400 for (a0=i->first; a0; a0=a0->next)
00401 if (a0->r_cap)
00402 {
00403 j = a0 -> head;
00404 if (j->is_sink && (a=j->parent))
00405 {
00406
00407 d = 0;
00408 while ( 1 )
00409 {
00410 if (j->TS == TIME)
00411 {
00412 d += j -> DIST;
00413 break;
00414 }
00415 a = j -> parent;
00416 d ++;
00417 if (a==TERMINAL)
00418 {
00419 j -> TS = TIME;
00420 j -> DIST = 1;
00421 break;
00422 }
00423 if (a==ORPHAN) { d = INFINITE_D; break; }
00424 j = a -> head;
00425 }
00426 if (d<INFINITE_D)
00427 {
00428 if (d<d_min)
00429 {
00430 a0_min = a0;
00431 d_min = d;
00432 }
00433
00434 for (j=a0->head; j->TS!=TIME; j=j->parent->head)
00435 {
00436 j -> TS = TIME;
00437 j -> DIST = d --;
00438 }
00439 }
00440 }
00441 }
00442
00443 if (i->parent = a0_min)
00444 {
00445 i -> TS = TIME;
00446 i -> DIST = d_min + 1;
00447 }
00448 else
00449 {
00450
00451 add_to_changed_list(i);
00452
00453
00454 for (a0=i->first; a0; a0=a0->next)
00455 {
00456 j = a0 -> head;
00457 if (j->is_sink && (a=j->parent))
00458 {
00459 if (a0->r_cap) set_active(j);
00460 if (a!=TERMINAL && a!=ORPHAN && a->head==i)
00461 {
00462 set_orphan_rear(j);
00463 }
00464 }
00465 }
00466 }
00467 }
00468
00469
00470
00471 template <typename captype, typename tcaptype, typename flowtype>
00472 flowtype Graph<captype,tcaptype,flowtype>::maxflow(bool reuse_trees, Block<node_id>* _changed_list)
00473 {
00474 node *i, *j, *current_node = NULL;
00475 arc *a;
00476 nodeptr *np, *np_next;
00477
00478 if (!nodeptr_block)
00479 {
00480 nodeptr_block = new DBlock<nodeptr>(NODEPTR_BLOCK_SIZE, error_function);
00481 }
00482
00483 changed_list = _changed_list;
00484 if (maxflow_iteration == 0 && reuse_trees) { if (error_function) (*error_function)("reuse_trees cannot be used in the first call to maxflow()!"); exit(1); }
00485 if (changed_list && !reuse_trees) { if (error_function) (*error_function)("changed_list cannot be used without reuse_trees!"); exit(1); }
00486
00487 if (reuse_trees) maxflow_reuse_trees_init();
00488 else maxflow_init();
00489
00490
00491 while ( 1 )
00492 {
00493
00494
00495 if ((i=current_node))
00496 {
00497 i -> next = NULL;
00498 if (!i->parent) i = NULL;
00499 }
00500 if (!i)
00501 {
00502 if (!(i = next_active())) break;
00503 }
00504
00505
00506 if (!i->is_sink)
00507 {
00508
00509 for (a=i->first; a; a=a->next)
00510 if (a->r_cap)
00511 {
00512 j = a -> head;
00513 if (!j->parent)
00514 {
00515 j -> is_sink = 0;
00516 j -> parent = a -> sister;
00517 j -> TS = i -> TS;
00518 j -> DIST = i -> DIST + 1;
00519 set_active(j);
00520 add_to_changed_list(j);
00521 }
00522 else if (j->is_sink) break;
00523 else if (j->TS <= i->TS &&
00524 j->DIST > i->DIST)
00525 {
00526
00527 j -> parent = a -> sister;
00528 j -> TS = i -> TS;
00529 j -> DIST = i -> DIST + 1;
00530 }
00531 }
00532 }
00533 else
00534 {
00535
00536 for (a=i->first; a; a=a->next)
00537 if (a->sister->r_cap)
00538 {
00539 j = a -> head;
00540 if (!j->parent)
00541 {
00542 j -> is_sink = 1;
00543 j -> parent = a -> sister;
00544 j -> TS = i -> TS;
00545 j -> DIST = i -> DIST + 1;
00546 set_active(j);
00547 add_to_changed_list(j);
00548 }
00549 else if (!j->is_sink) { a = a -> sister; break; }
00550 else if (j->TS <= i->TS &&
00551 j->DIST > i->DIST)
00552 {
00553
00554 j -> parent = a -> sister;
00555 j -> TS = i -> TS;
00556 j -> DIST = i -> DIST + 1;
00557 }
00558 }
00559 }
00560
00561 TIME ++;
00562
00563 if (a)
00564 {
00565 i -> next = i;
00566 current_node = i;
00567
00568
00569 augment(a);
00570
00571
00572
00573 while ((np=orphan_first))
00574 {
00575 np_next = np -> next;
00576 np -> next = NULL;
00577
00578 while ((np=orphan_first))
00579 {
00580 orphan_first = np -> next;
00581 i = np -> ptr;
00582 nodeptr_block -> Delete(np);
00583 if (!orphan_first) orphan_last = NULL;
00584 if (i->is_sink) process_sink_orphan(i);
00585 else process_source_orphan(i);
00586 }
00587
00588 orphan_first = np_next;
00589 }
00590
00591 }
00592 else current_node = NULL;
00593 }
00594
00595
00596 if (!reuse_trees || (maxflow_iteration % 64) == 0)
00597 {
00598 delete nodeptr_block;
00599 nodeptr_block = NULL;
00600 }
00601
00602 maxflow_iteration ++;
00603 return flow;
00604 }
00605
00606
00607
00608
00609 template <typename captype, typename tcaptype, typename flowtype>
00610 void Graph<captype,tcaptype,flowtype>::test_consistency(node* current_node)
00611 {
00612 node *i;
00613 arc *a;
00614 int r;
00615 int num1 = 0, num2 = 0;
00616
00617
00618 for (i=nodes; i<node_last; i++)
00619 {
00620 if (i->next || i==current_node) num1 ++;
00621 }
00622 for (r=0; r<3; r++)
00623 {
00624 i = (r == 2) ? current_node : queue_first[r];
00625 if (i)
00626 for ( ; ; i=i->next)
00627 {
00628 num2 ++;
00629 if (i->next == i)
00630 {
00631 if (r<2) assert(i == queue_last[r]);
00632 else assert(i == current_node);
00633 break;
00634 }
00635 }
00636 }
00637 assert(num1 == num2);
00638
00639 for (i=nodes; i<node_last; i++)
00640 {
00641
00642 if (i->parent == NULL) {}
00643 else if (i->parent == ORPHAN) {}
00644 else if (i->parent == TERMINAL)
00645 {
00646 if (!i->is_sink) assert(i->tr_cap > 0);
00647 else assert(i->tr_cap < 0);
00648 }
00649 else
00650 {
00651 if (!i->is_sink) assert (i->parent->sister->r_cap > 0);
00652 else assert (i->parent->r_cap > 0);
00653 }
00654
00655
00656 if (i->parent && !i->next)
00657 {
00658 if (!i->is_sink)
00659 {
00660 assert(i->tr_cap >= 0);
00661 for (a=i->first; a; a=a->next)
00662 {
00663 if (a->r_cap > 0) assert(a->head->parent && !a->head->is_sink);
00664 }
00665 }
00666 else
00667 {
00668 assert(i->tr_cap <= 0);
00669 for (a=i->first; a; a=a->next)
00670 {
00671 if (a->sister->r_cap > 0) assert(a->head->parent && a->head->is_sink);
00672 }
00673 }
00674 }
00675
00676 if (i->parent && i->parent!=ORPHAN && i->parent!=TERMINAL)
00677 {
00678 assert(i->TS <= i->parent->head->TS);
00679 if (i->TS == i->parent->head->TS) assert(i->DIST > i->parent->head->DIST);
00680 }
00681 }
00682 }
00683
00684 template <typename captype, typename tcaptype, typename flowtype>
00685 void Graph<captype,tcaptype,flowtype>::Copy(Graph<captype, tcaptype, flowtype>* g0)
00686 {
00687 node* i;
00688 arc* a;
00689
00690 reset();
00691
00692 if (node_max < nodes + g0->node_num)
00693 {
00694 free(nodes);
00695 nodes = node_last = (node*) malloc(g0->node_num*sizeof(node));
00696 node_max = nodes + g0->node_num;
00697 }
00698 if (arc_max < arcs + (g0->arc_last - g0->arcs))
00699 {
00700 free(arcs);
00701 arcs = arc_last = (arc*) malloc((g0->arc_last - g0->arcs)*sizeof(arc));
00702 arc_max = arcs + (g0->arc_last - g0->arcs);
00703 }
00704
00705 node_num = g0->node_num;
00706 node_last = nodes + node_num;
00707 memcpy(nodes, g0->nodes, node_num*sizeof(node));
00708 for (i=nodes; i<node_last; i++)
00709 {
00710 if (i->first) i->first = (arc*)((char*)arcs + (((char*)i->first) - ((char*)g0->arcs)));
00711 if (i->parent && i->parent!=TERMINAL && i->parent!=ORPHAN) i->parent = (arc*)((char*)arcs + (((char*)i->parent) - ((char*)g0->arcs)));
00712 if (i->next) i->next = (node*)((char*)nodes + (((char*)i->next) - ((char*)g0->nodes)));
00713 }
00714
00715 arc_last = arcs + (g0->arc_last - g0->arcs);
00716 memcpy(arcs, g0->arcs, (g0->arc_last - g0->arcs)*sizeof(arc));
00717 for (a=arcs; a<arc_last; a++)
00718 {
00719 a->head = (node*)((char*)nodes + (((char*)a->head) - ((char*)g0->nodes)));
00720 if (a->next) a->next = (arc*)((char*)arcs + (((char*)a->next) - ((char*)g0->arcs)));
00721 a->sister = (arc*)((char*)arcs + (((char*)a->sister) - ((char*)g0->arcs)));
00722 }
00723
00724 error_function = g0->error_function;
00725 flow = g0->flow;
00726 maxflow_iteration = g0->maxflow_iteration;
00727
00728 queue_first[0] = (g0->queue_first[0]==NULL) ? NULL : (node*)((char*)nodes + (((char*)g0->queue_first[0]) - ((char*)g0->nodes)));
00729 queue_first[1] = (g0->queue_first[1]==NULL) ? NULL : (node*)((char*)nodes + (((char*)g0->queue_first[1]) - ((char*)g0->nodes)));
00730 queue_last[0] = (g0->queue_last[0]==NULL) ? NULL : (node*)((char*)nodes + (((char*)g0->queue_last[0]) - ((char*)g0->nodes)));
00731 queue_last[1] = (g0->queue_last[1]==NULL) ? NULL : (node*)((char*)nodes + (((char*)g0->queue_last[1]) - ((char*)g0->nodes)));
00732 TIME = g0->TIME;
00733 }