[Lemon-commits] [lemon_svn] jacint: r822 - hugo/trunk/src/work/jacint

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


Author: jacint
Date: Thu May 13 12:30:20 2004
New Revision: 822

Modified:
   hugo/trunk/src/work/jacint/max_flow.h

Log:
Almost full documentation added, NO_FLOW incorporated, Phase0(1) changed to Phase1(2)

Modified: hugo/trunk/src/work/jacint/max_flow.h
==============================================================================
--- hugo/trunk/src/work/jacint/max_flow.h	(original)
+++ hugo/trunk/src/work/jacint/max_flow.h	Thu May 13 12:30:20 2004
@@ -1,38 +1,4 @@
 // -*- C++ -*-
-
-/*
-  Heuristics:
-  2 phase
-  gap
-  list 'level_list' on the nodes on level i implemented by hand
-  stack 'active' on the active nodes on level i
-  runs heuristic 'highest label' for H1*n relabels
-  runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
-
-  Parameters H0 and H1 are initialized to 20 and 1.
-
-  Constructors:
-
-  Preflow(Graph, Node, Node, CapMap, FlowMap, bool) : bool must be false if
-  FlowMap is not constant zero, and should be true if it is
-
-  Members:
-
-  void run()
-
-  Num flowValue() : returns the value of a maximum flow
-
-  void minMinCut(CutMap& M) : sets M to the characteristic vector of the
-  minimum min cut. M should be a map of bools initialized to false. ??Is it OK?
-
-  void maxMinCut(CutMap& M) : sets M to the characteristic vector of the
-  maximum min cut. M should be a map of bools initialized to false.
-
-  void minCut(CutMap& M) : sets M to the characteristic vector of
-  a min cut. M should be a map of bools initialized to false.
-
-*/
-
 #ifndef HUGO_MAX_FLOW_H
 #define HUGO_MAX_FLOW_H
 
@@ -47,15 +13,35 @@
 #include <for_each_macros.h>
 
 /// \file
