[Lemon-commits] [lemon_svn] athos: r100 - hugo/trunk/src/work/athos

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:37:20 CET 2006


Author: athos
Date: Mon Feb 16 16:57:59 2004
New Revision: 100

Added:
   hugo/trunk/src/work/athos/reverse_bfs.hh
Modified:
   hugo/trunk/src/work/athos/pf_demo.cc
   hugo/trunk/src/work/athos/preflow_push.hh

Log:
Kijavitottam a preflow_push algoritmust az uj koncept szerint.


Modified: hugo/trunk/src/work/athos/pf_demo.cc
==============================================================================
--- hugo/trunk/src/work/athos/pf_demo.cc	(original)
+++ hugo/trunk/src/work/athos/pf_demo.cc	Mon Feb 16 16:57:59 2004
@@ -2,9 +2,9 @@
 #include <vector>
 #include <string>
 
-#include "marci_list_graph.hh"
+#include "list_graph.hh"
 #include "marci_graph_traits.hh"
-#include "marci_property_vector.hh"
+//#include "marci_property_vector.hh"
 #include "preflow_push.hh"
 
 using namespace marci;
@@ -12,24 +12,67 @@
 
 int main (int, char*[])
 {
-  typedef graph_traits<list_graph>::node_iterator node_iterator;
-  typedef graph_traits<list_graph>::edge_iterator edge_iterator;
-  typedef graph_traits<list_graph>::each_node_iterator each_node_iterator;
-  typedef graph_traits<list_graph>::each_edge_iterator each_edge_iterator;
-  typedef graph_traits<list_graph>::out_edge_iterator out_edge_iterator;
-  typedef graph_traits<list_graph>::in_edge_iterator in_edge_iterator;
-  typedef graph_traits<list_graph>::sym_edge_iterator sym_edge_iterator;
 
-  list_graph flow_test;
- 
   
+  typedef ListGraph::NodeIt NodeIt;
+  typedef ListGraph::EdgeIt EdgeIt;
+  /*
+  typedef ListGraph::EachNodeIt EachNodeIt;
+  typedef ListGraph::EachEdgeIt EachEdgeIt;
+  typedef ListGraph::OutEdgeIt OutEdgeIt;
+  typedef ListGraph::InEdgeIt InEdgeIt;
+  typedef ListGraph::SymEdgeIt SymEdgeIt;
+  */
+  
+  //Marci példája
+  ListGraph flowG;
+
+  NodeIt s=flowG.addNode();
+  NodeIt v1=flowG.addNode();
+  NodeIt v2=flowG.addNode();
+  NodeIt v3=flowG.addNode();
+  NodeIt v4=flowG.addNode();
+  NodeIt t=flowG.addNode();
+  
+
+  EdgeIt s_v1=flowG.addEdge(s, v1);
+  EdgeIt s_v2=flowG.addEdge(s, v2);
+  EdgeIt v1_v2=flowG.addEdge(v1, v2);
+  EdgeIt v2_v1=flowG.addEdge(v2, v1);
+  EdgeIt v1_v3=flowG.addEdge(v1, v3);
+  EdgeIt v3_v2=flowG.addEdge(v3, v2);
+  EdgeIt v2_v4=flowG.addEdge(v2, v4);
+  EdgeIt v4_v3=flowG.addEdge(v4, v3);
+  EdgeIt v3_t=flowG.addEdge(v3, t);
+  EdgeIt v4_t=flowG.addEdge(v4, t);
+
+  ListGraph::EdgeMap<int> cap(flowG);
+
+  cap.set(s_v1, 16);
+  cap.set(s_v2, 13);
+  cap.set(v1_v2, 10);
+  cap.set(v2_v1, 4);
+  cap.set(v1_v3, 12);
+  cap.set(v3_v2, 9);
+  cap.set(v2_v4, 14);
+  cap.set(v4_v3, 7);
+  cap.set(v3_t, 20);
+  cap.set(v4_t, 4);
+
+
+
+
+
+
+
+  /*
   //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();
+  NodeIt v2=flow_test.add_node();
+  NodeIt v3=flow_test.add_node();
+  NodeIt v4=flow_test.add_node();
+  NodeIt v5=flow_test.add_node();
+  NodeIt t=flow_test.add_node();
   
   node_property_vector<list_graph, std::string> node_name(flow_test);
   node_name.put(s, "s");  
@@ -70,52 +113,15 @@
   //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<list_graph, std::string> 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<list_graph, int> 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();
+  NodeIt s=flow_test.add_node();
+  NodeIt v1=flow_test.add_node();
+  NodeIt v2=flow_test.add_node();
+  NodeIt t=flow_test.add_node();
   
   node_property_vector<list_graph, std::string> node_name(flow_test);
   node_name.put(s, "s");
@@ -135,9 +141,11 @@
   */
 
   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) { 
+  for(EachNodeIt 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) 
@@ -147,13 +155,13 @@
       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) { 
+  //for(each_NodeIt i=flow_test.first_node(); i.valid(); ++i) { 
   //  std::cout << i << " ";
   //}
   
-  preflow_push<list_graph, int> preflow_push_test(flow_test, s, t, cap);
+  preflow_push<ListGraph, int> preflow_push_test(flowG, s, t, cap);
   cout << preflow_push_test.run()<<endl;
 
   //cap.put(v5_t, 9);

Modified: hugo/trunk/src/work/athos/preflow_push.hh
==============================================================================
--- hugo/trunk/src/work/athos/preflow_push.hh	(original)
+++ hugo/trunk/src/work/athos/preflow_push.hh	Mon Feb 16 16:57:59 2004
@@ -6,7 +6,8 @@
 #include <vector>
 //#include "pf_hiba.hh"
 //#include <marci_list_graph.hh>
-#include <marci_graph_traits.hh>
+//#include <marci_graph_traits.hh>
+
 #include "reverse_bfs.hh"
 
 using namespace std;
@@ -17,13 +18,25 @@
   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<graph_type>::node_iterator node_iterator;
-    typedef graph_traits<graph_type>::edge_iterator edge_iterator;
+    typedef graph_traits<graph_type>::EdgeIt EdgeIt;
     typedef graph_traits<graph_type>::each_node_iterator each_node_iterator;
-    typedef graph_traits<graph_type>::each_edge_iterator each_edge_iterator;
-    typedef graph_traits<graph_type>::out_edge_iterator out_edge_iterator;
-    typedef graph_traits<graph_type>::in_edge_iterator in_edge_iterator;
-    typedef graph_traits<graph_type>::sym_edge_iterator sym_edge_iterator;
+    typedef graph_traits<graph_type>::each_EdgeIt each_EdgeIt;
+    typedef graph_traits<graph_type>::out_EdgeIt out_EdgeIt;
+    typedef graph_traits<graph_type>::InEdgeIt InEdgeIt;
+    typedef graph_traits<graph_type>::sym_EdgeIt sym_EdgeIt;
+    */
 
     //---------------------------------------------
     //Parameters of the algorithm
@@ -43,41 +56,49 @@
   private:
     //input
     graph_type& G;
-    node_iterator s;
-    node_iterator t;
-    edge_property_vector<graph_type, T> &capacity;
+    NodeIt s;
+    NodeIt t;
+    typename graph_type::EdgeMap<T> &capacity;
+    //typename graph_type::EdgeMap<T>  &capacity;
     //output
-    edge_property_vector<graph_type, T> preflow;
+    //typename graph_type::EdgeMap<T>  
+    typename graph_type::EdgeMap<T> preflow;
     T maxflow_value;
   
     //auxiliary variables for computation
     int number_of_nodes;
-    node_property_vector<graph_type, int> level;
-    node_property_vector<graph_type, T> excess;
+    
+    
+    typename graph_type::NodeMap<int> level;
+    typename graph_type::NodeMap<T> excess;
+    //node_property_vector<graph_type, int> level;
+    //node_property_vector<graph_type, T> excess;
     
     //Number of nodes on each level
     vector<int> num_of_nodes_on_level;
     
     //For the FIFO implementation
-    list<node_iterator> fifo_nodes;
+    list<NodeIt> fifo_nodes;
     //For 'highest label' implementation
     int highest_active;
     //int second_highest_active;
-    vector< list<node_iterator> > active_nodes;
+    vector< list<NodeIt> > 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<graph_type, T>& _capacity)
+		      NodeIt _s, 
+		      NodeIt _t, 
+		      typename graph_type::EdgeMap<T> & _capacity)
       : G(_G), s(_s), t(_t), 
 	capacity(_capacity), 
 	preflow(_G),
 	//Counting the number of nodes
