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@36: #include 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@36: typedef graph_traits::node_iterator node_iterator; athos@36: typedef graph_traits::edge_iterator edge_iterator; athos@36: typedef graph_traits::each_node_iterator each_node_iterator; athos@36: typedef graph_traits::each_edge_iterator each_edge_iterator; athos@36: typedef graph_traits::out_edge_iterator out_edge_iterator; athos@36: typedef graph_traits::in_edge_iterator in_edge_iterator; athos@36: typedef graph_traits::sym_edge_iterator sym_edge_iterator; 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@36: node_iterator s; athos@36: node_iterator t; athos@36: edge_property_vector &capacity; athos@36: //output athos@36: edge_property_vector preflow; athos@36: T maxflow_value; athos@36: athos@36: //auxiliary variables for computation athos@36: int number_of_nodes; athos@36: node_property_vector level; athos@36: 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@36: list fifo_nodes; athos@36: //For 'highest label' implementation athos@36: int highest_active; athos@36: //int second_highest_active; athos@36: 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@36: node_iterator _s, athos@36: node_iterator _t, athos@36: edge_property_vector& _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@36: number_of_nodes(number_of(G.first_node())), 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@36: edge_property_vector 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@36: void write_property_vector(node_property_vector a, athos@36: char* prop_name="property"){ athos@36: for(each_node_iterator i=G.first_node(); 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@36: node_iterator a=active_nodes[highest_active].front(); athos@36: active_nodes[highest_active].pop_front(); athos@36: return a; athos@36: } athos@36: else { athos@36: return node_iterator(); 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@36: node_iterator a=fifo_nodes.front(); athos@36: fifo_nodes.pop_front(); athos@36: return a; athos@36: } athos@36: else { athos@36: return node_iterator(); athos@36: } athos@36: break; athos@36: } athos@36: } athos@36: // athos@36: return node_iterator(); athos@36: } athos@36: athos@36: //Puts node 'a' among the active nodes athos@36: void make_active(const node_iterator& 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 rev_bfs(G,t); athos@36: rev_bfs.run(); athos@36: //write_property_vector(rev_bfs.dist,"rev_bfs"); athos@36: for(each_node_iterator i=G.first_node(); 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@36: for(out_edge_iterator j=G.first_out_edge(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@36: bool is_admissible_backward_edge(in_edge_iterator 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@36: node_iterator a; athos@36: while (a=get_active_node(), a.valid()){ athos@36: //cout<