-/// \brief Maximum flows.
+/// \brief Maximum flow algorithms.
 /// \ingroup galgs
 
 namespace hugo {
 
-
-  //  ///\author Marton Makai, Jacint Szabo
-  /// A class for computing max flows and related quantities.
-  /// \ingroup galgs
+  /// \addtogroup galgs
+  /// @{                                                                                                                                        
+  ///Maximum flow algorithms class.
+
+  ///This class provides various algorithms for finding a flow of
+  ///maximum value in a directed graph. The \e source node, the \e
+  ///target node, the \e capacity of the edges and the \e starting \e
+  ///flow value of the edges can be passed to the algorithm through the
+  ///constructor. It is possible to change these quantities using the
+  ///functions \ref resetSource, \ref resetTarget, \ref resetCap and
+  ///\ref resetFlow. Before any subsequent runs of any algorithm of
+  ///the class \ref resetFlow should be called, otherwise it will
+  ///start from a maximum flow.                                                                                                                 
+  ///After running an algorithm of the class, the maximum value of a
+  ///value can be obtained by calling \ref flowValue(). The minimum
+  ///value cut can be written into a \c node map of \c bools by
+  ///calling \ref minCut. (\ref minMinCut and \ref maxMinCut writes
+  ///the inclusionwise minimum and maximum of the minimum value
+  ///cuts, resp.)                                                                                                                               
+  ///\param Graph The undirected graph type the algorithm runs on.
+  ///\param Num The number type of the capacities and the flow values.
+  ///\param CapMap The type of the capacity map.
+  ///\param FlowMap The type of the flow map.                                                                                                           
+  ///\author Marton Makai, Jacint Szabo 
   template <typename Graph, typename Num,
 	    typename CapMap=typename Graph::template EdgeMap<Num>,
             typename FlowMap=typename Graph::template EdgeMap<Num> >
@@ -63,6 +49,7 @@
   protected:
     typedef typename Graph::Node Node;
     typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::EdgeIt EdgeIt;
     typedef typename Graph::OutEdgeIt OutEdgeIt;
     typedef typename Graph::InEdgeIt InEdgeIt;
 
@@ -81,13 +68,18 @@
     typedef typename ResGW::Edge ResGWEdge;
     //typedef typename ResGW::template NodeMap<bool> ReachedMap;
     typedef typename Graph::template NodeMap<int> ReachedMap;
+
+
+    //level works as a bool map in augmenting path algorithms and is
+    //used by bfs for storing reached information.  In preflow, it
+    //shows the levels of nodes.     
     ReachedMap level;
-    //level works as a bool map in augmenting path algorithms
-    //and is used by bfs for storing reached information.
-    //In preflow, it shows levels of nodes.
-    //typename Graph::template NodeMap<int> level;
+
+    //excess is needed only in preflow
     typename Graph::template NodeMap<Num> excess;
-    //   protected:
+
+    //fixme    
+//   protected:
     //     MaxFlow() { }
     //     void set(const Graph& _G, Node _s, Node _t, const CapMap& _capacity,
     // 	     FlowMap& _flow)
@@ -108,12 +100,17 @@
 
   public:
 
-    ///\todo Document this.
-    ///\todo Maybe, it should be PRE_FLOW instead.
-    ///- \c NO_FLOW means nothing,
-    ///- \c ZERO_FLOW means something,
-    ///- \c GEN_FLOW means something else,
-    ///- \c PRE_FLOW is something different.
+    ///Indicates the property of the starting flow.
+
+    ///Indicates the property of the starting flow. The meanings are as follows:
+    ///- \c ZERO_FLOW: constant zero flow
+    ///- \c GEN_FLOW: any flow, i.e. the sum of the in-flows equals to
+    ///the sum of the out-flows in every node except the \e source and
+    ///the \e target.
+    ///- \c PRE_FLOW: any preflow, i.e. the sum of the in-flows is at 
+    ///least the sum of the out-flows in every node except the \e source.
+    ///- \c NO_FLOW: indicates an unspecified edge map. \ref flow will be 
+    ///set to the constant zero flow in the beginning of the algorithm in this case.
     enum flowEnum{
       ZERO_FLOW,
       GEN_FLOW,
@@ -126,30 +123,66 @@
       g(&_G), s(_s), t(_t), capacity(&_capacity),
       flow(&_flow), n(_G.nodeNum()), level(_G), excess(_G,0) {}
 
-    /// A max flow algorithm is run.
-    /// \pre The flow have to satisfy the requirements
-    /// stated in fe.
+    ///Runs a maximum flow algorithm.
+
+    ///Runs a preflow algorithm, which is the fastest maximum flow
+    ///algorithm up-to-date. The default for \c fe is ZERO_FLOW.
+    ///\pre The starting flow must be
+    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
+    /// - an arbitary flow if \c fe is \c GEN_FLOW,
+    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
+    /// - any map if \c fe is NO_FLOW.
     void run(flowEnum fe=ZERO_FLOW) {
       preflow(fe);
     }
 
-    /// A preflow algorithm is run.
-    /// \pre The initial edge-map have to be a
-    /// zero flow if \c fe is \c ZERO_FLOW,
-    /// a flow if \c fe is \c GEN_FLOW,
-    /// a pre-flow if fe is \c PRE_FLOW and
-    /// anything if fe is NO_FLOW.
+                                                                                             
+    ///Runs a preflow algorithm.  
+
+    ///Runs a preflow algorithm. The preflow algorithms provide the
+    ///fastest way to compute a maximum flow in a directed graph.
+    ///\pre The starting flow must be
+    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
+    /// - an arbitary flow if \c fe is \c GEN_FLOW,
+    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
+    /// - any map if \c fe is NO_FLOW.
     void preflow(flowEnum fe) {
-      preflowPhase0(fe);
-      preflowPhase1();
+      preflowPhase1(fe);
+      preflowPhase2();
     }
-
-    /// Run the first phase of preflow, starting from a 0 flow, from a flow,
-    /// or from a preflow, of from undefined value according to \c fe.
-    void preflowPhase0(flowEnum fe);
-
-    /// Second phase of preflow.
-    void preflowPhase1();
+    // Heuristics:
+    //   2 phase
+    //   gap
+    //   list 'level_list' on the nodes on level i implemented by hand
+    //   stack 'active' on the active nodes on level i                                                                                    
+    //   runs heuristic 'highest label' for H1*n relabels
+    //   runs heuristic 'bound decrease' for H0*n relabels, starts with 'highest label'
+    //   Parameters H0 and H1 are initialized to 20 and 1.
+
+    ///Runs the first phase of the preflow algorithm.
+
+    ///The preflow algorithm consists of two phases, this method runs the
+    ///first phase. After the first phase the maximum flow value and a
+    ///minimum value cut can already be computed, though a maximum flow
+    ///is net yet obtained. So after calling this method \ref flowValue
+    ///and \ref actMinCut gives proper results.
+    ///\warning: \ref minCut, \ref minMinCut and \ref maxMinCut do not
+    ///give minimum value cuts unless calling \ref preflowPhase2.
+    ///\pre The starting flow must be
+    /// - a constant zero flow if \c fe is \c ZERO_FLOW,
+    /// - an arbitary flow if \c fe is \c GEN_FLOW,
+    /// - an arbitary preflow if \c fe is \c PRE_FLOW,
+    /// - any map if \c fe is NO_FLOW.
+    void preflowPhase1( flowEnum fe );
+
+    ///Runs the second phase of the preflow algorithm.
+
+    ///The preflow algorithm consists of two phases, this method runs
+    ///the second phase. After calling \ref preflowPhase1 and then
+    ///\ref preflowPhase2 the methods \ref flowValue, \ref minCut,
+    ///\ref minMinCut and \ref maxMinCut give proper results.
+    ///\pre \ref preflowPhase1 must be called before.
+    void preflowPhase2();
 
     /// Starting from a flow, this method searches for an augmenting path
     /// according to the Edmonds-Karp algorithm
@@ -169,17 +202,27 @@
     /// The return value shows if the augmentation was succesful.
     bool augmentOnBlockingFlow2();
 
-    /// Returns the actual flow value.
-    /// More precisely, it returns the negative excess of s, thus
-    /// this works also for preflows.
+    /// Returns the maximum value of a flow.
+
+    /// Returns the maximum value of a flow, by counting the 
+    /// over-flow of the target node \ref t.
+    /// It can be called already after running \ref preflowPhase1.
     Num flowValue() {
       Num a=0;
       FOR_EACH_INC_LOC(InEdgeIt, e, *g, t) a+=(*flow)[e];
       FOR_EACH_INC_LOC(OutEdgeIt, e, *g, t) a-=(*flow)[e];
       return a;
+      //marci figyu: excess[t] epp ezt adja preflow 1. fazisa utan   
     }
 
-    /// Should be used between preflowPhase0 and preflowPhase1.
+    ///Returns a minimum value cut after calling \ref preflowPhase1.
+
+    ///After the first phase of the preflow algorithm the maximum flow
+    ///value and a minimum value cut can already be computed. This
+    ///method can be called after running \ref preflowPhase1 for
+    ///obtaining a minimum value cut.
+    /// \warning Gives proper result only right after calling \ref
+    /// preflowPhase1.
     /// \todo We have to make some status variable which shows the
     /// actual state
     /// of the class. This enables us to determine which methods are valid
@@ -196,9 +239,13 @@
       }
     }
 
