Read@CVL
graph.h
Go to the documentation of this file.
1 /* graph.h */
2 /*
3  This software library implements the maxflow algorithm
4  described in
5 
6  "An Experimental Comparison of Min-Cut/Max-Flow Algorithms for Energy Minimization in Vision."
7  Yuri Boykov and Vladimir Kolmogorov.
8  In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI),
9  September 2004
10 
11  This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov
12  at Siemens Corporate Research. To make it available for public use,
13  it was later reimplemented by Vladimir Kolmogorov based on open publications.
14 
15  If you use this software for research purposes, you should cite
16  the aforementioned paper in any resulting publication.
17 
18  ----------------------------------------------------------------------
19 
20  REUSING TREES:
21 
22  Starting with version 3.0, there is a also an option of reusing search
23  trees from one maxflow computation to the next, as described in
24 
25  "Efficiently Solving Dynamic Markov Random Fields Using Graph Cuts."
26  Pushmeet Kohli and Philip H.S. Torr
27  International Conference on Computer Vision (ICCV), 2005
28 
29  If you use this option, you should cite
30  the aforementioned paper in any resulting publication.
31 */
32 
33 
34 
35 /*
36  For description, license, example usage see README.TXT.
37 */
38 
39 #ifndef __GRAPH_H__
40 #define __GRAPH_H__
41 
42 #include <string.h>
43 #include "block.h"
44 
45 #include <assert.h>
46 // NOTE: in UNIX you need to use -DNDEBUG preprocessor option to supress assert's!!!
47 
48 
49 
50 // captype: type of edge capacities (excluding t-links)
51 // tcaptype: type of t-links (edges between nodes and terminals)
52 // flowtype: type of total flow
53 //
54 // Current instantiations are in instances.inc
55 template <typename captype, typename tcaptype, typename flowtype> class Graph
56 {
57 public:
58  typedef enum
59  {
60  SOURCE = 0,
61  SINK = 1
62  } termtype; // terminals
63  typedef int node_id;
64 
66  // BASIC INTERFACE FUNCTIONS //
67  // (should be enough for most applications) //
69 
70  // Constructor.
71  // The first argument gives an estimate of the maximum number of nodes that can be added
72  // to the graph, and the second argument is an estimate of the maximum number of edges.
73  // The last (optional) argument is the pointer to the function which will be called
74  // if an error occurs; an error message is passed to this function.
75  // If this argument is omitted, exit(1) will be called.
76  //
77  // IMPORTANT: It is possible to add more nodes to the graph than node_num_max
78  // (and node_num_max can be zero). However, if the count is exceeded, then
79  // the internal memory is reallocated (increased by 50%) which is expensive.
80  // Also, temporarily the amount of allocated memory would be more than twice than needed.
81  // Similarly for edges.
82  // If you wish to avoid this overhead, you can download version 2.2, where nodes and edges are stored in blocks.
83  Graph(int node_num_max, int edge_num_max, void (*err_function)(const char *) = NULL);
84 
85  // Destructor
86  ~Graph();
87 
88  // 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.
89  // If num>1, then several nodes are added, and node_id of the first one is returned.
90  // IMPORTANT: see note about the constructor
91  node_id add_node(int num = 1);
92 
93  // Adds a bidirectional edge between 'i' and 'j' with the weights 'cap' and 'rev_cap'.
94  // IMPORTANT: see note about the constructor
95  void add_edge(node_id i, node_id j, captype cap, captype rev_cap);
96 
97  // Adds new edges 'SOURCE->i' and 'i->SINK' with corresponding weights.
98  // Can be called multiple times for each node.
99  // Weights can be negative.
100  // NOTE: the number of such edges is not counted in edge_num_max.
101  // No internal memory is allocated by this call.
102  void add_tweights(node_id i, tcaptype cap_source, tcaptype cap_sink);
103 
104 
105  // Computes the maxflow. Can be called several times.
106  // FOR DESCRIPTION OF reuse_trees, SEE mark_node().
107  // FOR DESCRIPTION OF changed_list, SEE remove_from_changed_list().
108  flowtype maxflow(bool reuse_trees = false, Block<node_id>* changed_list = NULL);
109 
110  // After the maxflow is computed, this function returns to which
111  // segment the node 'i' belongs (Graph<captype,tcaptype,flowtype>::SOURCE or Graph<captype,tcaptype,flowtype>::SINK).
112  //
113  // Occasionally there may be several minimum cuts. If a node can be assigned
114  // to both the source and the sink, then default_segm is returned.
115  termtype what_segment(node_id i, termtype default_segm = SOURCE);
116 
117 
118 
120  // ADVANCED INTERFACE FUNCTIONS //
121  // (provide access to the graph) //
123 
124 private:
125  struct node;
126  struct arc;
127 
128 public:
129 
131  // 1. Reallocating graph. //
133 
134  // Removes all nodes and edges.
135  // After that functions add_node() and add_edge() must be called again.
136  //
137  // Advantage compared to deleting Graph and allocating it again:
138  // no calls to delete/new (which could be quite slow).
139  //
140  // If the graph structure stays the same, then an alternative
141  // is to go through all nodes/edges and set new residual capacities
142  // (see functions below).
143  void reset();
144 
146  // 2. Functions for getting pointers to arcs and for reading graph structure. //
147  // NOTE: adding new arcs may invalidate these pointers (if reallocation //
148  // happens). So it's best not to add arcs while reading graph structure. //
150 
151  // The following two functions return arcs in the same order that they
152  // were added to the graph. NOTE: for each call add_edge(i,j,cap,cap_rev)
153  // the first arc returned will be i->j, and the second j->i.
154  // If there are no more arcs, then the function can still be called, but
155  // the returned arc_id is undetermined.
156  typedef arc* arc_id;
157  arc_id get_first_arc();
158  arc_id get_next_arc(arc_id a);
159 
160  // other functions for reading graph structure
161  int get_node_num() { return node_num; }
162  int get_arc_num() { return (int)(arc_last - arcs); }
163  void get_arc_ends(arc_id a, node_id& i, node_id& j); // returns i,j to that a = i->j
164 
166  // 3. Functions for reading residual capacities. //
168 
169  // returns residual capacity of SOURCE->i minus residual capacity of i->SINK
170  tcaptype get_trcap(node_id i);
171  // returns residual capacity of arc a
172  captype get_rcap(arc* a);
173 
175  // 4. Functions for setting residual capacities. //
176  // NOTE: If these functions are used, the value of the flow //
177  // returned by maxflow() will not be valid! //
179 
180  void set_trcap(node_id i, tcaptype trcap);
181  void set_rcap(arc* a, captype rcap);
182 
184  // 5. Functions related to reusing trees & list of changed nodes. //
186 
187  // If flag reuse_trees is true while calling maxflow(), then search trees
188  // are reused from previous maxflow computation.
189  // In this case before calling maxflow() the user must
190  // specify which parts of the graph have changed by calling mark_node():
191  // add_tweights(i),set_trcap(i) => call mark_node(i)
192  // add_edge(i,j),set_rcap(a) => call mark_node(i); mark_node(j)
193  //
194  // This option makes sense only if a small part of the graph is changed.
195  // The initialization procedure goes only through marked nodes then.
196  //
197  // mark_node(i) can either be called before or after graph modification.
198  // Can be called more than once per node, but calls after the first one
199  // do not have any effect.
200  //
201  // NOTE:
202  // - This option cannot be used in the first call to maxflow().
203  // - It is not necessary to call mark_node() if the change is ``not essential'',
204  // i.e. sign(trcap) is preserved for a node and zero/nonzero status is preserved for an arc.
205  // - To check that you marked all necessary nodes, you can call maxflow(false) after calling maxflow(true).
206  // If everything is correct, the two calls must return the same value of flow. (Useful for debugging).
207  void mark_node(node_id i);
208 
209  // If changed_list is not NULL while calling maxflow(), then the algorithm
210  // keeps a list of nodes which could potentially have changed their segmentation label.
211  // Nodes which are not in the list are guaranteed to keep their old segmentation label (SOURCE or SINK).
212  // Example usage:
213  //
214  // typedef Graph<int,int,int> G;
215  // G* g = new Graph(nodeNum, edgeNum);
216  // Block<G::node_id>* changed_list = new Block<G::node_id>(128);
217  //
218  // ... // add nodes and edges
219  //
220  // g->maxflow(); // first call should be without arguments
221  // for (int iter=0; iter<10; iter++)
222  // {
223  // ... // change graph, call mark_node() accordingly
224  //
225  // g->maxflow(true, changed_list);
226  // G::node_id* ptr;
227  // for (ptr=changed_list->ScanFirst(); ptr; ptr=changed_list->ScanNext())
228  // {
229  // G::node_id i = *ptr; assert(i>=0 && i<nodeNum);
230  // g->remove_from_changed_list(i);
231  // // do something with node i...
232  // if (g->what_segment(i) == G::SOURCE) { ... }
233  // }
234  // changed_list->Reset();
235  // }
236  // delete changed_list;
237  //
238  // NOTE:
239  // - If changed_list option is used, then reuse_trees must be used as well.
240  // - In the example above, the user may omit calls g->remove_from_changed_list(i) and changed_list->Reset() in a given iteration.
241  // Then during the next call to maxflow(true, &changed_list) new nodes will be added to changed_list.
242  // - If the next call to maxflow() does not use option reuse_trees, then calling remove_from_changed_list()
243  // is not necessary. ("changed_list->Reset()" or "delete changed_list" should still be called, though).
244  void remove_from_changed_list(node_id i)
245  {
246  assert(i>=0 && i<node_num && nodes[i].is_in_changed_list);
247  nodes[i].is_in_changed_list = 0;
248  }
249 
251 
252 
253 
254 
258 
259 private:
260  // internal variables and functions
261 
262  struct node
263  {
264  arc *first; // first outcoming arc
265 
266  arc *parent; // node's parent
267  node *next; // pointer to the next active node
268  // (or to itself if it is the last node in the list)
269  int TS; // timestamp showing when DIST was computed
270  int DIST; // distance to the terminal
271  int is_sink : 1; // flag showing whether the node is in the source or in the sink tree (if parent!=NULL)
272  int is_marked : 1; // set by mark_node()
273  int is_in_changed_list : 1; // set by maxflow if
274 
275  tcaptype tr_cap; // if tr_cap > 0 then tr_cap is residual capacity of the arc SOURCE->node
276  // otherwise -tr_cap is residual capacity of the arc node->SINK
277 
278  };
279 
280  struct arc
281  {
282  node *head; // node the arc points to
283  arc *next; // next arc with the same originating node
284  arc *sister; // reverse arc
285 
286  captype r_cap; // residual capacity
287  };
288 
289  struct nodeptr
290  {
291  node *ptr;
292  nodeptr *next;
293  };
294  static const int NODEPTR_BLOCK_SIZE = 128;
295 
296  node *nodes, *node_last, *node_max; // node_last = nodes+node_num, node_max = nodes+node_num_max;
297  arc *arcs, *arc_last, *arc_max; // arc_last = arcs+2*edge_num, arc_max = arcs+2*edge_num_max;
298 
299  int node_num;
300 
301  DBlock<nodeptr> *nodeptr_block;
302 
303  void (*error_function)(const char *); // this function is called if a error occurs,
304  // with a corresponding error message
305  // (or exit(1) is called if it's NULL)
306 
307  flowtype flow; // total flow
308 
309  // reusing trees & list of changed pixels
310  int maxflow_iteration; // counter
311  Block<node_id> *changed_list;
312 
314 
315  node *queue_first[2], *queue_last[2]; // list of active nodes
316  nodeptr *orphan_first, *orphan_last; // list of pointers to orphans
317  int TIME; // monotonically increasing global counter
318 
320 
321  void reallocate_nodes(int num); // num is the number of new nodes
322  void reallocate_arcs();
323 
324  // functions for processing active list
325  void set_active(node *i);
326  node *next_active();
327 
328  // functions for processing orphans list
329  void set_orphan_front(node* i); // add to the beginning of the list
330  void set_orphan_rear(node* i); // add to the end of the list
331 
332  void add_to_changed_list(node* i);
333 
334  void maxflow_init(); // called if reuse_trees == false
335  void maxflow_reuse_trees_init(); // called if reuse_trees == true
336  void augment(arc *middle_arc);
337  void process_source_orphan(node *i);
338  void process_sink_orphan(node *i);
339 
340  void test_consistency(node* current_node=NULL); // debug function
341 };
342 
343 
344 
345 
346 
347 
348 
349 
350 
351 
352 
354 // Implementation - inline functions //
356 
357 
358 
359 template <typename captype, typename tcaptype, typename flowtype>
361 {
362  assert(num > 0);
363 
364  if (node_last + num > node_max) reallocate_nodes(num);
365 
366  if (num == 1)
367  {
368  node_last -> first = NULL;
369  node_last -> tr_cap = 0;
370  node_last -> is_marked = 0;
371  node_last -> is_in_changed_list = 0;
372 
373  node_last ++;
374  return node_num ++;
375  }
376  else
377  {
378  memset(node_last, 0, num*sizeof(node));
379 
380  node_id i = node_num;
381  node_num += num;
382  node_last += num;
383  return i;
384  }
385 }
386 
387 template <typename captype, typename tcaptype, typename flowtype>
388  inline void Graph<captype,tcaptype,flowtype>::add_tweights(node_id i, tcaptype cap_source, tcaptype cap_sink)
389 {
390  assert(i >= 0 && i < node_num);
391 
392  tcaptype delta = nodes[i].tr_cap;
393  if (delta > 0) cap_source += delta;
394  else cap_sink -= delta;
395  flow += (cap_source < cap_sink) ? cap_source : cap_sink;
396  nodes[i].tr_cap = cap_source - cap_sink;
397 }
398 
399 template <typename captype, typename tcaptype, typename flowtype>
400  inline void Graph<captype,tcaptype,flowtype>::add_edge(node_id _i, node_id _j, captype cap, captype rev_cap)
401 {
402  assert(_i >= 0 && _i < node_num);
403  assert(_j >= 0 && _j < node_num);
404  assert(_i != _j);
405  assert(cap >= 0);
406  assert(rev_cap >= 0);
407 
408  if (arc_last == arc_max) reallocate_arcs();
409 
410  arc *a = arc_last ++;
411  arc *a_rev = arc_last ++;
412 
413  node* i = nodes + _i;
414  node* j = nodes + _j;
415 
416  a -> sister = a_rev;
417  a_rev -> sister = a;
418  a -> next = i -> first;
419  i -> first = a;
420  a_rev -> next = j -> first;
421  j -> first = a_rev;
422  a -> head = j;
423  a_rev -> head = i;
424  a -> r_cap = cap;
425  a_rev -> r_cap = rev_cap;
426 }
427 
428 template <typename captype, typename tcaptype, typename flowtype>
430 {
431  return arcs;
432 }
433 
434 template <typename captype, typename tcaptype, typename flowtype>
436 {
437  return a + 1;
438 }
439 
440 template <typename captype, typename tcaptype, typename flowtype>
441  inline void Graph<captype,tcaptype,flowtype>::get_arc_ends(arc* a, node_id& i, node_id& j)
442 {
443  assert(a >= arcs && a < arc_last);
444  i = (node_id) (a->sister->head - nodes);
445  j = (node_id) (a->head - nodes);
446 }
447 
448 template <typename captype, typename tcaptype, typename flowtype>
450 {
451  assert(i>=0 && i<node_num);
452  return nodes[i].tr_cap;
453 }
454 
455 template <typename captype, typename tcaptype, typename flowtype>
457 {
458  assert(a >= arcs && a < arc_last);
459  return a->r_cap;
460 }
461 
462 template <typename captype, typename tcaptype, typename flowtype>
463  inline void Graph<captype,tcaptype,flowtype>::set_trcap(node_id i, tcaptype trcap)
464 {
465  assert(i>=0 && i<node_num);
466  nodes[i].tr_cap = trcap;
467 }
468 
469 template <typename captype, typename tcaptype, typename flowtype>
470  inline void Graph<captype,tcaptype,flowtype>::set_rcap(arc* a, captype rcap)
471 {
472  assert(a >= arcs && a < arc_last);
473  a->r_cap = rcap;
474 }
475 
476 
477 template <typename captype, typename tcaptype, typename flowtype>
479 {
480  if (nodes[i].parent)
481  {
482  return (nodes[i].is_sink) ? SINK : SOURCE;
483  }
484  else
485  {
486  return default_segm;
487  }
488 }
489 
490 template <typename captype, typename tcaptype, typename flowtype>
492 {
493  node* i = nodes + _i;
494  if (!i->next)
495  {
496  /* it's not in the list yet */
497  if (queue_last[1]) queue_last[1] -> next = i;
498  else queue_first[1] = i;
499  queue_last[1] = i;
500  i -> next = i;
501  }
502  i->is_marked = 1;
503 }
504 
505 
506 #endif
arc_id get_next_arc(arc_id a)
Definition: graph.h:435
void set_rcap(arc *a, captype rcap)
Definition: graph.h:470
arc_id get_first_arc()
Definition: graph.h:429
void add_edge(node_id i, node_id j, captype cap, captype rev_cap)
Definition: graph.h:400
arc * arc_id
Definition: graph.h:156
node_id add_node(int num=1)
Definition: graph.h:360
int get_node_num()
Definition: graph.h:161
void set_trcap(node_id i, tcaptype trcap)
Definition: graph.h:463
void reset()
Definition: graph.cpp:45
int node_id
Definition: graph.h:63
Definition: graph.h:55
void Copy(Graph< captype, tcaptype, flowtype > *g0)
Definition: maxflow.cpp:688
Definition: graph.h:61
void remove_from_changed_list(node_id i)
Definition: graph.h:244
captype get_rcap(arc *a)
Definition: graph.h:456
void add_tweights(node_id i, tcaptype cap_source, tcaptype cap_sink)
Definition: graph.h:388
void get_arc_ends(arc_id a, node_id &i, node_id &j)
Definition: graph.h:441
termtype
Definition: graph.h:58
int get_arc_num()
Definition: graph.h:162
~Graph()
Definition: graph.cpp:33
tcaptype get_trcap(node_id i)
Definition: graph.h:449
flowtype maxflow(bool reuse_trees=false, Block< node_id > *changed_list=NULL)
Definition: maxflow.cpp:475
Graph(int node_num_max, int edge_num_max, void(*err_function)(const char *)=NULL)
Definition: graph.cpp:11
Definition: graph.h:60
termtype what_segment(node_id i, termtype default_segm=SOURCE)
Definition: graph.h:478
void mark_node(node_id i)
Definition: graph.h:491