[Lemon-commits] deba: r3132 - hugo/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Thu Jan 11 22:22:40 CET 2007


Author: deba
Date: Thu Jan 11 22:22:39 2007
New Revision: 3132

Modified:
   hugo/trunk/lemon/graph_adaptor.h
   hugo/trunk/lemon/hao_orlin.h

Log:
Make Hao-Orlin epsilon-safe



Modified: hugo/trunk/lemon/graph_adaptor.h
==============================================================================
--- hugo/trunk/lemon/graph_adaptor.h	(original)
+++ hugo/trunk/lemon/graph_adaptor.h	Thu Jan 11 22:22:39 2007
@@ -1450,7 +1450,7 @@
     void setFlow(const FlowMap& _flow) { flow = &_flow; }
 
     bool operator[](const typename Graph::Edge& e) const {
-      return tolerance.less((*flow)[e], (*capacity)[e]);
+      return tolerance.positive((*capacity)[e] - (*flow)[e]);
     }
   };
 
@@ -1473,7 +1473,7 @@
     void setCapacity(const CapacityMap& _capacity) { capacity = &_capacity; }
     void setFlow(const FlowMap& _flow) { flow = &_flow; }
     bool operator[](const typename Graph::Edge& e) const {
-      return tolerance.less(0, Number((*flow)[e]));
+      return tolerance.positive((*flow)[e]);
     }
   };
 

Modified: hugo/trunk/lemon/hao_orlin.h
==============================================================================
--- hugo/trunk/lemon/hao_orlin.h	(original)
+++ hugo/trunk/lemon/hao_orlin.h	Thu Jan 11 22:22:39 2007
@@ -19,15 +19,19 @@
 #ifndef LEMON_HAO_ORLIN_H
 #define LEMON_HAO_ORLIN_H
 
+#include <cassert>
+ 
+
+
 #include <vector>
 #include <queue>
+#include <list>
 #include <limits>
 
 #include <lemon/maps.h>
 #include <lemon/graph_utils.h>
 #include <lemon/graph_adaptor.h>
 #include <lemon/iterable_maps.h>
- 
 
 /// \file
 /// \ingroup flowalgs
@@ -108,9 +112,6 @@
     
     OutResGraph* _out_res_graph;
 
-    typedef typename Graph::template NodeMap<OutResEdge> OutCurrentEdgeMap;
-    OutCurrentEdgeMap* _out_current_edge;  
-
     typedef RevGraphAdaptor<const Graph> RevGraph;
     RevGraph* _rev_graph;
 
@@ -120,10 +121,6 @@
     
     InResGraph* _in_res_graph;
 
-    typedef typename Graph::template NodeMap<InResEdge> InCurrentEdgeMap;
-    InCurrentEdgeMap* _in_current_edge;  
-
-
     typedef IterableBoolMap<Graph, Node> WakeMap;
     WakeMap* _wake;
 
@@ -161,8 +158,7 @@
              const Tolerance& tolerance = Tolerance()) :
       _graph(&graph), _capacity(&capacity), 
       _preflow(0), _source(), _target(), 
-      _out_res_graph(0), _out_current_edge(0),
-      _rev_graph(0), _in_res_graph(0), _in_current_edge(0),
+      _out_res_graph(0), _rev_graph(0), _in_res_graph(0),
       _wake(0),_dist(0), _excess(0), _source_set(0), 
       _highest_active(), _active_nodes(), _dormant_max(), _dormant(), 
       _min_cut(), _min_cut_map(0), _tolerance(tolerance) {}
@@ -171,18 +167,12 @@
       if (_min_cut_map) {
         delete _min_cut_map;
       } 
-      if (_in_current_edge) {
-        delete _in_current_edge;
-      }
       if (_in_res_graph) {
         delete _in_res_graph;
       }
       if (_rev_graph) {
         delete _rev_graph;
       }
-      if (_out_current_edge) {
-        delete _out_current_edge;
-      }
       if (_out_res_graph) {
         delete _out_res_graph;
       }
@@ -205,9 +195,9 @@
     
   private:
     