-	number_of_nodes(number_of(G.first_node())),
+	//number_of_nodes(count(G.first<EachNodeIt>())),
+	number_of_nodes(G.nodeNum()),
+
 	level(_G),
 	excess(_G)//,
         // Default constructor: active_nodes()
@@ -106,7 +127,7 @@
     //Returns the value of a maximal flow 
     T run();
   
-    edge_property_vector<graph_type, T> getmaxflow(){
+    typename graph_type::EdgeMap<T>  getmaxflow(){
       return preflow;
     }
 
@@ -114,32 +135,33 @@
   private:
     //For testing purposes only
     //Lists the node_properties
-    void write_property_vector(node_property_vector<graph_type, T> a, 
+    void write_property_vector(typename graph_type::NodeMap<T> a,
+			       //node_property_vector<graph_type, T> a, 
 			       char* prop_name="property"){
-      for(each_node_iterator i=G.first_node(); i.valid(); ++i) {
+      for(EachNodeIt i=G.template first<EachNodeIt>(); i.valid(); ++i) {
 	cout<<"Node id.: "<<G.id(i)<<", "<<prop_name<<" value: "<<a.get(i)<<endl;
       }
       cout<<endl;
     }
 
     //Modifies the excess of the node and makes sufficient changes
-    void modify_excess(const node_iterator& a ,T v){
+    void modify_excess(const NodeIt& a ,T v){
 	T old_value=excess.get(a);
-	excess.put(a,old_value+v);
+	excess.set(a,old_value+v);
     }
   
     //This private procedure is supposed to modify the preflow on edge j
     //by value v (which can be positive or negative as well) 
     //and maintain the excess on the head and tail
     //Here we do not check whether this is possible or not
-    void modify_preflow(edge_iterator j, const T& v){
+    void modify_preflow(EdgeIt j, const T& v){
 
       //Auxiliary variable
       T old_value;
 	
       //Modifiyng the edge
       old_value=preflow.get(j);
-      preflow.put(j,old_value+v);
+      preflow.set(j,old_value+v);
 
 
       //Modifiyng the head
@@ -152,7 +174,7 @@
 
     //Gives the active node to work with 
     //(depending on the implementation to be used)
-    node_iterator get_active_node(){
+    NodeIt get_active_node(){
       //cout<<highest_active<<endl;
 
       switch(implementation) {
@@ -164,12 +186,12 @@
 	}
 
 	if( highest_active>=0) {
-	  node_iterator a=active_nodes[highest_active].front();
+	  NodeIt a=active_nodes[highest_active].front();
 	  active_nodes[highest_active].pop_front();
 	  return a;
 	}
 	else {
-	  return node_iterator();
+	  return NodeIt();
 	}
 	
 	break;
@@ -178,22 +200,22 @@
       case impl_fifo : {
 
 	if( ! fifo_nodes.empty() ) {
-	  node_iterator a=fifo_nodes.front();
+	  NodeIt a=fifo_nodes.front();
 	  fifo_nodes.pop_front();
 	  return a;
 	}
 	else {
-	  return node_iterator();
+	  return NodeIt();
 	}
 	break;
       }
       }
       //
-      return node_iterator();
+      return NodeIt();
     }
 
     //Puts node 'a' among the active nodes
-    void make_active(const node_iterator& a){
+    void make_active(const NodeIt& a){
       //s and t never become active
       if (a!=s && a!= t){
 	switch(implementation){
@@ -215,14 +237,15 @@
     }
 
     //Changes the level of node a and make sufficent changes
-    void change_level_to(node_iterator a, int new_value){
+    void change_level_to(NodeIt a, int new_value){
       int seged = level.get(a);
-      level.put(a,new_value);
+      level.set(a,new_value);
       --num_of_nodes_on_level[seged];
       ++num_of_nodes_on_level[new_value];
     }
 
     //Collection of things useful (or necessary) to do before running
+
     void preprocess(){
 
       //---------------------------------------
@@ -231,11 +254,11 @@
 
       //Setting starting preflow, level and excess values to zero
       //This can be important, if the algorithm is run more then once
-      for(each_node_iterator i=G.first_node(); i.valid(); ++i) {
-        level.put(i,0);
-        excess.put(i,0);
-	for(out_edge_iterator j=G.first_out_edge(i); j.valid(); ++j) 
-	  preflow.put(j, 0);
+      for(EachNodeIt i=G.template first<EachNodeIt>(); i.valid(); ++i) {
+        level.set(i,0);
+        excess.set(i,0);
+	for(OutEdgeIt j=G.template first<OutEdgeIt>(i); j.valid(); ++j) 
+	  preflow.set(j, 0);
       }
       num_of_nodes_on_level[0]=number_of_nodes;
       highest_active=0;
@@ -251,7 +274,7 @@
       reverse_bfs<graph_type> 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) {
+      for(EachNodeIt i=G.template first<EachNodeIt>(); i.valid(); ++i) {
         change_level_to(i,rev_bfs.dist(i));
 	//level.put(i,rev_bfs.dist.get(i));
       }
@@ -266,7 +289,7 @@
       
       
       //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){ 
+      for(OutEdgeIt j=G.template first<OutEdgeIt>(s); j.valid(); ++j){ 
 	modify_preflow(j,capacity.get(j) );
 	make_active(G.head(j));
 	int lev=level.get(G.head(j));
@@ -280,7 +303,7 @@
     
     //If the preflow is less than the capacity on the given edge
     //then it is an edge in the residual graph
-    bool is_admissible_forward_edge(out_edge_iterator j, int& new_level){
+    bool is_admissible_forward_edge(OutEdgeIt j, int& new_level){
       if (capacity.get(j)>preflow.get(j)){
 	if(level.get(G.tail(j))==level.get(G.head(j))+1){
 	  return true;
@@ -295,7 +318,7 @@
 
     //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){
+    bool is_admissible_backward_edge(InEdgeIt j, int& new_level){
       if (0<preflow.get(j)){
 	if(level.get(G.tail(j))==level.get(G.head(j))-1){
 	  return true;
@@ -318,22 +341,25 @@
     preprocess();
     
     T e,v;
-    node_iterator a;
+    NodeIt a;
     while (a=get_active_node(), a.valid()){
       //cout<<G.id(a)<<endl;
       //write_property_vector(excess,"excess");
       //write_property_vector(level,"level");
 
-      //Initial value for the new level for the active node we are dealing with
-      int new_level=2*number_of_nodes;
 
       bool go_to_next_node=false;
       e = excess.get(a);
       while (!go_to_next_node){
-	
+
+	//Initial value for the new level for the active node we are dealing with
+	int new_level=2*number_of_nodes;
+	//write_property_vector(excess,"excess");
+	//write_property_vector(level,"level");
+	//cout<<G.id(a)<<endl;
 	//Out edges from node a
 	{
-	  out_edge_iterator j=G.first_out_edge(a);
+	  OutEdgeIt j=G.template first<OutEdgeIt>(a);
 	  while (j.valid() && e){
 
 	    if (is_admissible_forward_edge(j,new_level)){
@@ -350,7 +376,7 @@
 	}
 	//In edges to node a
 	{
-	  in_edge_iterator j=G.first_in_edge(a);
+	  InEdgeIt j=G.template first<InEdgeIt>(a);
 	  while (j.valid() && e){
 	    if (is_admissible_backward_edge(j,new_level)){
 	      v=min(e,preflow.get(j));
@@ -372,7 +398,9 @@
 	  go_to_next_node=true;
 	}
 	else{//If there is still excess in node a
-
+	  
+	  //change_level_to(a,new_level+1);
+	  
 	  //Level remains empty
 	  if (num_of_nodes_on_level[level.get(a)]==1){
 	    change_level_to(a,number_of_nodes);
@@ -382,7 +410,7 @@
 	    change_level_to(a,new_level+1);
 	    //increase_level(a);
 	  }
-
+	  
     
 	  
 

Added: hugo/trunk/src/work/athos/reverse_bfs.hh
==============================================================================
--- (empty file)
+++ hugo/trunk/src/work/athos/reverse_bfs.hh	Mon Feb 16 16:57:59 2004
@@ -0,0 +1,103 @@
+/*
+reverse_bfs
+by jacint
+Performs a bfs on the out edges. It does not count predecessors, 
+only the distances, but one can easily modify it to know the pred as well.
+
+Constructor: 
+
+reverse_bfs(graph_type& G, node_iterator t)
+
+
+
+Member functions:
+
+void run(): runs a reverse bfs from t
+
+  The following function should be used after run() was already run.
+
+int dist(node_iterator v) : returns the distance from v to t. It is the number of nodes if t is not reachable from v.
+
+*/
+#ifndef REVERSE_BFS_HH
+#define REVERSE_BFS_HH
+
+#include <queue>
+
+//#include <marci_list_graph.hh>
+//#include <marci_property_vector.hh>
+
+
+
+namespace  marci {
+
+  template <typename graph_type>
+  class reverse_bfs {
+
+    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;
+
+
+
+    graph_type& G;
+    NodeIt t;
+//    node_property_vector<graph_type, edge_iterator> pred;
+    //node_property_vector<graph_type, int>
+    typename graph_type::NodeMap<int> distance;
+    
+
+  public :
+
+    /*
+      The distance of the nodes is n, except t for which it is 0.
+    */
+    reverse_bfs(graph_type& _G, NodeIt _t) : 
+      G(_G), t(_t), 
+      distance(G, G.nodeNum()) {
+      distance.set(t,0);
+    }
+    
+    void run() {
+
+      //node_property_vector<graph_type, bool> 
+      typename graph_type::NodeMap<bool> reached(G, false); 
+      reached.set(t, true);
+
+      std::queue<NodeIt> bfs_queue;
+      bfs_queue.push(t);
+
+      while (!bfs_queue.empty()) {
+
+        NodeIt v=bfs_queue.front();	
+	bfs_queue.pop();
+
+	for(InEdgeIt e=G.template first<InEdgeIt>(v); e.valid(); ++e) {
+	  NodeIt w=G.tail(e);
+	  if (!reached.get(w)) {
+	    bfs_queue.push(w);
+	    distance.set(w, distance.get(v)+1);
+	    reached.set(w, true);
+	  }
+	}
+      }
+    }
+
+
+
+    int dist(NodeIt v) {
+      return distance.get(v);
+    }
+
+
+  };
+
+} // namespace marci
+
+#endif //REVERSE_BFS_HH
+
+



More information about the Lemon-commits mailing list