├── README.md ├── block.h ├── graph.cpp ├── graph.h ├── instances.inc ├── maxflow.cpp ├── mlginstances.inc ├── multilayergraph.cpp └── multilayergraph.h /README.md: -------------------------------------------------------------------------------- 1 | MultiLayerGraph 2 | ================================================================== 3 | 4 | MultiLayerGraph - Software for computing the multilabel problem in a graph 5 | Version 1.0 6 | 7 | https://github.com/liaoxl/MultiLayerGraph 8 | Xiangli Liao(liaoxl2012@gmail.com) 9 | Implemented to make it available for public usage 10 | 2012~2013 11 | 12 | -------------------------------------------------------------------- 13 | 14 | ### 1. Introduction. 15 | 16 | The MultiLayerGraph was firstly proposed in 17 | 18 | "Exact Optimization for Markov Random Fields with Convex Priors" 19 | Hiroshi Ishikawa 20 | In IEEE Transactions on PAMI 21 | October 2003 22 | 23 | which can exactly optimize the multilabel MRF energy. 24 | Bae and Tai devise a similar multilayer graph to solve the multiphase Mumford-Shah model in 25 | 26 | "Graph Cut Optimization for the Piecewise Constant Level Set Method Applied to Multiphase Image Segmentation" 27 | Egil Bae and Xue-Cheng Tai 28 | In The 2nd international conference, SSVM 29 | 2009 30 | 31 | This software is an implementation of the above publications and is applied in some publications of Wenbing Tao (Mentor of **Xiangli Liao**) 32 | 33 | This MultiLayerGraph library implements the maxflow algorithm described in 34 | 35 | "Interactively multiphase image segmentation based on variational formulation and graph cuts" 36 | Wenbing Tao, Feng Chang, Liman Liu, Hai Jin, Tianjiang Wang 37 | In Pattern Recognition 38 | October 2010 39 | 40 | This algorithm was proposed by Wenbing Tao in Academic Research. 41 | To make it available for public use, 42 | it was later implemented by **Xiangli Liao** based on open publications. 43 | 44 | If you use this software for research purposes, you should cite 45 | the aforementioned paper in any resulting publication. 46 | 47 | --------------------------------------------------------------------- 48 | 49 | ### 2. Related Works. 50 | 51 | Our work is based on the public available source code `MAXFLOW` developed by Boykov and Kolmogorov 52 | 53 | MAXFLOW - software for computing mincut/maxflow in a graph 54 | Version 3.01 55 | http://www.cs.ucl.ac.uk/staff/V.Kolmogorov/software.html 56 | 57 | Yuri Boykov (yuri@csd.uwo.ca) 58 | Vladimir Kolmogorov (v.kolmogorov@cs.ucl.ac.uk) 59 | 2001-2006 60 | 61 | ------------------------------------------------------------------------- 62 | 63 | "An Experimental Comparison of Min-Cut/Max-Flow Algorithms for Energy Minimization in Vision." 64 | Yuri Boykov and Vladimir Kolmogorov. 65 | In IEEE Transactions on Pattern Analysis and Machine Intelligence (PAMI), 66 | September 2004 67 | 68 | This algorithm was developed by Yuri Boykov and Vladimir Kolmogorov 69 | at Siemens Corporate Research. To make it available for public use, 70 | it was later reimplemented by Vladimir Kolmogorov based on open publications. 71 | 72 | If you use this software for research purposes, you should cite 73 | the aforementioned paper in any resulting publication. 74 | 75 | ---------------------------------------------------------------------- 76 | 77 | REUSING TREES: 78 | 79 | Starting with version 3.0, there is a also an option of reusing search 80 | trees from one maxflow computation to the next, as described in 81 | 82 | "Efficiently Solving Dynamic Markov Random Fields Using Graph Cuts." 83 | Pushmeet Kohli and Philip H.S. Torr 84 | International Conference on Computer Vision (ICCV), 2005 85 | 86 | If you use this option, you should cite 87 | the aforementioned paper in any resulting publication. 88 | 89 | Tested under windows, Visual C++ 6.0 compiler and unix (SunOS 5.8 90 | and RedHat Linux 7.0, GNU c++ compiler). 91 | 92 | ---------------------------------------------------------------------- 93 | 94 | ### 3. Example usage. 95 | 96 | This section shows how to use the library to compute 97 | a minimum cut on the following graph: 98 | 99 | ---------------------------------------------------------------- 100 | 101 | SOURCE Node_Layer 0 102 | / | | \ 103 | 2 / 5 | 4| 1\ Layer 1 104 | / | | \ 105 | n0 --- n1 --- n2 --- n3 Node_Layer 1 106 | | 2 | 4 | 2 | 107 | 4| 2 | 2| 4| Layer 2 108 | | | | | 109 | n0 --- n1 --- n2 --- n3 Node_Layer 2 110 | \ 2 | 4 | 2 / 111 | 1 \ 5 | 3| 2/ Layer 3 112 | \ | | / 113 | SINK Node_Layer 3 114 | 115 | ---------------------------------------------------------------- 116 | 117 | 118 | #include 119 | #include "multilayergraph.h" 120 | #include 121 | 122 | 123 | using namespace std; 124 | 125 | 126 | int main() 127 | { 128 | typedef MultiLayerGraph GraphType; 129 | int node_num=4; 130 | int edge_num=3; 131 | int label_num=3; 132 | 133 | float node[][3]={{2,4,1},{5,2,5},{4,2,3},{1,4,2}}; 134 | float edge[3]={2,4,2}; 135 | 136 | MultiLayerGraph *mg=new GraphType(node_num,edge_num,label_num); 137 | 138 | for(int i=0; iadd_node(); 141 | } 142 | 143 | for(int i=0; iadd_tweights(i,j,cap); 150 | } 151 | } 152 | cout << endl; 153 | 154 | int head, tail; 155 | for(int i=0; iadd_edge(head,tail,cap,cap); 164 | } 165 | } 166 | cout << endl; 167 | cout << "Energy is : " << mg->maxflow() << endl; 168 | for(int i=0; iwhat_segment(i) << endl; 171 | } 172 | return 0; 173 | } 174 | 175 | ---------------------------------------------------------------------- 176 | -------------------------------------------------------------------------------- /block.h: -------------------------------------------------------------------------------- 1 | /* block.h */ 2 | /* 3 | Template classes Block and DBlock 4 | Implement adding and deleting items of the same type in blocks. 5 | 6 | If there there are many items then using Block or DBlock 7 | is more efficient than using 'new' and 'delete' both in terms 8 | of memory and time since 9 | (1) On some systems there is some minimum amount of memory 10 | that 'new' can allocate (e.g., 64), so if items are 11 | small that a lot of memory is wasted. 12 | (2) 'new' and 'delete' are designed for items of varying size. 13 | If all items has the same size, then an algorithm for 14 | adding and deleting can be made more efficient. 15 | (3) All Block and DBlock functions are inline, so there are 16 | no extra function calls. 17 | 18 | Differences between Block and DBlock: 19 | (1) DBlock allows both adding and deleting items, 20 | whereas Block allows only adding items. 21 | (2) Block has an additional operation of scanning 22 | items added so far (in the order in which they were added). 23 | (3) Block allows to allocate several consecutive 24 | items at a time, whereas DBlock can add only a single item. 25 | 26 | Note that no constructors or destructors are called for items. 27 | 28 | Example usage for items of type 'MyType': 29 | 30 | /////////////////////////////////////////////////// 31 | #include "block.h" 32 | #define BLOCK_SIZE 1024 33 | typedef struct { int a, b; } MyType; 34 | MyType *ptr, *array[10000]; 35 | 36 | ... 37 | 38 | Block *block = new Block(BLOCK_SIZE); 39 | 40 | // adding items 41 | for (int i=0; i New(); 44 | ptr -> a = ptr -> b = rand(); 45 | } 46 | 47 | // reading items 48 | for (ptr=block->ScanFirst(); ptr; ptr=block->ScanNext()) 49 | { 50 | printf("%d %d\n", ptr->a, ptr->b); 51 | } 52 | 53 | delete block; 54 | 55 | ... 56 | 57 | DBlock *dblock = new DBlock(BLOCK_SIZE); 58 | 59 | // adding items 60 | for (int i=0; i New(); 63 | } 64 | 65 | // deleting items 66 | for (int i=0; i Delete(array[i]); 69 | } 70 | 71 | // adding items 72 | for (int i=0; i New(); 75 | } 76 | 77 | delete dblock; 78 | 79 | /////////////////////////////////////////////////// 80 | 81 | Note that DBlock deletes items by marking them as 82 | empty (i.e., by adding them to the list of free items), 83 | so that this memory could be used for subsequently 84 | added items. Thus, at each moment the memory allocated 85 | is determined by the maximum number of items allocated 86 | simultaneously at earlier moments. All memory is 87 | deallocated only when the destructor is called. 88 | */ 89 | 90 | #ifndef __BLOCK_H__ 91 | #define __BLOCK_H__ 92 | 93 | #include 94 | 95 | /***********************************************************************/ 96 | /***********************************************************************/ 97 | /***********************************************************************/ 98 | 99 | template class Block 100 | { 101 | public: 102 | /* Constructor. Arguments are the block size and 103 | (optionally) the pointer to the function which 104 | will be called if allocation failed; the message 105 | passed to this function is "Not enough memory!" */ 106 | Block(int size, void (*err_function)(char *) = NULL) { first = last = NULL; block_size = size; error_function = err_function; } 107 | 108 | /* Destructor. Deallocates all items added so far */ 109 | ~Block() { while (first) { block *next = first -> next; delete[] ((char*)first); first = next; } } 110 | 111 | /* Allocates 'num' consecutive items; returns pointer 112 | to the first item. 'num' cannot be greater than the 113 | block size since items must fit in one block */ 114 | Type *New(int num = 1) 115 | { 116 | Type *t; 117 | 118 | if (!last || last->current + num > last->last) 119 | { 120 | if (last && last->next) last = last -> next; 121 | else 122 | { 123 | block *next = (block *) new char [sizeof(block) + (block_size-1)*sizeof(Type)]; 124 | if (!next) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 125 | if (last) last -> next = next; 126 | else first = next; 127 | last = next; 128 | last -> current = & ( last -> data[0] ); 129 | last -> last = last -> current + block_size; 130 | last -> next = NULL; 131 | } 132 | } 133 | 134 | t = last -> current; 135 | last -> current += num; 136 | return t; 137 | } 138 | 139 | /* Returns the first item (or NULL, if no items were added) */ 140 | Type *ScanFirst() 141 | { 142 | for (scan_current_block=first; scan_current_block; scan_current_block = scan_current_block->next) 143 | { 144 | scan_current_data = & ( scan_current_block -> data[0] ); 145 | if (scan_current_data < scan_current_block -> current) return scan_current_data ++; 146 | } 147 | return NULL; 148 | } 149 | 150 | /* Returns the next item (or NULL, if all items have been read) 151 | Can be called only if previous ScanFirst() or ScanNext() 152 | call returned not NULL. */ 153 | Type *ScanNext() 154 | { 155 | while (scan_current_data >= scan_current_block -> current) 156 | { 157 | scan_current_block = scan_current_block -> next; 158 | if (!scan_current_block) return NULL; 159 | scan_current_data = & ( scan_current_block -> data[0] ); 160 | } 161 | return scan_current_data ++; 162 | } 163 | 164 | /* Marks all elements as empty */ 165 | void Reset() 166 | { 167 | block *b; 168 | if (!first) return; 169 | for (b=first; ; b=b->next) 170 | { 171 | b -> current = & ( b -> data[0] ); 172 | if (b == last) break; 173 | } 174 | last = first; 175 | } 176 | 177 | /***********************************************************************/ 178 | 179 | private: 180 | 181 | typedef struct block_st 182 | { 183 | Type *current, *last; 184 | struct block_st *next; 185 | Type data[1]; 186 | } block; 187 | 188 | int block_size; 189 | block *first; 190 | block *last; 191 | 192 | block *scan_current_block; 193 | Type *scan_current_data; 194 | 195 | void (*error_function)(char *); 196 | }; 197 | 198 | /***********************************************************************/ 199 | /***********************************************************************/ 200 | /***********************************************************************/ 201 | 202 | template class DBlock 203 | { 204 | public: 205 | /* Constructor. Arguments are the block size and 206 | (optionally) the pointer to the function which 207 | will be called if allocation failed; the message 208 | passed to this function is "Not enough memory!" */ 209 | DBlock(int size, void (*err_function)(char *) = NULL) { first = NULL; first_free = NULL; block_size = size; error_function = err_function; } 210 | 211 | /* Destructor. Deallocates all items added so far */ 212 | ~DBlock() { while (first) { block *next = first -> next; delete[] ((char*)first); first = next; } } 213 | 214 | /* Allocates one item */ 215 | Type *New() 216 | { 217 | block_item *item; 218 | 219 | if (!first_free) 220 | { 221 | block *next = first; 222 | first = (block *) new char [sizeof(block) + (block_size-1)*sizeof(block_item)]; 223 | if (!first) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 224 | first_free = & (first -> data[0] ); 225 | for (item=first_free; item next_free = item + 1; 227 | item -> next_free = NULL; 228 | first -> next = next; 229 | } 230 | 231 | item = first_free; 232 | first_free = item -> next_free; 233 | return (Type *) item; 234 | } 235 | 236 | /* Deletes an item allocated previously */ 237 | void Delete(Type *t) 238 | { 239 | ((block_item *) t) -> next_free = first_free; 240 | first_free = (block_item *) t; 241 | } 242 | 243 | /***********************************************************************/ 244 | 245 | private: 246 | 247 | typedef union block_item_st 248 | { 249 | Type t; 250 | block_item_st *next_free; 251 | } block_item; 252 | 253 | typedef struct block_st 254 | { 255 | struct block_st *next; 256 | block_item data[1]; 257 | } block; 258 | 259 | int block_size; 260 | block *first; 261 | block_item *first_free; 262 | 263 | void (*error_function)(char *); 264 | }; 265 | 266 | 267 | #endif 268 | 269 | -------------------------------------------------------------------------------- /graph.cpp: -------------------------------------------------------------------------------- 1 | /* graph.cpp */ 2 | 3 | 4 | #include 5 | #include 6 | #include 7 | #include "graph.h" 8 | 9 | 10 | template 11 | Graph::Graph(int node_num_max, int edge_num_max, void (*err_function)(char *)) 12 | : node_num(0), 13 | nodeptr_block(NULL), 14 | error_function(err_function) 15 | { 16 | if (node_num_max < 16) node_num_max = 16; 17 | if (edge_num_max < 16) edge_num_max = 16; 18 | 19 | nodes = (node*) malloc(node_num_max*sizeof(node)); 20 | arcs = (arc*) malloc(2*edge_num_max*sizeof(arc)); 21 | if (!nodes || !arcs) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 22 | 23 | node_last = nodes; 24 | node_max = nodes + node_num_max; 25 | arc_last = arcs; 26 | arc_max = arcs + 2*edge_num_max; 27 | 28 | maxflow_iteration = 0; 29 | flow = 0; 30 | } 31 | 32 | template 33 | Graph::~Graph() 34 | { 35 | if (nodeptr_block) 36 | { 37 | delete nodeptr_block; 38 | nodeptr_block = NULL; 39 | } 40 | free(nodes); 41 | free(arcs); 42 | } 43 | 44 | template 45 | void Graph::reset() 46 | { 47 | node_last = nodes; 48 | arc_last = arcs; 49 | node_num = 0; 50 | 51 | if (nodeptr_block) 52 | { 53 | delete nodeptr_block; 54 | nodeptr_block = NULL; 55 | } 56 | 57 | maxflow_iteration = 0; 58 | flow = 0; 59 | } 60 | 61 | template 62 | void Graph::reallocate_nodes(int num) 63 | { 64 | int node_num_max = (int)(node_max - nodes); 65 | node* nodes_old = nodes; 66 | 67 | node_num_max += node_num_max / 2; 68 | if (node_num_max < node_num + num) node_num_max = node_num + num; 69 | nodes = (node*) realloc(nodes_old, node_num_max*sizeof(node)); 70 | if (!nodes) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 71 | 72 | node_last = nodes + node_num; 73 | node_max = nodes + node_num_max; 74 | 75 | if (nodes != nodes_old) 76 | { 77 | arc* a; 78 | for (a=arcs; ahead = (node*) ((char*)a->head + (((char*) nodes) - ((char*) nodes_old))); 81 | } 82 | } 83 | } 84 | 85 | template 86 | void Graph::reallocate_arcs() 87 | { 88 | int arc_num_max = (int)(arc_max - arcs); 89 | int arc_num = (int)(arc_last - arcs); 90 | arc* arcs_old = arcs; 91 | 92 | arc_num_max += arc_num_max / 2; if (arc_num_max & 1) arc_num_max ++; 93 | arcs = (arc*) realloc(arcs_old, arc_num_max*sizeof(arc)); 94 | if (!arcs) { if (error_function) (*error_function)("Not enough memory!"); exit(1); } 95 | 96 | arc_last = arcs + arc_num; 97 | arc_max = arcs + arc_num_max; 98 | 99 | if (arcs != arcs_old) 100 | { 101 | node* i; 102 | arc* a; 103 | for (i=nodes; ifirst) i->first = (arc*) ((char*)i->first + (((char*) arcs) - ((char*) arcs_old))); 106 | } 107 | for (a=arcs; anext) a->next = (arc*) ((char*)a->next + (((char*) arcs) - ((char*) arcs_old))); 110 | a->sister = (arc*) ((char*)a->sister + (((char*) arcs) - ((char*) arcs_old))); 111 | } 112 | } 113 | } 114 | 115 | #include "instances.inc" 116 | -------------------------------------------------------------------------------- /graph.h: -------------------------------------------------------------------------------- 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 43 | #include "block.h" 44 | 45 | #include 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 class Graph 56 | { 57 | public: 58 | typedef enum 59 | { 60 | SOURCE = 0, 61 | SINK = 1 62 | } termtype; // terminals 63 | typedef int node_id; 64 | 65 | ///////////////////////////////////////////////////////////////////////// 66 | // BASIC INTERFACE FUNCTIONS // 67 | // (should be enough for most applications) // 68 | ///////////////////////////////////////////////////////////////////////// 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)(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* changed_list = NULL); 109 | 110 | // After the maxflow is computed, this function returns to which 111 | // segment the node 'i' belongs (Graph::SOURCE or Graph::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 | 119 | ////////////////////////////////////////////// 120 | // ADVANCED INTERFACE FUNCTIONS // 121 | // (provide access to the graph) // 122 | ////////////////////////////////////////////// 123 | 124 | public: 125 | struct node; 126 | struct arc; 127 | 128 | public: 129 | 130 | //////////////////////////// 131 | // 1. Reallocating graph. // 132 | //////////////////////////// 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 | 145 | //////////////////////////////////////////////////////////////////////////////// 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. // 149 | //////////////////////////////////////////////////////////////////////////////// 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 | 165 | /////////////////////////////////////////////////// 166 | // 3. Functions for reading residual capacities. // 167 | /////////////////////////////////////////////////// 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 | 174 | ///////////////////////////////////////////////////////////////// 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! // 178 | ///////////////////////////////////////////////////////////////// 179 | 180 | void set_trcap(node_id i, tcaptype trcap); 181 | void set_rcap(arc* a, captype rcap); 182 | 183 | //////////////////////////////////////////////////////////////////// 184 | // 5. Functions related to reusing trees & list of changed nodes. // 185 | //////////////////////////////////////////////////////////////////// 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 G; 215 | // G* g = new Graph(nodeNum, edgeNum); 216 | // Block* changed_list = new Block(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 && iremove_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 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_block; 302 | 303 | void (*error_function)(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 *changed_list; 312 | 313 | ///////////////////////////////////////////////////////////////////////// 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 | 319 | ///////////////////////////////////////////////////////////////////////// 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 | 353 | /////////////////////////////////////// 354 | // Implementation - inline functions // 355 | /////////////////////////////////////// 356 | 357 | 358 | 359 | template 360 | inline typename Graph::node_id Graph::add_node(int num) 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 388 | inline void Graph::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 400 | inline void Graph::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 429 | inline typename Graph::arc* Graph::get_first_arc() 430 | { 431 | return arcs; 432 | } 433 | 434 | template 435 | inline typename Graph::arc* Graph::get_next_arc(arc* a) 436 | { 437 | return a + 1; 438 | } 439 | 440 | template 441 | inline void Graph::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 449 | inline tcaptype Graph::get_trcap(node_id i) 450 | { 451 | assert(i>=0 && i 456 | inline captype Graph::get_rcap(arc* a) 457 | { 458 | assert(a >= arcs && a < arc_last); 459 | return a->r_cap; 460 | } 461 | 462 | template 463 | inline void Graph::set_trcap(node_id i, tcaptype trcap) 464 | { 465 | assert(i>=0 && i 470 | inline void Graph::set_rcap(arc* a, captype rcap) 471 | { 472 | assert(a >= arcs && a < arc_last); 473 | a->r_cap = rcap; 474 | } 475 | 476 | 477 | template 478 | inline typename Graph::termtype Graph::what_segment(node_id i, termtype default_segm) 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 491 | inline void Graph::mark_node(node_id _i) 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 507 | -------------------------------------------------------------------------------- /instances.inc: -------------------------------------------------------------------------------- 1 | #include "graph.h" 2 | 3 | #ifdef _MSC_VER 4 | #pragma warning(disable: 4661) 5 | #endif 6 | 7 | // Instantiations: 8 | // IMPORTANT: 9 | // flowtype should be 'larger' than tcaptype 10 | // tcaptype should be 'larger' than captype 11 | 12 | template class Graph; 13 | template class Graph; 14 | template class Graph; 15 | template class Graph; 16 | 17 | -------------------------------------------------------------------------------- /maxflow.cpp: -------------------------------------------------------------------------------- 1 | /* maxflow.cpp */ 2 | 3 | 4 | #include 5 | #include "graph.h" 6 | 7 | 8 | /* 9 | special constants for node->parent 10 | */ 11 | #define TERMINAL ( (arc *) 1 ) /* to terminal */ 12 | #define ORPHAN ( (arc *) 2 ) /* orphan */ 13 | 14 | 15 | #define INFINITE_D ((int)(((unsigned)-1)/2)) /* infinite distance to the terminal */ 16 | 17 | /***********************************************************************/ 18 | 19 | /* 20 | Functions for processing active list. 21 | i->next points to the next node in the list 22 | (or to i, if i is the last node in the list). 23 | If i->next is NULL iff i is not in the list. 24 | 25 | There are two queues. Active nodes are added 26 | to the end of the second queue and read from 27 | the front of the first queue. If the first queue 28 | is empty, it is replaced by the second queue 29 | (and the second queue becomes empty). 30 | */ 31 | 32 | 33 | template 34 | inline void Graph::set_active(node *i) 35 | { 36 | if (!i->next) 37 | { 38 | /* it's not in the list yet */ 39 | if (queue_last[1]) queue_last[1] -> next = i; 40 | else queue_first[1] = i; 41 | queue_last[1] = i; 42 | i -> next = i; 43 | } 44 | } 45 | 46 | /* 47 | Returns the next active node. 48 | If it is connected to the sink, it stays in the list, 49 | otherwise it is removed from the list 50 | */ 51 | template 52 | inline typename Graph::node* Graph::next_active() 53 | { 54 | node *i; 55 | 56 | while ( 1 ) 57 | { 58 | if (!(i=queue_first[0])) 59 | { 60 | queue_first[0] = i = queue_first[1]; 61 | queue_last[0] = queue_last[1]; 62 | queue_first[1] = NULL; 63 | queue_last[1] = NULL; 64 | if (!i) return NULL; 65 | } 66 | 67 | /* remove it from the active list */ 68 | if (i->next == i) queue_first[0] = queue_last[0] = NULL; 69 | else queue_first[0] = i -> next; 70 | i -> next = NULL; 71 | 72 | /* a node in the list is active iff it has a parent */ 73 | if (i->parent) return i; 74 | } 75 | } 76 | 77 | /***********************************************************************/ 78 | 79 | template 80 | inline void Graph::set_orphan_front(node *i) 81 | { 82 | nodeptr *np; 83 | i -> parent = ORPHAN; 84 | np = nodeptr_block -> New(); 85 | np -> ptr = i; 86 | np -> next = orphan_first; 87 | orphan_first = np; 88 | } 89 | 90 | template 91 | inline void Graph::set_orphan_rear(node *i) 92 | { 93 | nodeptr *np; 94 | i -> parent = ORPHAN; 95 | np = nodeptr_block -> New(); 96 | np -> ptr = i; 97 | if (orphan_last) orphan_last -> next = np; 98 | else orphan_first = np; 99 | orphan_last = np; 100 | np -> next = NULL; 101 | } 102 | 103 | /***********************************************************************/ 104 | 105 | template 106 | inline void Graph::add_to_changed_list(node *i) 107 | { 108 | if (changed_list && !i->is_in_changed_list) 109 | { 110 | node_id* ptr = changed_list->New(); 111 | *ptr = (node_id)(i - nodes); 112 | i->is_in_changed_list = true; 113 | } 114 | } 115 | 116 | /***********************************************************************/ 117 | 118 | template 119 | void Graph::maxflow_init() 120 | { 121 | node *i; 122 | 123 | queue_first[0] = queue_last[0] = NULL; 124 | queue_first[1] = queue_last[1] = NULL; 125 | orphan_first = NULL; 126 | 127 | TIME = 0; 128 | 129 | for (i=nodes; i next = NULL; 132 | i -> is_marked = 0; 133 | i -> is_in_changed_list = 0; 134 | i -> TS = TIME; 135 | if (i->tr_cap > 0) 136 | { 137 | /* i is connected to the source */ 138 | i -> is_sink = 0; 139 | i -> parent = TERMINAL; 140 | set_active(i); 141 | i -> DIST = 1; 142 | } 143 | else if (i->tr_cap < 0) 144 | { 145 | /* i is connected to the sink */ 146 | i -> is_sink = 1; 147 | i -> parent = TERMINAL; 148 | set_active(i); 149 | i -> DIST = 1; 150 | } 151 | else 152 | { 153 | i -> parent = NULL; 154 | } 155 | } 156 | } 157 | 158 | template 159 | void Graph::maxflow_reuse_trees_init() 160 | { 161 | node* i; 162 | node* j; 163 | node* queue = queue_first[1]; 164 | arc* a; 165 | nodeptr* np; 166 | 167 | queue_first[0] = queue_last[0] = NULL; 168 | queue_first[1] = queue_last[1] = NULL; 169 | orphan_first = orphan_last = NULL; 170 | 171 | TIME ++; 172 | 173 | while ((i=queue)) 174 | { 175 | queue = i->next; 176 | if (queue == i) queue = NULL; 177 | i->next = NULL; 178 | i->is_marked = 0; 179 | set_active(i); 180 | 181 | if (i->tr_cap == 0) 182 | { 183 | if (i->parent) set_orphan_rear(i); 184 | continue; 185 | } 186 | 187 | if (i->tr_cap > 0) 188 | { 189 | if (!i->parent || i->is_sink) 190 | { 191 | i->is_sink = 0; 192 | for (a=i->first; a; a=a->next) 193 | { 194 | j = a->head; 195 | if (!j->is_marked) 196 | { 197 | if (j->parent == a->sister) set_orphan_rear(j); 198 | if (j->parent && j->is_sink && a->r_cap > 0) set_active(j); 199 | } 200 | } 201 | add_to_changed_list(i); 202 | } 203 | } 204 | else 205 | { 206 | if (!i->parent || !i->is_sink) 207 | { 208 | i->is_sink = 1; 209 | for (a=i->first; a; a=a->next) 210 | { 211 | j = a->head; 212 | if (!j->is_marked) 213 | { 214 | if (j->parent == a->sister) set_orphan_rear(j); 215 | if (j->parent && !j->is_sink && a->sister->r_cap > 0) set_active(j); 216 | } 217 | } 218 | add_to_changed_list(i); 219 | } 220 | } 221 | i->parent = TERMINAL; 222 | i -> TS = TIME; 223 | i -> DIST = 1; 224 | } 225 | 226 | //test_consistency(); 227 | 228 | /* adoption */ 229 | while ((np=orphan_first)) 230 | { 231 | orphan_first = np -> next; 232 | i = np -> ptr; 233 | nodeptr_block -> Delete(np); 234 | if (!orphan_first) orphan_last = NULL; 235 | if (i->is_sink) process_sink_orphan(i); 236 | else process_source_orphan(i); 237 | } 238 | /* adoption end */ 239 | 240 | //test_consistency(); 241 | } 242 | 243 | template 244 | void Graph::augment(arc *middle_arc) 245 | { 246 | node *i; 247 | arc *a; 248 | tcaptype bottleneck; 249 | 250 | 251 | /* 1. Finding bottleneck capacity */ 252 | /* 1a - the source tree */ 253 | bottleneck = middle_arc -> r_cap; 254 | for (i=middle_arc->sister->head; ; i=a->head) 255 | { 256 | a = i -> parent; 257 | if (a == TERMINAL) break; 258 | if (bottleneck > a->sister->r_cap) bottleneck = a -> sister -> r_cap; 259 | } 260 | if (bottleneck > i->tr_cap) bottleneck = i -> tr_cap; 261 | /* 1b - the sink tree */ 262 | for (i=middle_arc->head; ; i=a->head) 263 | { 264 | a = i -> parent; 265 | if (a == TERMINAL) break; 266 | if (bottleneck > a->r_cap) bottleneck = a -> r_cap; 267 | } 268 | if (bottleneck > - i->tr_cap) bottleneck = - i -> tr_cap; 269 | 270 | 271 | /* 2. Augmenting */ 272 | /* 2a - the source tree */ 273 | middle_arc -> sister -> r_cap += bottleneck; 274 | middle_arc -> r_cap -= bottleneck; 275 | for (i=middle_arc->sister->head; ; i=a->head) 276 | { 277 | a = i -> parent; 278 | if (a == TERMINAL) break; 279 | a -> r_cap += bottleneck; 280 | a -> sister -> r_cap -= bottleneck; 281 | if (!a->sister->r_cap) 282 | { 283 | set_orphan_front(i); // add i to the beginning of the adoption list 284 | } 285 | } 286 | i -> tr_cap -= bottleneck; 287 | if (!i->tr_cap) 288 | { 289 | set_orphan_front(i); // add i to the beginning of the adoption list 290 | } 291 | /* 2b - the sink tree */ 292 | for (i=middle_arc->head; ; i=a->head) 293 | { 294 | a = i -> parent; 295 | if (a == TERMINAL) break; 296 | a -> sister -> r_cap += bottleneck; 297 | a -> r_cap -= bottleneck; 298 | if (!a->r_cap) 299 | { 300 | set_orphan_front(i); // add i to the beginning of the adoption list 301 | } 302 | } 303 | i -> tr_cap += bottleneck; 304 | if (!i->tr_cap) 305 | { 306 | set_orphan_front(i); // add i to the beginning of the adoption list 307 | } 308 | 309 | 310 | flow += bottleneck; 311 | } 312 | 313 | /***********************************************************************/ 314 | 315 | template 316 | void Graph::process_source_orphan(node *i) 317 | { 318 | node *j; 319 | arc *a0, *a0_min = NULL, *a; 320 | int d, d_min = INFINITE_D; 321 | 322 | /* trying to find a new parent */ 323 | for (a0=i->first; a0; a0=a0->next) 324 | if (a0->sister->r_cap) 325 | { 326 | j = a0 -> head; 327 | if (!j->is_sink && (a=j->parent)) 328 | { 329 | /* checking the origin of j */ 330 | d = 0; 331 | while ( 1 ) 332 | { 333 | if (j->TS == TIME) 334 | { 335 | d += j -> DIST; 336 | break; 337 | } 338 | a = j -> parent; 339 | d ++; 340 | if (a==TERMINAL) 341 | { 342 | j -> TS = TIME; 343 | j -> DIST = 1; 344 | break; 345 | } 346 | if (a==ORPHAN) { d = INFINITE_D; break; } 347 | j = a -> head; 348 | } 349 | if (dhead; j->TS!=TIME; j=j->parent->head) 358 | { 359 | j -> TS = TIME; 360 | j -> DIST = d --; 361 | } 362 | } 363 | } 364 | } 365 | 366 | if (i->parent = a0_min) 367 | { 368 | i -> TS = TIME; 369 | i -> DIST = d_min + 1; 370 | } 371 | else 372 | { 373 | /* no parent is found */ 374 | add_to_changed_list(i); 375 | 376 | /* process neighbors */ 377 | for (a0=i->first; a0; a0=a0->next) 378 | { 379 | j = a0 -> head; 380 | if (!j->is_sink && (a=j->parent)) 381 | { 382 | if (a0->sister->r_cap) set_active(j); 383 | if (a!=TERMINAL && a!=ORPHAN && a->head==i) 384 | { 385 | set_orphan_rear(j); // add j to the end of the adoption list 386 | } 387 | } 388 | } 389 | } 390 | } 391 | 392 | template 393 | void Graph::process_sink_orphan(node *i) 394 | { 395 | node *j; 396 | arc *a0, *a0_min = NULL, *a; 397 | int d, d_min = INFINITE_D; 398 | 399 | /* trying to find a new parent */ 400 | for (a0=i->first; a0; a0=a0->next) 401 | if (a0->r_cap) 402 | { 403 | j = a0 -> head; 404 | if (j->is_sink && (a=j->parent)) 405 | { 406 | /* checking the origin of j */ 407 | d = 0; 408 | while ( 1 ) 409 | { 410 | if (j->TS == TIME) 411 | { 412 | d += j -> DIST; 413 | break; 414 | } 415 | a = j -> parent; 416 | d ++; 417 | if (a==TERMINAL) 418 | { 419 | j -> TS = TIME; 420 | j -> DIST = 1; 421 | break; 422 | } 423 | if (a==ORPHAN) { d = INFINITE_D; break; } 424 | j = a -> head; 425 | } 426 | if (dhead; j->TS!=TIME; j=j->parent->head) 435 | { 436 | j -> TS = TIME; 437 | j -> DIST = d --; 438 | } 439 | } 440 | } 441 | } 442 | 443 | if (i->parent = a0_min) 444 | { 445 | i -> TS = TIME; 446 | i -> DIST = d_min + 1; 447 | } 448 | else 449 | { 450 | /* no parent is found */ 451 | add_to_changed_list(i); 452 | 453 | /* process neighbors */ 454 | for (a0=i->first; a0; a0=a0->next) 455 | { 456 | j = a0 -> head; 457 | if (j->is_sink && (a=j->parent)) 458 | { 459 | if (a0->r_cap) set_active(j); 460 | if (a!=TERMINAL && a!=ORPHAN && a->head==i) 461 | { 462 | set_orphan_rear(j); // add j to the end of the adoption list 463 | } 464 | } 465 | } 466 | } 467 | } 468 | 469 | /***********************************************************************/ 470 | 471 | template 472 | flowtype Graph::maxflow(bool reuse_trees, Block* _changed_list) 473 | { 474 | node *i, *j, *current_node = NULL; 475 | arc *a; 476 | nodeptr *np, *np_next; 477 | 478 | if (!nodeptr_block) 479 | { 480 | nodeptr_block = new DBlock(NODEPTR_BLOCK_SIZE, error_function); 481 | } 482 | 483 | changed_list = _changed_list; 484 | if (maxflow_iteration == 0 && reuse_trees) { if (error_function) (*error_function)("reuse_trees cannot be used in the first call to maxflow()!"); exit(1); } 485 | if (changed_list && !reuse_trees) { if (error_function) (*error_function)("changed_list cannot be used without reuse_trees!"); exit(1); } 486 | 487 | if (reuse_trees) maxflow_reuse_trees_init(); 488 | else maxflow_init(); 489 | 490 | // main loop 491 | while ( 1 ) 492 | { 493 | // test_consistency(current_node); 494 | 495 | if ((i=current_node)) 496 | { 497 | i -> next = NULL; /* remove active flag */ 498 | if (!i->parent) i = NULL; 499 | } 500 | if (!i) 501 | { 502 | if (!(i = next_active())) break; 503 | } 504 | 505 | /* growth */ 506 | if (!i->is_sink) 507 | { 508 | /* grow source tree */ 509 | for (a=i->first; a; a=a->next) 510 | if (a->r_cap) 511 | { 512 | j = a -> head; 513 | if (!j->parent) 514 | { 515 | j -> is_sink = 0; 516 | j -> parent = a -> sister; 517 | j -> TS = i -> TS; 518 | j -> DIST = i -> DIST + 1; 519 | set_active(j); 520 | add_to_changed_list(j); 521 | } 522 | else if (j->is_sink) break; 523 | else if (j->TS <= i->TS && 524 | j->DIST > i->DIST) 525 | { 526 | /* heuristic - trying to make the distance from j to the source shorter */ 527 | j -> parent = a -> sister; 528 | j -> TS = i -> TS; 529 | j -> DIST = i -> DIST + 1; 530 | } 531 | } 532 | } 533 | else 534 | { 535 | /* grow sink tree */ 536 | for (a=i->first; a; a=a->next) 537 | if (a->sister->r_cap) 538 | { 539 | j = a -> head; 540 | if (!j->parent) 541 | { 542 | j -> is_sink = 1; 543 | j -> parent = a -> sister; 544 | j -> TS = i -> TS; 545 | j -> DIST = i -> DIST + 1; 546 | set_active(j); 547 | add_to_changed_list(j); 548 | } 549 | else if (!j->is_sink) { a = a -> sister; break; } 550 | else if (j->TS <= i->TS && 551 | j->DIST > i->DIST) 552 | { 553 | /* heuristic - trying to make the distance from j to the sink shorter */ 554 | j -> parent = a -> sister; 555 | j -> TS = i -> TS; 556 | j -> DIST = i -> DIST + 1; 557 | } 558 | } 559 | } 560 | 561 | TIME ++; 562 | 563 | if (a) 564 | { 565 | i -> next = i; /* set active flag */ 566 | current_node = i; 567 | 568 | /* augmentation */ 569 | augment(a); 570 | /* augmentation end */ 571 | 572 | /* adoption */ 573 | while ((np=orphan_first)) 574 | { 575 | np_next = np -> next; 576 | np -> next = NULL; 577 | 578 | while ((np=orphan_first)) 579 | { 580 | orphan_first = np -> next; 581 | i = np -> ptr; 582 | nodeptr_block -> Delete(np); 583 | if (!orphan_first) orphan_last = NULL; 584 | if (i->is_sink) process_sink_orphan(i); 585 | else process_source_orphan(i); 586 | } 587 | 588 | orphan_first = np_next; 589 | } 590 | /* adoption end */ 591 | } 592 | else current_node = NULL; 593 | } 594 | // test_consistency(); 595 | 596 | if (!reuse_trees || (maxflow_iteration % 64) == 0) 597 | { 598 | delete nodeptr_block; 599 | nodeptr_block = NULL; 600 | } 601 | 602 | maxflow_iteration ++; 603 | return flow; 604 | } 605 | 606 | /***********************************************************************/ 607 | 608 | 609 | template 610 | void Graph::test_consistency(node* current_node) 611 | { 612 | node *i; 613 | arc *a; 614 | int r; 615 | int num1 = 0, num2 = 0; 616 | 617 | // test whether all nodes i with i->next!=NULL are indeed in the queue 618 | for (i=nodes; inext || i==current_node) num1 ++; 621 | } 622 | for (r=0; r<3; r++) 623 | { 624 | i = (r == 2) ? current_node : queue_first[r]; 625 | if (i) 626 | for ( ; ; i=i->next) 627 | { 628 | num2 ++; 629 | if (i->next == i) 630 | { 631 | if (r<2) assert(i == queue_last[r]); 632 | else assert(i == current_node); 633 | break; 634 | } 635 | } 636 | } 637 | assert(num1 == num2); 638 | 639 | for (i=nodes; iparent == NULL) {} 643 | else if (i->parent == ORPHAN) {} 644 | else if (i->parent == TERMINAL) 645 | { 646 | if (!i->is_sink) assert(i->tr_cap > 0); 647 | else assert(i->tr_cap < 0); 648 | } 649 | else 650 | { 651 | if (!i->is_sink) assert (i->parent->sister->r_cap > 0); 652 | else assert (i->parent->r_cap > 0); 653 | } 654 | // test whether passive nodes in search trees have neighbors in 655 | // a different tree through non-saturated edges 656 | if (i->parent && !i->next) 657 | { 658 | if (!i->is_sink) 659 | { 660 | assert(i->tr_cap >= 0); 661 | for (a=i->first; a; a=a->next) 662 | { 663 | if (a->r_cap > 0) assert(a->head->parent && !a->head->is_sink); 664 | } 665 | } 666 | else 667 | { 668 | assert(i->tr_cap <= 0); 669 | for (a=i->first; a; a=a->next) 670 | { 671 | if (a->sister->r_cap > 0) assert(a->head->parent && a->head->is_sink); 672 | } 673 | } 674 | } 675 | // test marking invariants 676 | if (i->parent && i->parent!=ORPHAN && i->parent!=TERMINAL) 677 | { 678 | assert(i->TS <= i->parent->head->TS); 679 | if (i->TS == i->parent->head->TS) assert(i->DIST > i->parent->head->DIST); 680 | } 681 | } 682 | } 683 | 684 | #include "instances.inc" 685 | -------------------------------------------------------------------------------- /mlginstances.inc: -------------------------------------------------------------------------------- 1 | #include "multilayergraph.h" 2 | 3 | #ifdef _MSC_VER 4 | #pragma warning(disable: 4661) 5 | #endif 6 | 7 | // Instantiations: 8 | // IMPORTANT: 9 | // flowtype should be 'larger' than tcaptype 10 | // tcaptype should be 'larger' than captype 11 | 12 | template class MultiLayerGraph; 13 | template class MultiLayerGraph; 14 | template class MultiLayerGraph; 15 | template class MultiLayerGraph; 16 | 17 | -------------------------------------------------------------------------------- /multilayergraph.cpp: -------------------------------------------------------------------------------- 1 | #include "multilayergraph.h" 2 | 3 | template 4 | MultiLayerGraph::MultiLayerGraph(int node_num_max, int arc_num_max, int label_max) 5 | { 6 | if(label_max < 2) label_max=2; 7 | label_num=label_max; 8 | layer_num=label_num-1; 9 | graph=new Graph(node_num_max*(label_max-1),arc_num_max*(label_max-1)+node_num_max*label_max); 10 | node_num=node_num_max; 11 | final_label=new label_id[node_num_max]; 12 | memset(final_label, -1, node_num_max*sizeof(label_id)); 13 | } 14 | 15 | template 16 | MultiLayerGraph::~MultiLayerGraph() 17 | { 18 | if(graph) 19 | { 20 | delete graph; 21 | graph=NULL; 22 | } 23 | if(final_label) 24 | { 25 | delete final_label; 26 | } 27 | } 28 | 29 | template 30 | void MultiLayerGraph::add_node() 31 | { 32 | for(int i=0; iadd_node(); 35 | } 36 | } 37 | 38 | template 39 | void MultiLayerGraph::add_edge(node_id i, node_id j, captype cap, captype rev_cap) 40 | { 41 | assert(i>=0 && i=0 && jadd_edge(i*layer_num+k,j*layer_num+k,cap,rev_cap); 46 | } 47 | } 48 | 49 | template 50 | void MultiLayerGraph::add_tweights(node_id i, label_id j, tcaptype cap) 51 | { 52 | assert(j>=0 && jadd_tweights(i*layer_num,cap,0); 56 | } 57 | else if(j==label_num-1) 58 | { 59 | graph->add_tweights((i+1)*layer_num-1,0,cap); 60 | } 61 | else 62 | { 63 | graph->add_edge(i*layer_num+j-1,i*layer_num+j,cap,cap); 64 | } 65 | } 66 | 67 | template 68 | flowtype MultiLayerGraph::maxflow() 69 | { 70 | flowtype energy=graph->maxflow(); 71 | 72 | node *i; 73 | node *j; 74 | arc *a; 75 | 76 | for(i=graph->nodes; inode_last; i++) 77 | { 78 | int node_index=(i-graph->nodes)/layer_num; 79 | if(final_label[node_index]!=-1) continue; 80 | int layer_index=(i-graph->nodes)%layer_num+1; 81 | if(layer_index==1) 82 | { 83 | if(i->is_sink) 84 | { 85 | final_label[node_index]=1; 86 | continue; 87 | } 88 | } 89 | if(layer_index==layer_num) 90 | { 91 | if(!i->is_sink) 92 | { 93 | final_label[node_index]=layer_num+1; 94 | } 95 | } 96 | for(a=i->first; a; a=a->next) 97 | { 98 | j=a->head; 99 | int jnode_index=(j-graph->nodes)/layer_num; 100 | int jlayer_index=(j-graph->nodes)%layer_num+1; 101 | if(jnode_index==node_index && i->is_sink!=j->is_sink) 102 | { 103 | final_label[node_index]=layer_index>jlayer_index?layer_index:jlayer_index; 104 | break; 105 | } 106 | } 107 | } 108 | 109 | return energy; 110 | } 111 | 112 | template 113 | typename MultiLayerGraph::label_id MultiLayerGraph::what_segment(node_id i) 114 | { 115 | assert(i>=0 && i class MultiLayerGraph 7 | { 8 | private: 9 | typedef typename Graph::node_id node_id; 10 | typedef typename Graph::node node; 11 | typedef typename Graph::arc arc; 12 | typedef int label_id; 13 | 14 | public: 15 | 16 | MultiLayerGraph(int node_num_max, int arc_num_max, int label_max); 17 | 18 | ~MultiLayerGraph(); 19 | 20 | void add_node(); 21 | 22 | void add_edge(node_id i, node_id j, captype cap, captype rev_cap); 23 | 24 | void add_tweights(node_id i, label_id j, tcaptype cap); 25 | 26 | flowtype maxflow(); 27 | 28 | label_id what_segment(node_id i); 29 | 30 | private: 31 | int label_num; 32 | int node_num; 33 | int layer_num; 34 | int arcs; 35 | int current_node; 36 | label_id *final_label; 37 | 38 | Graph *graph; 39 | }; 40 | 41 | #endif // MULTILAYERGRAPH_H 42 | --------------------------------------------------------------------------------