#ifndef PREFLOW_PUSH_HH #define PREFLOW_PUSH_HH #include #include #include //#include "pf_hiba.hh" //#include //#include #include using namespace std; namespace hugo { template class preflow_push { //Hasznos typedef-ek typedef typename graph_type::NodeIt NodeIt; typedef typename graph_type::EdgeIt EdgeIt; typedef typename graph_type::EachNodeIt EachNodeIt; typedef typename graph_type::EachEdgeIt EachEdgeIt; typedef typename graph_type::OutEdgeIt OutEdgeIt; typedef typename graph_type::InEdgeIt InEdgeIt; typedef typename graph_type::SymEdgeIt SymEdgeIt; /* typedef graph_traits::node_iterator node_iterator; typedef graph_traits::EdgeIt EdgeIt; typedef graph_traits::each_node_iterator each_node_iterator; typedef graph_traits::each_EdgeIt each_EdgeIt; typedef graph_traits::out_EdgeIt out_EdgeIt; typedef graph_traits::InEdgeIt InEdgeIt; typedef graph_traits::sym_EdgeIt sym_EdgeIt; */ //--------------------------------------------- //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; NodeIt s; NodeIt t; typename graph_type::EdgeMap &capacity; //typename graph_type::EdgeMap &capacity; //output //typename graph_type::EdgeMap typename graph_type::EdgeMap preflow; T maxflow_value; //auxiliary variables for computation int number_of_nodes; typename graph_type::NodeMap level; typename graph_type::NodeMap excess; //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, NodeIt _s, NodeIt _t, typename graph_type::EdgeMap & _capacity) : G(_G), s(_s), t(_t), capacity(_capacity), preflow(_G), //Counting the number of nodes //number_of_nodes(count(G.first())), number_of_nodes(G.nodeNum()), 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(); typename graph_type::EdgeMap getmaxflow(){ return preflow; } private: //For testing purposes only //Lists the node_properties void write_property_vector(typename graph_type::NodeMap a, //node_property_vector a, char* prop_name="property"){ for(EachNodeIt i=G.template first(); i.valid(); ++i) { cout<<"Node id.: "<=0 && active_nodes[highest_active].empty() ){ --highest_active; } if( highest_active>=0) { NodeIt a=active_nodes[highest_active].front(); active_nodes[highest_active].pop_front(); return a; } else { return NodeIt(); } break; } case impl_fifo : { if( ! fifo_nodes.empty() ) { NodeIt a=fifo_nodes.front(); fifo_nodes.pop_front(); return a; } else { return NodeIt(); } break; } } // return NodeIt(); } //Puts node 'a' among the active nodes void make_active(const NodeIt& 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(); i.valid(); ++i) { level.set(i,0); excess.set(i,0); for(OutEdgeIt j=G.template first(i); j.valid(); ++j) preflow.set(j, 0); } num_of_nodes_on_level[0]=number_of_nodes; highest_active=0; //--------------------------------------- //Initialize parameters //--------------------------------------- //------------------------------------ //This is the only part that uses BFS //------------------------------------ //Setting starting level values using reverse bfs reverse_bfs rev_bfs(G,t); rev_bfs.run(); //write_property_vector(rev_bfs.dist,"rev_bfs"); for(EachNodeIt i=G.template first(); 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(OutEdgeIt j=G.template first(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(InEdgeIt j, int& new_level){ if (0 T preflow_push::run() { preprocess(); //write_property_vector(level,"level"); T e,v; NodeIt a; while (a=get_active_node(), a.valid()){ //cout<(a); while (j.valid() && e){ if (is_admissible_forward_edge(j,new_level)){ v=min(e,capacity.get(j) - preflow.get(j)); e -= v; //New node might become active if (excess.get(G.head(j))==0){ make_active(G.head(j)); } modify_preflow(j,v); } ++j; } } //In edges to node a { InEdgeIt j=G.template first(a); while (j.valid() && e){ if (is_admissible_backward_edge(j,new_level)){ v=min(e,preflow.get(j)); e -= v; //New node might become active if (excess.get(G.tail(j))==0){ make_active(G.tail(j)); } modify_preflow(j,-v); } ++j; } } //if (G.id(a)==999) //cout<