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