-    /// The unique inclusionwise minimum cut is computed by
-    /// processing a bfs from s in the residual graph.
-    /// \pre flow have to be a max flow otherwise it will the whole node-set.
+    ///Returns the inclusionwise minimum of the minimum value cuts.
+
+    ///Sets \c M to the characteristic vector of the minimum value cut
+    ///which is inclusionwise minimum. It is computed by processing
+    ///a bfs from the source node \c s in the residual graph.
+    ///\pre M should be a node map of bools initialized to false.
+    ///\pre \c flow must be a maximum flow.
     template<typename _CutMap>
     void minMinCut(_CutMap& M) {
 
@@ -231,10 +278,13 @@
       }
     }
 
+    ///Returns the inclusionwise maximum of the minimum value cuts.
 
-    /// The unique inclusionwise maximum cut is computed by
-    /// processing a reverse bfs from t in the residual graph.
-    /// \pre flow have to be a max flow otherwise it will be empty.
+    ///Sets \c M to the characteristic vector of the minimum value cut
+    ///which is inclusionwise maximum. It is computed by processing a
+    ///backward bfs from the target node \c t in the residual graph.
+    ///\pre M should be a node map of bools initialized to false.
+    ///\pre \c flow must be a maximum flow. 
     template<typename _CutMap>
     void maxMinCut(_CutMap& M) {
 
@@ -272,20 +322,36 @@
       }
     }
 
