graph.h
Go to the documentation of this file.
00001 /* graph.h */
00002 /*
00003         This software library implements the maxflow algorithm
00004         described in
00005 
00006                 "An Experimental Comparison of Min-Cut/Max-Flow Algorithms for Energy Minimization in Vision."
00007                 Yuri Boykov and Vladimir Kolmogorov.
00008                 In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI),
00009                 September 2004
00010 
00011         This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov
00012         at Siemens Corporate Research. To make it available for public use,
00013         it was later reimplemented by Vladimir Kolmogorov based on open publications.
00014 
00015         If you use this software for research purposes, you should cite
00016         the aforementioned paper in any resulting publication.
00017 
00018         ----------------------------------------------------------------------
00019 
00020         REUSING TREES:
00021 
00022         Starting with version 3.0, there is a also an option of reusing search
00023         trees from one maxflow computation to the next, as described in
00024 
00025                 "Efficiently Solving Dynamic Markov Random Fields Using Graph Cuts."
00026                 Pushmeet Kohli and Philip H.S. Torr
00027                 International Conference on Computer Vision (ICCV), 2005
00028 
00029         If you use this option, you should cite
00030         the aforementioned paper in any resulting publication.
00031 */
00032 
00033 
00034 
00035 /*
00036         For description, license, example usage see README.TXT.
00037 */
00038 
00039 #ifndef __GRAPH_H__
00040 #define __GRAPH_H__
00041 
00042 #include <string.h>
00043 #include "block.h"
00044 
00045 #include <assert.h>
00046 // NOTE: in UNIX you need to use -DNDEBUG preprocessor option to supress assert's!!!
00047 
00048 
00049 
00050 // captype: type of edge capacities (excluding t-links)
00051 // tcaptype: type of t-links (edges between nodes and terminals)
00052 // flowtype: type of total flow
00053 //
00054 // Current instantiations are in instances.inc
00055 template <typename captype, typename tcaptype, typename flowtype> class Graph
00056 {
00057 public:
00058         typedef enum
00059         {
00060                 SOURCE  = 0,
00061                 SINK    = 1
00062         } termtype; // terminals
00063         typedef int node_id;
00064 
00066         //                     BASIC INTERFACE FUNCTIONS                       //
00067     //              (should be enough for most applications)               //
00069 
00070         // Constructor.
00071         // The first argument gives an estimate of the maximum number of nodes that can be added
00072         // to the graph, and the second argument is an estimate of the maximum number of edges.
00073         // The last (optional) argument is the pointer to the function which will be called
00074         // if an error occurs; an error message is passed to this function.
00075         // If this argument is omitted, exit(1) will be called.
00076         //
00077         // IMPORTANT: It is possible to add more nodes to the graph than node_num_max
00078         // (and node_num_max can be zero). However, if the count is exceeded, then
00079         // the internal memory is reallocated (increased by 50%) which is expensive.
00080         // Also, temporarily the amount of allocated memory would be more than twice than needed.
00081         // Similarly for edges.
00082         // If you wish to avoid this overhead, you can download version 2.2, where nodes and edges are stored in blocks.
00083         Graph(int node_num_max, int edge_num_max, void (*err_function)(char *) = NULL);
00084 
00085         // Destructor
00086         ~Graph();
00087 
00088         // Adds node(s) to the graph. By default, one node is added (num=1); then first call returns 0, second call returns 1, and so on.
00089         // If num>1, then several nodes are added, and node_id of the first one is returned.
00090         // IMPORTANT: see note about the constructor
00091         node_id add_node(int num = 1);
00092 
00093         // Adds a bidirectional edge between 'i' and 'j' with the weights 'cap' and 'rev_cap'.
00094         // IMPORTANT: see note about the constructor
00095         void add_edge(node_id i, node_id j, captype cap, captype rev_cap);
00096 
00097         // Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights.
00098         // Can be called multiple times for each node.
00099         // Weights can be negative.
00100         // NOTE: the number of such edges is not counted in edge_num_max.
00101         //       No internal memory is allocated by this call.
00102         void add_tweights(node_id i, tcaptype cap_source, tcaptype cap_sink);
00103 
00104 
00105         // Computes the maxflow. Can be called several times.
00106         // FOR DESCRIPTION OF reuse_trees, SEE mark_node().
00107         // FOR DESCRIPTION OF changed_list, SEE remove_from_changed_list().
00108         flowtype maxflow(bool reuse_trees = false, Block<node_id>* changed_list = NULL);
00109 
00110         // After the maxflow is computed, this function returns to which
00111         // segment the node 'i' belongs (Graph<captype,tcaptype,flowtype>::SOURCE or Graph<captype,tcaptype,flowtype>::SINK).
00112         //
00113         // Occasionally there may be several minimum cuts. If a node can be assigned
00114         // to both the source and the sink, then default_segm is returned.
00115         termtype what_segment(node_id i, termtype default_segm = SOURCE);
00116 
00117 
00118 
00120         //       ADVANCED INTERFACE FUNCTIONS       //
00121         //      (provide access to the graph)       //
00123 
00124 private:
00125         struct node;
00126         struct arc;
00127 
00128 public:
00129 
00131         // 1. Reallocating graph. //
00133 
00134         // Removes all nodes and edges.
00135         // After that functions add_node() and add_edge() must be called again.
00136         //
00137         // Advantage compared to deleting Graph and allocating it again:
00138         // no calls to delete/new (which could be quite slow).
00139         //
00140         // If the graph structure stays the same, then an alternative
00141         // is to go through all nodes/edges and set new residual capacities
00142         // (see functions below).
00143         void reset();
00144 
00146         // 2. Functions for getting pointers to arcs and for reading graph structure. //
00147         //    NOTE: adding new arcs may invalidate these pointers (if reallocation    //
00148         //    happens). So it's best not to add arcs while reading graph structure.   //
00150 
00151         // The following two functions return arcs in the same order that they
00152         // were added to the graph. NOTE: for each call add_edge(i,j,cap,cap_rev)
00153         // the first arc returned will be i->j, and the second j->i.
00154         // If there are no more arcs, then the function can still be called, but
00155         // the returned arc_id is undetermined.
00156         typedef arc* arc_id;
00157         arc_id get_first_arc();
00158         arc_id get_next_arc(arc_id a);
00159 
00160         // other functions for reading graph structure
00161         int get_node_num() { return node_num; }
00162         int get_arc_num() { return (int)(arc_last - arcs); }
00163         void get_arc_ends(arc_id a, node_id& i, node_id& j); // returns i,j to that a = i->j
00164 
00166         // 3. Functions for reading residual capacities. //
00168 
00169         // returns residual capacity of SOURCE->i minus residual capacity of i->SINK
00170         tcaptype get_trcap(node_id i);
00171         // returns residual capacity of arc a
00172         captype get_rcap(arc* a);
00173 
00175         // 4. Functions for setting residual capacities.               //
00176         //    NOTE: If these functions are used, the value of the flow //
00177         //    returned by maxflow() will not be valid!                 //
00179 
00180         void set_trcap(node_id i, tcaptype trcap);
00181         void set_rcap(arc* a, captype rcap);
00182 
00184         // 5. Functions related to reusing trees & list of changed nodes. //
00186 
00187         // If flag reuse_trees is true while calling maxflow(), then search trees
00188         // are reused from previous maxflow computation.
00189         // In this case before calling maxflow() the user must
00190         // specify which parts of the graph have changed by calling mark_node():
00191         //   add_tweights(i),set_trcap(i)    => call mark_node(i)
00192         //   add_edge(i,j),set_rcap(a)       => call mark_node(i); mark_node(j)
00193         //
00194         // This option makes sense only if a small part of the graph is changed.
00195         // The initialization procedure goes only through marked nodes then.
00196         //
00197         // mark_node(i) can either be called before or after graph modification.
00198         // Can be called more than once per node, but calls after the first one
00199         // do not have any effect.
00200         //
00201         // NOTE:
00202         //   - This option cannot be used in the first call to maxflow().
00203         //   - It is not necessary to call mark_node() if the change is ``not essential'',
00204         //     i.e. sign(trcap) is preserved for a node and zero/nonzero status is preserved for an arc.
00205         //   - To check that you marked all necessary nodes, you can call maxflow(false) after calling maxflow(true).
00206         //     If everything is correct, the two calls must return the same value of flow. (Useful for debugging).
00207         void mark_node(node_id i);
00208 
00209         // If changed_list is not NULL while calling maxflow(), then the algorithm
00210         // keeps a list of nodes which could potentially have changed their segmentation label.
00211         // Nodes which are not in the list are guaranteed to keep their old segmentation label (SOURCE or SINK).
00212         // Example usage:
00213         //
00214         //              typedef Graph<int,int,int> G;
00215         //              G* g = new Graph(nodeNum, edgeNum);
00216         //              Block<G::node_id>* changed_list = new Block<G::node_id>(128);
00217         //
00218         //              ... // add nodes and edges
00219         //
00220         //              g->maxflow(); // first call should be without arguments
00221         //              for (int iter=0; iter<10; iter++)
00222         //              {
00223         //                      ... // change graph, call mark_node() accordingly
00224         //
00225         //                      g->maxflow(true, changed_list);
00226         //                      G::node_id* ptr;
00227         //                      for (ptr=changed_list->ScanFirst(); ptr; ptr=changed_list->ScanNext())
00228         //                      {
00229         //                              G::node_id i = *ptr; assert(i>=0 && i<nodeNum);
00230         //                              g->remove_from_changed_list(i);
00231         //                              // do something with node i...
00232         //                              if (g->what_segment(i) == G::SOURCE) { ... }
00233         //                      }
00234         //                      changed_list->Reset();
00235         //              }
00236         //              delete changed_list;
00237         //
00238         // NOTE:
00239         //  - If changed_list option is used, then reuse_trees must be used as well.
00240         //  - In the example above, the user may omit calls g->remove_from_changed_list(i) and changed_list->Reset() in a given iteration.
00241         //    Then during the next call to maxflow(true, &changed_list) new nodes will be added to changed_list.
00242         //  - If the next call to maxflow() does not use option reuse_trees, then calling remove_from_changed_list()
00243         //    is not necessary. ("changed_list->Reset()" or "delete changed_list" should still be called, though).
00244         void remove_from_changed_list(node_id i)
00245         {
00246                 assert(i>=0 && i<node_num && nodes[i].is_in_changed_list);
00247                 nodes[i].is_in_changed_list = 0;
00248         }
00249 
00250         void Copy(Graph<captype, tcaptype, flowtype>* g0);
00251 
00252 
00253 
00254 
00258 
00259 private:
00260         // internal variables and functions
00261 
00262         struct node
00263         {
00264                 arc                     *first;         // first outcoming arc
00265 
00266                 arc                     *parent;        // node's parent
00267                 node            *next;          // pointer to the next active node
00268                                                                 //   (or to itself if it is the last node in the list)
00269                 int                     TS;                     // timestamp showing when DIST was computed
00270                 int                     DIST;           // distance to the terminal
00271                 int                     is_sink : 1;    // flag showing whether the node is in the source or in the sink tree (if parent!=NULL)
00272                 int                     is_marked : 1;  // set by mark_node()
00273                 int                     is_in_changed_list : 1; // set by maxflow if
00274 
00275                 tcaptype        tr_cap;         // if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node
00276                                                                 // otherwise         -tr_cap is residual capacity of the arc node->SINK
00277 
00278         };
00279 
00280         struct arc
00281         {
00282                 node            *head;          // node the arc points to
00283                 arc                     *next;          // next arc with the same originating node
00284                 arc                     *sister;        // reverse arc
00285 
00286                 captype         r_cap;          // residual capacity
00287         };
00288 
00289         struct nodeptr
00290         {
00291                 node            *ptr;
00292                 nodeptr         *next;
00293         };
00294         static const int NODEPTR_BLOCK_SIZE = 128;
00295 
00296         node                            *nodes, *node_last, *node_max; // node_last = nodes+node_num, node_max = nodes+node_num_max;
00297         arc                                     *arcs, *arc_last, *arc_max; // arc_last = arcs+2*edge_num, arc_max = arcs+2*edge_num_max;
00298 
00299         int                                     node_num;
00300 
00301         DBlock<nodeptr>         *nodeptr_block;
00302 
00303         void    (*error_function)(char *);      // this function is called if a error occurs,
00304                                                                                 // with a corresponding error message
00305                                                                                 // (or exit(1) is called if it's NULL)
00306 
00307         flowtype                        flow;           // total flow
00308 
00309         // reusing trees & list of changed pixels
00310         int                                     maxflow_iteration; // counter
00311         Block<node_id>          *changed_list;
00312 
00314 
00315         node                            *queue_first[2], *queue_last[2];        // list of active nodes
00316         nodeptr                         *orphan_first, *orphan_last;            // list of pointers to orphans
00317         int                                     TIME;                                                           // monotonically increasing global counter
00318 
00320 
00321         void reallocate_nodes(int num); // num is the number of new nodes
00322         void reallocate_arcs();
00323 
00324         // functions for processing active list
00325         void set_active(node *i);
00326         node *next_active();
00327 
00328         // functions for processing orphans list
00329         void set_orphan_front(node* i); // add to the beginning of the list
00330         void set_orphan_rear(node* i);  // add to the end of the list
00331 
00332         void add_to_changed_list(node* i);
00333 
00334         void maxflow_init();             // called if reuse_trees == false
00335         void maxflow_reuse_trees_init(); // called if reuse_trees == true
00336         void augment(arc *middle_arc);
00337         void process_source_orphan(node *i);
00338         void process_sink_orphan(node *i);
00339 
00340         void test_consistency(node* current_node=NULL); // debug function
00341 };
00342 
00343 
00344 
00345 
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00354 // Implementation - inline functions //
00356 
00357 
00358 
00359 template <typename captype, typename tcaptype, typename flowtype>
00360         inline typename Graph<captype,tcaptype,flowtype>::node_id Graph<captype,tcaptype,flowtype>::add_node(int num)
00361 {
00362         assert(num > 0);
00363 
00364         if (node_last + num > node_max) reallocate_nodes(num);
00365 
00366         if (num == 1)
00367         {
00368                 node_last -> first = NULL;
00369                 node_last -> tr_cap = 0;
00370                 node_last -> is_marked = 0;
00371                 node_last -> is_in_changed_list = 0;
00372 
00373                 node_last ++;
00374                 return node_num ++;
00375         }
00376         else
00377         {
00378                 memset(node_last, 0, num*sizeof(node));
00379 
00380                 node_id i = node_num;
00381                 node_num += num;
00382                 node_last += num;
00383                 return i;
00384         }
00385 }
00386 
00387 template <typename captype, typename tcaptype, typename flowtype>
00388         inline void Graph<captype,tcaptype,flowtype>::add_tweights(node_id i, tcaptype cap_source, tcaptype cap_sink)
00389 {
00390         assert(i >= 0 && i < node_num);
00391         tcaptype delta = nodes[i].tr_cap;
00392         if (delta > 0) cap_source += delta;
00393         else           cap_sink   -= delta;
00394         flow += (cap_source < cap_sink) ? cap_source : cap_sink;
00395         nodes[i].tr_cap = cap_source - cap_sink;
00396 }
00397 
00398 template <typename captype, typename tcaptype, typename flowtype>
00399         inline void Graph<captype,tcaptype,flowtype>::add_edge(node_id _i, node_id _j, captype cap, captype rev_cap)
00400 {
00401         assert(_i >= 0 && _i < node_num);
00402         assert(_j >= 0 && _j < node_num);
00403         assert(_i != _j);
00404         assert(cap >= 0);
00405         assert(rev_cap >= 0);
00406 
00407         if (arc_last == arc_max) reallocate_arcs();
00408 
00409         arc *a = arc_last ++;
00410         arc *a_rev = arc_last ++;
00411 
00412         node* i = nodes + _i;
00413         node* j = nodes + _j;
00414 
00415         a -> sister = a_rev;
00416         a_rev -> sister = a;
00417         a -> next = i -> first;
00418         i -> first = a;
00419         a_rev -> next = j -> first;
00420         j -> first = a_rev;
00421         a -> head = j;
00422         a_rev -> head = i;
00423         a -> r_cap = cap;
00424         a_rev -> r_cap = rev_cap;
00425 }
00426 
00427 template <typename captype, typename tcaptype, typename flowtype>
00428         inline typename Graph<captype,tcaptype,flowtype>::arc* Graph<captype,tcaptype,flowtype>::get_first_arc()
00429 {
00430         return arcs;
00431 }
00432 
00433 template <typename captype, typename tcaptype, typename flowtype>
00434         inline typename Graph<captype,tcaptype,flowtype>::arc* Graph<captype,tcaptype,flowtype>::get_next_arc(arc* a)
00435 {
00436         return a + 1;
00437 }
00438 
00439 template <typename captype, typename tcaptype, typename flowtype>
00440         inline void Graph<captype,tcaptype,flowtype>::get_arc_ends(arc* a, node_id& i, node_id& j)
00441 {
00442         assert(a >= arcs && a < arc_last);
00443         i = (node_id) (a->sister->head - nodes);
00444         j = (node_id) (a->head - nodes);
00445 }
00446 
00447 template <typename captype, typename tcaptype, typename flowtype>
00448         inline tcaptype Graph<captype,tcaptype,flowtype>::get_trcap(node_id i)
00449 {
00450         assert(i>=0 && i<node_num);
00451         return nodes[i].tr_cap;
00452 }
00453 
00454 template <typename captype, typename tcaptype, typename flowtype>
00455         inline captype Graph<captype,tcaptype,flowtype>::get_rcap(arc* a)
00456 {
00457         assert(a >= arcs && a < arc_last);
00458         return a->r_cap;
00459 }
00460 
00461 template <typename captype, typename tcaptype, typename flowtype>
00462         inline void Graph<captype,tcaptype,flowtype>::set_trcap(node_id i, tcaptype trcap)
00463 {
00464         assert(i>=0 && i<node_num);
00465         nodes[i].tr_cap = trcap;
00466 }
00467 
00468 template <typename captype, typename tcaptype, typename flowtype>
00469         inline void Graph<captype,tcaptype,flowtype>::set_rcap(arc* a, captype rcap)
00470 {
00471         assert(a >= arcs && a < arc_last);
00472         a->r_cap = rcap;
00473 }
00474 
00475 
00476 template <typename captype, typename tcaptype, typename flowtype>
00477         inline typename Graph<captype,tcaptype,flowtype>::termtype Graph<captype,tcaptype,flowtype>::what_segment(node_id i, termtype default_segm)
00478 {
00479         if (nodes[i].parent)
00480         {
00481                 return (nodes[i].is_sink) ? SINK : SOURCE;
00482         }
00483         else
00484         {
00485                 return default_segm;
00486         }
00487 }
00488 
00489 template <typename captype, typename tcaptype, typename flowtype>
00490         inline void Graph<captype,tcaptype,flowtype>::mark_node(node_id _i)
00491 {
00492         node* i = nodes + _i;
00493         if (!i->next)
00494         {
00495                 /* it's not in the list yet */
00496                 if (queue_last[1]) queue_last[1] -> next = i;
00497                 else               queue_first[1]        = i;
00498                 queue_last[1] = i;
00499                 i -> next = i;
00500         }
00501         i->is_marked = 1;
00502 }
00503 
00504 
00505 #endif


tabletop_pushing
Author(s): Tucker Hermans
autogenerated on Wed Nov 27 2013 11:59:44