# HG changeset patch # User athos # Date 1075220631 0 # Node ID 7d539ea6ad267d7ca53483ebf41d9486aabd2b03 # Parent 65dca0f43fbada3b9cd35308f8fce62a31fb7d60 preflow_push.hh: Preflow-push valtozat by athos A tesztfile: pf_demo.cc Kulon makefile is van. diff -r 65dca0f43fba -r 7d539ea6ad26 src/work/athos/makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/athos/makefile Tue Jan 27 16:23:51 2004 +0000 @@ -0,0 +1,7 @@ +CXXFLAGS = -Wall -ansi -g +CXX = g++-3.0 + +pf_demo: pf_demo.cc ../marci_graph_traits.hh ../marci_list_graph.hh ../marci_property_vector.hh preflow_push.hh ../reverse_bfs.hh + $(CXX) $(CXXFLAGS) -I. -I.. pf_demo.cc -o pf_demo + + diff -r 65dca0f43fba -r 7d539ea6ad26 src/work/athos/pf_demo.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/athos/pf_demo.cc Tue Jan 27 16:23:51 2004 +0000 @@ -0,0 +1,172 @@ +#include +#include +#include + +#include "marci_list_graph.hh" +#include "marci_graph_traits.hh" +#include "marci_property_vector.hh" +#include "preflow_push.hh" + +using namespace marci; + + +int main (int, char*[]) +{ + 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; + + list_graph flow_test; + + + //Ahuja könyv példája + node_iterator s=flow_test.add_node(); + node_iterator v2=flow_test.add_node(); + node_iterator v3=flow_test.add_node(); + node_iterator v4=flow_test.add_node(); + node_iterator v5=flow_test.add_node(); + node_iterator t=flow_test.add_node(); + + node_property_vector node_name(flow_test); + node_name.put(s, "s"); + node_name.put(v2, "v2"); + node_name.put(v3, "v3"); + node_name.put(v4, "v4"); + node_name.put(v5, "v5"); + node_name.put(t, "t"); + + + edge_iterator s_v2=flow_test.add_edge(s, v2); + edge_iterator s_v3=flow_test.add_edge(s, v3); + + edge_iterator v2_v4=flow_test.add_edge(v2, v4); + edge_iterator v2_v5=flow_test.add_edge(v2, v5); + + edge_iterator v3_v5=flow_test.add_edge(v3, v5); + + edge_iterator v4_t=flow_test.add_edge(v4, t); + edge_iterator v5_t=flow_test.add_edge(v5, t); + + //Kis modositas + edge_iterator v2_s=flow_test.add_edge(v2, s); + + edge_property_vector cap(flow_test); + cap.put(s_v2, 10); + cap.put(s_v3, 10); + cap.put(v2_v4, 5); + cap.put(v2_v5, 8); + cap.put(v3_v5, 5); + cap.put(v4_t, 8); + cap.put(v5_t, 8); + + //Kis modositas + cap.put(v2_s, 100); + + //Kis modositas + //edge_iterator t_s=flow_test.add_edge(t, s); + //cap.put(t_s, 20); + + + /* + //Marci példája + node_iterator s=flow_test.add_node(); + node_iterator v1=flow_test.add_node(); + node_iterator v2=flow_test.add_node(); + node_iterator v3=flow_test.add_node(); + node_iterator v4=flow_test.add_node(); + node_iterator t=flow_test.add_node(); + + node_property_vector node_name(flow_test); + node_name.put(s, "s"); + node_name.put(v1, "v1"); + node_name.put(v2, "v2"); + node_name.put(v3, "v3"); + node_name.put(v4, "v4"); + node_name.put(t, "t"); + + edge_iterator s_v1=flow_test.add_edge(s, v1); + edge_iterator s_v2=flow_test.add_edge(s, v2); + edge_iterator v1_v2=flow_test.add_edge(v1, v2); + edge_iterator v2_v1=flow_test.add_edge(v2, v1); + edge_iterator v1_v3=flow_test.add_edge(v1, v3); + edge_iterator v3_v2=flow_test.add_edge(v3, v2); + edge_iterator v2_v4=flow_test.add_edge(v2, v4); + edge_iterator v4_v3=flow_test.add_edge(v4, v3); + edge_iterator v3_t=flow_test.add_edge(v3, t); + edge_iterator v4_t=flow_test.add_edge(v4, t); + + edge_property_vector cap(flow_test); + cap.put(s_v1, 16); + cap.put(s_v2, 13); + cap.put(v1_v2, 10); + cap.put(v2_v1, 4); + cap.put(v1_v3, 12); + cap.put(v3_v2, 9); + cap.put(v2_v4, 14); + cap.put(v4_v3, 7); + cap.put(v3_t, 20); + cap.put(v4_t, 4); + */ + /*Egyszerű példa + node_iterator s=flow_test.add_node(); + node_iterator v1=flow_test.add_node(); + node_iterator v2=flow_test.add_node(); + node_iterator t=flow_test.add_node(); + + node_property_vector node_name(flow_test); + node_name.put(s, "s"); + node_name.put(v1, "v1"); + node_name.put(v2, "v2"); + node_name.put(t, "t"); + + edge_iterator s_v1=flow_test.add_edge(s, v1); + edge_iterator v1_v2=flow_test.add_edge(v1, v2); + edge_iterator v2_t=flow_test.add_edge(v2, t); + + edge_property_vector cap(flow_test); + + cap.put(s_v1, 16); + cap.put(v1_v2, 10); + cap.put(v2_t, 4); + */ + + std::cout << "preflow-push algorithm test..." << std::endl; + std::cout << "on directed graph graph" << std::endl; //<< flow_test; + std::cout << "names and capacity values" << std::endl; + for(each_node_iterator i=flow_test.first_node(); i.valid(); ++i) { + std::cout << node_name.get(i) << ": "; + std::cout << "out edges: "; + for(out_edge_iterator j=flow_test.first_out_edge(i); j.valid(); ++j) + std::cout << node_name.get(flow_test.tail(j)) << "-"<< cap.get(j) << "->" << node_name.get(flow_test.head(j)) << " "; + std::cout << "in edges: "; + for(in_edge_iterator j=flow_test.first_in_edge(i); j.valid(); ++j) + std::cout << node_name.get(flow_test.tail(j)) << "-"<< cap.get(j) << "->" << node_name.get(flow_test.head(j)) << " "; + std::cout << std::endl; + } + + + //for(each_node_iterator i=flow_test.first_node(); i.valid(); ++i) { + // std::cout << i << " "; + //} + + preflow_push preflow_push_test(flow_test, s, t, cap); + cout << preflow_push_test.run()< +#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<