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 }