#ifndef PREFLOW_PUSH_HH #define PREFLOW_PUSH_HH #include #include #include //#include "pf_hiba.hh" //#include #include #include "reverse_bfs.hh" using namespace std; namespace marci { template class preflow_push { //Hasznos typedef-ek typedef graph_traits::node_iterator node_iterator; typedef graph_traits::edge_iterator edge_iterator; typedef graph_traits::each_node_iterator each_node_iterator; typedef graph_traits::each_edge_iterator each_edge_iterator; typedef graph_traits::out_edge_iterator out_edge_iterator; typedef graph_traits::in_edge_iterator in_edge_iterator; typedef graph_traits::sym_edge_iterator sym_edge_iterator; //--------------------------------------------- //Parameters of the algorithm //--------------------------------------------- //Fully examine an active node until excess becomes 0 enum node_examination_t {examine_full, examine_to_relabel}; //No more implemented yet:, examine_only_one_edge}; node_examination_t node_examination; //Which implementation to be used enum implementation_t {impl_fifo, impl_highest_label}; //No more implemented yet:}; implementation_t implementation; //--------------------------------------------- //Parameters of the algorithm //--------------------------------------------- private: //input graph_type& G; node_iterator s; node_iterator t; edge_property_vector &capacity; //output edge_property_vector preflow; T maxflow_value; //auxiliary variables for computation int number_of_nodes; node_property_vector level; node_property_vector excess; //Number of nodes on each level vector num_of_nodes_on_level; //For the FIFO implementation list fifo_nodes; //For 'highest label' implementation int highest_active; //int second_highest_active; vector< list > active_nodes; public: //Constructing the object using the graph, source, sink and capacity vector preflow_push( graph_type& _G, node_iterator _s, node_iterator _t, edge_property_vector& _capacity) : G(_G), s(_s), t(_t), capacity(_capacity), preflow(_G), //Counting the number of nodes number_of_nodes(number_of(G.first_node())), level(_G), excess(_G)//, // Default constructor: active_nodes() { //Simplest parameter settings node_examination = examine_full;//examine_to_relabel;// //Which implementation to be usedexamine_full implementation = impl_highest_label;//impl_fifo; // num_of_nodes_on_level.resize(2*number_of_nodes-1); num_of_nodes_on_level.clear(); switch(implementation){ case impl_highest_label :{ active_nodes.resize(2*number_of_nodes-1); active_nodes.clear(); break; } default: break; } } //Returns the value of a maximal flow T run(); edge_property_vector getmaxflow(){ return preflow; } private: //For testing purposes only //Lists the node_properties void write_property_vector(node_property_vector a, char* prop_name="property"){ for(each_node_iterator i=G.first_node(); i.valid(); ++i) { cout<<"Node id.: "<=0 && active_nodes[highest_active].empty() ){ --highest_active; } if( highest_active>=0) { node_iterator a=active_nodes[highest_active].front(); active_nodes[highest_active].pop_front(); return a; } else { return node_iterator(); } break; } case impl_fifo : { if( ! fifo_nodes.empty() ) { node_iterator a=fifo_nodes.front(); fifo_nodes.pop_front(); return a; } else { return node_iterator(); } break; } } // return node_iterator(); } //Puts node 'a' among the active nodes void make_active(const node_iterator& a){ //s and t never become active if (a!=s && a!= t){ switch(implementation){ case impl_highest_label : active_nodes[level.get(a)].push_back(a); break; case impl_fifo : fifo_nodes.push_back(a); break; } } //Update highest_active label if (highest_active rev_bfs(G,t); rev_bfs.run(); //write_property_vector(rev_bfs.dist,"rev_bfs"); for(each_node_iterator i=G.first_node(); i.valid(); ++i) { change_level_to(i,rev_bfs.dist(i)); //level.put(i,rev_bfs.dist.get(i)); } //------------------------------------ //This is the only part that uses BFS //------------------------------------ //Starting level of s change_level_to(s,number_of_nodes); //level.put(s,number_of_nodes); //we push as much preflow from s as possible to start with for(out_edge_iterator j=G.first_out_edge(s); j.valid(); ++j){ modify_preflow(j,capacity.get(j) ); make_active(G.head(j)); int lev=level.get(G.head(j)); if(highest_activepreflow.get(j)){ if(level.get(G.tail(j))==level.get(G.head(j))+1){ return true; } else{ if (level.get(G.head(j)) < new_level) new_level=level.get(G.head(j)); } } return false; } //If the preflow is greater than 0 on the given edge //then the edge reversd is an edge in the residual graph bool is_admissible_backward_edge(in_edge_iterator j, int& new_level){ if (0 T preflow_push::run() { preprocess(); T e,v; node_iterator a; while (a=get_active_node(), a.valid()){ //cout<