Doc for the union-find structures.
1 #ifndef HUGO_PREFLOW_PUSH_HH
2 #define HUGO_PREFLOW_PUSH_HH
8 //#include "pf_hiba.hh"
9 //#include <marci_list_graph.hh>
10 //#include <marci_graph_traits.hh>
12 #include <graph_wrapper.h>
13 //#include <reverse_bfs.hh>
19 template <typename Graph, typename T>
23 typedef typename Graph::Node Node;
24 typedef typename Graph::NodeIt NodeIt;
25 typedef typename Graph::Edge Edge;
26 typedef typename Graph::OutEdgeIt OutEdgeIt;
27 typedef typename Graph::InEdgeIt InEdgeIt;
30 //---------------------------------------------
31 //Parameters of the algorithm
32 //---------------------------------------------
33 //Fully examine an active node until excess becomes 0
34 enum node_examination_t {examine_full, examine_to_relabel};
35 //No more implemented yet:, examine_only_one_edge};
36 node_examination_t node_examination;
37 //Which implementation to be used
38 enum implementation_t {impl_fifo, impl_highest_label};
39 //No more implemented yet:};
40 implementation_t implementation;
41 //---------------------------------------------
42 //Parameters of the algorithm
43 //---------------------------------------------
50 typename Graph::EdgeMap<T> &capacity;
53 typename Graph::EdgeMap<T> preflow;
56 //auxiliary variables for computation
57 //The number of the nodes
59 //A nodemap for the level
60 typename Graph::NodeMap<int> level;
61 //A nodemap for the excess
62 typename Graph::NodeMap<T> excess;
64 //Number of nodes on each level
65 vector<int> num_of_nodes_on_level;
67 //For the FIFO implementation
68 list<Node> fifo_nodes;
69 //For 'highest label' implementation
71 //int second_highest_active;
72 vector< list<Node> > active_nodes;
76 //Constructing the object using the graph, source, sink and capacity vector
81 typename Graph::EdgeMap<T> & _capacity)
82 : G(_G), s(_s), t(_t),
85 //Counting the number of nodes
86 //number_of_nodes(count(G.first<EachNodeIt>())),
87 number_of_nodes(G.nodeNum()),
91 // Default constructor: active_nodes()
93 //Simplest parameter settings
94 node_examination = examine_full;//examine_to_relabel;//
95 //Which implementation to be usedexamine_full
96 implementation = impl_highest_label;//impl_fifo;
99 num_of_nodes_on_level.resize(2*number_of_nodes-1);
100 num_of_nodes_on_level.clear();
102 switch(implementation){
103 case impl_highest_label :{
104 active_nodes.clear();
105 active_nodes.resize(2*number_of_nodes-1);
115 //Returns the value of a maximal flow
118 typename Graph::EdgeMap<T> getmaxflow(){
124 //For testing purposes only
125 //Lists the node_properties
126 void write_property_vector(typename Graph::NodeMap<T> a,
127 //node_property_vector<Graph, T> a,
128 char* prop_name="property"){
129 for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
130 cout<<"Node id.: "<<G.id(i)<<", "<<prop_name<<" value: "<<a[i]<<endl;
135 //Modifies the excess of the node and makes sufficient changes
136 void modify_excess(const Node& a ,T v){
137 //T old_value=excess[a];
141 //This private procedure is supposed to modify the preflow on edge j
142 //by value v (which can be positive or negative as well)
143 //and maintain the excess on the head and tail
144 //Here we do not check whether this is possible or not
145 void modify_preflow(Edge j, const T& v){
152 modify_excess(G.head(j),v);
155 modify_excess(G.tail(j),-v);
159 //Gives the active node to work with
160 //(depending on the implementation to be used)
161 Node get_active_node(){
164 switch(implementation) {
165 case impl_highest_label : {
167 //First need to find the highest label for which there's an active node
168 while( highest_active>=0 && active_nodes[highest_active].empty() ){
172 if( highest_active>=0) {
175 Node a=active_nodes[highest_active].front();
176 active_nodes[highest_active].pop_front();
189 if( ! fifo_nodes.empty() ) {
190 Node a=fifo_nodes.front();
191 fifo_nodes.pop_front();
204 //Puts node 'a' among the active nodes
205 void make_active(const Node& a){
206 //s and t never become active
208 switch(implementation){
209 case impl_highest_label :
210 active_nodes[level[a]].push_back(a);
213 fifo_nodes.push_back(a);
219 //Update highest_active label
220 if (highest_active<level[a]){
221 highest_active=level[a];
226 //Changes the level of node a and make sufficent changes
227 void change_level_to(Node a, int new_value){
228 int seged = level[a];
229 level.set(a,new_value);
230 --num_of_nodes_on_level[seged];
231 ++num_of_nodes_on_level[new_value];
234 //Collection of things useful (or necessary) to do before running
238 //---------------------------------------
239 //Initialize parameters
240 //---------------------------------------
242 //Setting starting preflow, level and excess values to zero
243 //This can be important, if the algorithm is run more then once
244 for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
247 for(OutEdgeIt j=G.template first<OutEdgeIt>(i); G.valid(j); G.next(j))
250 num_of_nodes_on_level[0]=number_of_nodes;
252 //---------------------------------------
253 //Initialize parameters
254 //---------------------------------------
257 //------------------------------------
258 //This is the only part that uses BFS
259 //------------------------------------
261 /*Reverse_bfs from t, to find the starting level.*/
263 change_level_to(t,0);
265 std::queue<Node> bfs_queue;
268 while (!bfs_queue.empty()) {
270 Node v=bfs_queue.front();
275 for(G.first(e,v); G.valid(e); G.next(e)) {
277 if ( level[w] == number_of_nodes && w != s ) {
279 //Node first=level_list[l];
280 //if ( G.valid(first) ) left.set(first,w);
281 //right.set(w,first);
283 change_level_to(w, l);
288 change_level_to(s,number_of_nodes);
289 //level.set(s,number_of_nodes);
292 //Setting starting level values using reverse bfs
293 reverse_bfs<Graph> rev_bfs(G,t);
295 //write_property_vector(rev_bfs.dist,"rev_bfs");
296 for(NodeIt i=G.template first<NodeIt>(); G.valid(i); G.next(i)) {
297 change_level_to(i,rev_bfs.dist(i));
298 //level.put(i,rev_bfs.dist.get(i));
301 //------------------------------------
302 //This is the only part that uses BFS
303 //------------------------------------
306 //Starting level of s
307 change_level_to(s,number_of_nodes);
308 //level.put(s,number_of_nodes);
311 //we push as much preflow from s as possible to start with
312 for(OutEdgeIt j=G.template first<OutEdgeIt>(s); G.valid(j); G.next(j)){
313 modify_preflow(j,capacity[j] );
314 make_active(G.head(j));
315 int lev=level[G.head(j)];
316 if(highest_active<lev){
320 //cout<<highest_active<<endl;
324 //If the preflow is less than the capacity on the given edge
325 //then it is an edge in the residual graph
326 bool is_admissible_forward_edge(Edge j, int& new_level){
328 if (capacity[j]>preflow[j]){
329 if(level[G.tail(j)]==level[G.head(j)]+1){
333 if (level[G.head(j)] < new_level)
334 new_level=level[G.head(j)];
340 //If the preflow is greater than 0 on the given edge
341 //then the edge reversd is an edge in the residual graph
342 bool is_admissible_backward_edge(Edge j, int& new_level){
345 if(level[G.tail(j)]==level[G.head(j)]-1){
350 if (level[G.tail(j)] < new_level)
351 new_level=level[G.tail(j)];
359 }; //class preflow_push
361 template<typename Graph, typename T>
362 T preflow_push<Graph, T>::run() {
364 //We need a residual graph
365 ResGraphType res_graph(G, preflow, capacity);
368 //write_property_vector(level,"level");
371 while (a=get_active_node(), G.valid(a)){
373 bool go_to_next_node=false;
375 while (!go_to_next_node){
377 //Initial value for the new level for the active node we are dealing with
378 int new_level=2*number_of_nodes;
381 //Out edges from node a
383 OutEdgeIt j=G.template first<OutEdgeIt>(a);
384 while (G.valid(j) && e){
386 if (is_admissible_forward_edge(j,new_level)){
387 v=min(e,capacity[j] - preflow[j]);
389 //New node might become active
390 if (excess[G.head(j)]==0){
391 make_active(G.head(j));
400 InEdgeIt j=G.template first<InEdgeIt>(a);
401 while (G.valid(j) && e){
402 if (is_admissible_backward_edge(j,new_level)){
405 //New node might become active
406 if (excess[G.tail(j)]==0){
407 make_active(G.tail(j));
409 modify_preflow(j,-v);
416 //cout<<new_level<<" e: "<<e<<endl;
417 //cout<<G.id(a)<<" "<<new_level<<endl;
421 go_to_next_node=true;
423 else{//If there is still excess in node a
425 //change_level_to(a,new_level+1);
427 //Level remains empty
428 if (num_of_nodes_on_level[level[a]]==1){
429 change_level_to(a,number_of_nodes);
430 //go_to_next_node=True;
433 change_level_to(a,new_level+1);
440 switch(node_examination){
441 case examine_to_relabel:
444 go_to_next_node = true;
455 maxflow_value = excess[t];
456 return maxflow_value;
462 #endif //PREFLOW_PUSH_HH