#ifndef HUGO_PREFLOW_PUSH_HH #define HUGO_PREFLOW_PUSH_HH //#include #include #include #include //#include "pf_hiba.hh" //#include //#include #include //#include using namespace std; namespace hugo { template class preflow_push { //Useful typedefs typedef typename Graph::Node Node; typedef typename Graph::NodeIt NodeIt; typedef typename Graph::Edge Edge; typedef typename Graph::OutEdgeIt OutEdgeIt; typedef typename Graph::InEdgeIt InEdgeIt; //--------------------------------------------- //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& G; Node s; Node t; typename Graph::EdgeMap &capacity; //output typename Graph::EdgeMap preflow; T maxflow_value; //auxiliary variables for computation //The number of the nodes int number_of_nodes; //A nodemap for the level typename Graph::NodeMap level; //A nodemap for the excess typename Graph::NodeMap 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& _G, Node _s, Node _t, typename Graph::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.clear(); active_nodes.resize(2*number_of_nodes-1); break; } default: break; } } //Returns the value of a maximal flow T run(); typename Graph::EdgeMap getmaxflow(){ return preflow; } private: //For testing purposes only //Lists the node_properties void write_property_vector(typename Graph::NodeMap a, //node_property_vector a, char* prop_name="property"){ for(NodeIt i=G.template first(); G.valid(i); G.next(i)) { cout<<"Node id.: "<=0 && active_nodes[highest_active].empty() ){ --highest_active; } if( highest_active>=0) { Node a=active_nodes[highest_active].front(); active_nodes[highest_active].pop_front(); return a; } else { return INVALID; } break; } case impl_fifo : { if( ! fifo_nodes.empty() ) { Node a=fifo_nodes.front(); fifo_nodes.pop_front(); return a; } else { return INVALID; } break; } } // return INVALID; } //Puts node 'a' among the active nodes void make_active(const Node& a){ //s and t never become active if (a!=s && a!= t){ switch(implementation){ case impl_highest_label : active_nodes[level[a]].push_back(a); break; case impl_fifo : fifo_nodes.push_back(a); break; } } //Update highest_active label if (highest_active(); G.valid(i); G.next(i)) { level.set(i,0); excess.set(i,0); for(OutEdgeIt j=G.template first(i); G.valid(j); G.next(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 //------------------------------------ /*Reverse_bfs from t, to find the starting level.*/ //Copyright: Jacint change_level_to(t,0); std::queue bfs_queue; bfs_queue.push(t); while (!bfs_queue.empty()) { Node v=bfs_queue.front(); bfs_queue.pop(); int l=level[v]+1; InEdgeIt e; for(G.first(e,v); G.valid(e); G.next(e)) { Node w=G.tail(e); if ( level[w] == number_of_nodes && w != s ) { bfs_queue.push(w); //Node first=level_list[l]; //if ( G.valid(first) ) left.set(first,w); //right.set(w,first); //level_list[l]=w; change_level_to(w, l); //level.set(w, l); } } } change_level_to(s,number_of_nodes); //level.set(s,number_of_nodes); /* //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(NodeIt i=G.template first(); G.valid(i); G.next(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); G.valid(j); G.next(j)){ modify_preflow(j,capacity[j] ); make_active(G.head(j)); int lev=level[G.head(j)]; if(highest_activepreflow[j]){ if(level[G.tail(j)]==level[G.head(j)]+1){ return true; } else{ if (level[G.head(j)] < new_level) new_level=level[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(Edge j, int& new_level){ if (0 T preflow_push::run() { preprocess(); //write_property_vector(level,"level"); T e,v; Node a; while (a=get_active_node(), G.valid(a)){ //cout<(a); while (G.valid(j) && e){ if (is_admissible_forward_edge(j,new_level)){ v=min(e,capacity[j] - preflow[j]); e -= v; //New node might become active if (excess[G.head(j)]==0){ make_active(G.head(j)); } modify_preflow(j,v); } G.next(j); } } //In edges to node a { InEdgeIt j=G.template first(a); while (G.valid(j) && e){ if (is_admissible_backward_edge(j,new_level)){ v=min(e,preflow[j]); e -= v; //New node might become active if (excess[G.tail(j)]==0){ make_active(G.tail(j)); } modify_preflow(j,-v); } G.next(j); } } //if (G.id(a)==999) //cout<