-    template <typename ResGraph, typename EdgeMap>
-    void findMinCut(const Node& target, bool out, 
-                    ResGraph& res_graph, EdgeMap& current_edge) {
+    template <typename ResGraph>
+    void findMinCut(const Node& target, bool out, ResGraph& res_graph) {
+      typedef typename Graph::Node Node;
       typedef typename ResGraph::Edge ResEdge;
       typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
 
@@ -219,22 +209,25 @@
         (*_dist)[it] = 1;
         (*_excess)[it] = 0;
         (*_source_set)[it] = false;
-
-        res_graph.firstOut(current_edge[it], it);
       }
 
+      _dormant[0].push_front(_source);
+      (*_source_set)[_source] = true;
+      _dormant_max = 0;
+      (*_wake)[_source] = false;
+
+      _level_size[0] = 1;
+      _level_size[1] = _node_num - 1;
+
       _target = target;
       (*_dist)[target] = 0;
 
       for (ResOutEdgeIt it(res_graph, _source); it != INVALID; ++it) {
         Value delta = res_graph.rescap(it);
-        if (!_tolerance.positive(delta)) continue;
-        
-        (*_excess)[res_graph.source(it)] -= delta;
+        (*_excess)[_source] -= delta;
         res_graph.augment(it, delta);
         Node a = res_graph.target(it);
-        if (!_tolerance.positive((*_excess)[a]) && 
-            (*_wake)[a] && a != _target) {
+        if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
           _active_nodes[(*_dist)[a]].push_front(a);
           if (_highest_active < (*_dist)[a]) {
             _highest_active = (*_dist)[a];
@@ -243,39 +236,29 @@
         (*_excess)[a] += delta;
       }
 
-      _dormant[0].push_front(_source);
-      (*_source_set)[_source] = true;
-      _dormant_max = 0;
-      (*_wake)[_source] = false;
-
-      _level_size[0] = 1;
-      _level_size[1] = _node_num - 1;
 
       do {
 	Node n;
 	while ((n = findActiveNode()) != INVALID) {
-	  ResEdge e;
-	  while (_tolerance.positive((*_excess)[n]) && 
-                 (e = findAdmissibleEdge(n, res_graph, current_edge)) 
-                 != INVALID){
-	    Value delta;
-	    if ((*_excess)[n] < res_graph.rescap(e)) {
-	      delta = (*_excess)[n];
+	  for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
+            Node a = res_graph.target(e);
+            if ((*_dist)[a] >= (*_dist)[n] || !(*_wake)[a]) continue;
+	    Value delta = res_graph.rescap(e);
+	    if (_tolerance.positive((*_excess)[n] - delta)) {
+              (*_excess)[n] -= delta;
 	    } else {
-	      delta = res_graph.rescap(e);
-	      res_graph.nextOut(current_edge[n]);
+	      delta = (*_excess)[n];
+              (*_excess)[n] = 0;
 	    }
-            if (!_tolerance.positive(delta)) continue;
 	    res_graph.augment(e, delta);
-	    (*_excess)[res_graph.source(e)] -= delta;
-	    Node a = res_graph.target(e);
-	    if (!_tolerance.positive((*_excess)[a]) && a != _target) {
+	    if ((*_excess)[a] == 0 && a != _target) {
 	      _active_nodes[(*_dist)[a]].push_front(a);
 	    }
 	    (*_excess)[a] += delta;
+            if ((*_excess)[n] == 0) break;
 	  }
-	  if (_tolerance.positive((*_excess)[n])) {
-	    relabel(n, res_graph, current_edge);
+	  if ((*_excess)[n] != 0) {
+	    relabel(n, res_graph);
           }
 	}
 
@@ -297,8 +280,8 @@
       } while (selectNewSink(res_graph));
     }
 
-    template <typename ResGraph, typename EdgeMap>
-    void relabel(const Node& n, ResGraph& res_graph, EdgeMap& current_edge) {
+    template <typename ResGraph>
+    void relabel(const Node& n, ResGraph& res_graph) {
       typedef typename ResGraph::OutEdgeIt ResOutEdgeIt;
 
       int k = (*_dist)[n];
@@ -311,7 +294,7 @@
 	    --_level_size[(*_dist)[it]];
 	  }
 	}
-	--_highest_active;
+        --_highest_active;
       } else {	
         int new_dist = _node_num;
         for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e) {
@@ -331,7 +314,6 @@
 	  _highest_active = (*_dist)[n];
 	  _active_nodes[_highest_active].push_front(n);
 	  ++_level_size[(*_dist)[n]];
-	  res_graph.firstOut(current_edge[n], n);
 	}
       }
     }
@@ -372,38 +354,34 @@
 
       if (wake_was_empty){
 	for (typename WakeMap::TrueIt it(*_wake); it != INVALID; ++it) {
-          if (_tolerance.positive((*_excess)[it])) {
-	    if ((*_wake)[it] && it != _target) {
-	      _active_nodes[(*_dist)[it]].push_front(it);
-            }
-	    if (_highest_active < (*_dist)[it]) {
-	      _highest_active = (*_dist)[it];		    
+          if ((*_excess)[it] != 0 && it != _target) {
+            _active_nodes[(*_dist)[it]].push_front(it);
+            if (_highest_active < (*_dist)[it]) {
+              _highest_active = (*_dist)[it];		    
             }
 	  }
 	}
       }
 
-      for (ResOutEdgeIt e(res_graph, old_target); e!=INVALID; ++e){
-	if (!(*_source_set)[res_graph.target(e)]) {
-          Value delta = res_graph.rescap(e);
-          if (!_tolerance.positive(delta)) continue;
-          res_graph.augment(e, delta);
-          (*_excess)[res_graph.source(e)] -= delta;
-          Node a = res_graph.target(e);
-          if (!_tolerance.positive((*_excess)[a]) && 
-              (*_wake)[a] && a != _target) {
-            _active_nodes[(*_dist)[a]].push_front(a);
-            if (_highest_active < (*_dist)[a]) {
-              _highest_active = (*_dist)[a];
-            }
+      Node n = old_target;
+      for (ResOutEdgeIt e(res_graph, n); e != INVALID; ++e){
+        Node a = res_graph.target(e);
+	if (!(*_wake)[a]) continue;
+        Value delta = res_graph.rescap(e);
+        res_graph.augment(e, delta);
+        (*_excess)[n] -= delta;
+        if ((*_excess)[a] == 0 && (*_wake)[a] && a != _target) {
+          _active_nodes[(*_dist)[a]].push_front(a);
+          if (_highest_active < (*_dist)[a]) {
+            _highest_active = (*_dist)[a];
           }
-          (*_excess)[a] += delta;
-	}
+        }
+        (*_excess)[a] += delta;
       }
       
       return true;
     }
-    
+
     Node findActiveNode() {
       while (_highest_active > 0 && _active_nodes[_highest_active].empty()){ 
 	--_highest_active;
@@ -417,25 +395,6 @@
       }
     }
 
-    template <typename ResGraph, typename EdgeMap>
-    typename ResGraph::Edge findAdmissibleEdge(const Node& n, 
-                                               ResGraph& res_graph, 
-                                               EdgeMap& current_edge) {
-      typedef typename ResGraph::Edge ResEdge;
-      ResEdge e = current_edge[n];
-      while (e != INVALID && 
-             ((*_dist)[n] <= (*_dist)[res_graph.target(e)] || 
-              !(*_wake)[res_graph.target(e)])) {
-	res_graph.nextOut(e);
-      }
-      if (e != INVALID) {
-	current_edge[n] = e;	
-	return e;
-      } else {
-	return INVALID;
-      }
-    }
-
     Value cutValue(bool out) {
       Value value = 0;
       if (out) {
@@ -512,18 +471,12 @@
       if (!_out_res_graph) {
         _out_res_graph = new OutResGraph(*_graph, *_capacity, *_preflow);
       }
-      if (!_out_current_edge) {
-        _out_current_edge = new OutCurrentEdgeMap(*_graph);
-      }
       if (!_rev_graph) {
         _rev_graph = new RevGraph(*_graph);
       }
       if (!_in_res_graph) {
         _in_res_graph = new InResGraph(*_rev_graph, *_capacity, *_preflow);
       }
-      if (!_in_current_edge) {
-        _in_current_edge = new InCurrentEdgeMap(*_graph);
-      }
       if (!_min_cut_map) {
         _min_cut_map = new MinCutMap(*_graph);
       }
@@ -555,7 +508,7 @@
     ///  and minimal out-degree). The \c target is the initial target
     /// for the push-relabel algorithm.
     void calculateOut(const Node& target) {
-      findMinCut(target, true, *_out_res_graph, *_out_current_edge);
+      findMinCut(target, true, *_out_res_graph);
     }
 
     /// \brief Calculates a minimum cut with \f$ source \f$ on the
@@ -583,7 +536,7 @@
     /// The \c target is the initial
     /// target for the push-relabel algorithm.
     void calculateIn(const Node& target) {
-      findMinCut(target, false, *_in_res_graph, *_in_current_edge);
+      findMinCut(target, false, *_in_res_graph);
     }
 
     /// \brief Runs the algorithm.



More information about the Lemon-commits mailing list