+    ///Returns a minimum value cut.
 
-    /// A minimum cut is computed.
+    ///Sets \c M to the characteristic vector of a minimum value cut.
+    ///\pre M should be a node map of bools initialized to false.
+    ///\pre \c flow must be a maximum flow.    
     template<typename CutMap>
     void minCut(CutMap& M) { minMinCut(M); }
 
-    ///
+    ///Resets the source node to \c _s.
+
+    ///Resets the source node to \c _s.
+    /// 
     void resetSource(Node _s) { s=_s; }
+
+    ///Resets the target node to \c _t.
+
+    ///Resets the target node to \c _t.
     ///
     void resetTarget(Node _t) { t=_t; }
 
-    /// capacity-map is changed.
+    /// Resets the edge map of the capacities to _cap.
+
+    /// Resets the edge map of the capacities to _cap.
+    /// 
     void resetCap(const CapMap& _cap) { capacity=&_cap; }
 
-    /// flow-map is changed.
+    /// Resets the edge map of the flows to _flow.
+
+    /// Resets the edge map of the flows to _flow.
+    /// 
     void resetFlow(FlowMap& _flow) { flow=&_flow; }
 
 
@@ -374,6 +440,7 @@
       std::queue<Node> bfs_queue;
 
       switch (fe) {
+      case NO_FLOW:   //flow is already set to const zero in this case
       case ZERO_FLOW:
 	{
 	  //Reverse_bfs from t, to find the starting level.
@@ -586,7 +653,7 @@
 
 
   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
-  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase0( flowEnum fe )
+  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1( flowEnum fe )
   {
 
     int heur0=(int)(H0*n);  //time while running 'bound decrease'
@@ -615,10 +682,14 @@
     for(g->first(v); g->valid(v); g->next(v)) level.set(v,n);
     //setting each node to level n
 
-    switch (fe) {
+    if ( fe == NO_FLOW ) {
+      EdgeIt e;
+      for(g->first(e); g->valid(e); g->next(e)) flow->set(e,0);
+    }
+
+    switch (fe) { //computing the excess
     case PRE_FLOW:
       {
-	//computing the excess
 	NodeIt v;
 	for(g->first(v); g->valid(v); g->next(v)) {
 	  Num exc=0;
@@ -638,19 +709,24 @@
       }
     case GEN_FLOW:
       {
-	//computing the excess of t
-	Num exc=0;
+	NodeIt v;
+	for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
 
+	Num exc=0;
 	InEdgeIt e;
 	for(g->first(e,t); g->valid(e); g->next(e)) exc+=(*flow)[e];
 	OutEdgeIt f;
 	for(g->first(f,t); g->valid(f); g->next(f)) exc-=(*flow)[f];
-
 	excess.set(t,exc);
-
 	break;
       }
-    default:;
+    case ZERO_FLOW:
+    case NO_FLOW:
+      {
+	NodeIt v;
+        for(g->first(v); g->valid(v); g->next(v)) excess.set(v,0);
+	break;
+      }
     }
 
     preflowPreproc(fe, active, level_list, left, right);
@@ -695,7 +771,7 @@
 
 
   template <typename Graph, typename Num, typename CapMap, typename FlowMap>
-  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase1()
+  void MaxFlow<Graph, Num, CapMap, FlowMap>::preflowPhase2()
   {
 
     int k=n-2;  //bound on the highest level under n containing a node



More information about the Lemon-commits mailing list