[Lemon-commits] Peter Kovacs: Fix tolerance usage in Preflow alg...

Lemon HG hg at lemon.cs.elte.hu
Fri Mar 23 16:14:07 CET 2018


details:   http://lemon.cs.elte.hu/hg/lemon/rev/8db773f19586
changeset: 1385:8db773f19586
user:      Peter Kovacs <kpeter [at] inf.elte.hu>
date:      Thu Mar 22 18:56:47 2018 +0100
description:
	Fix tolerance usage in Preflow algorithm (#608)

diffstat:

 lemon/preflow.h       |  12 +++++-----
 test/max_flow_test.cc |  58 +++++++++++++++++++++++++++++++++++++++++++-------
 2 files changed, 55 insertions(+), 15 deletions(-)

diffs (176 lines):

diff --git a/lemon/preflow.h b/lemon/preflow.h
--- a/lemon/preflow.h
+++ b/lemon/preflow.h
@@ -476,7 +476,7 @@
     /// Initializes the internal data structures and sets the initial
     /// flow to the given \c flowMap. The \c flowMap should contain a
     /// flow or at least a preflow, i.e. at each node excluding the
-    /// source node the incoming flow should greater or equal to the
+    /// source node the incoming flow should be greater or equal to the
     /// outgoing flow.
     /// \return \c false if the given \c flowMap is not a preflow.
     template <typename FlowMap>
@@ -495,7 +495,7 @@
         for (OutArcIt e(_graph, n); e != INVALID; ++e) {
           excess -= (*_flow)[e];
         }
-        if (excess < 0 && n != _source) return false;
+        if (_tolerance.negative(excess) && n != _source) return false;
         (*_excess)[n] = excess;
       }
 
@@ -639,7 +639,7 @@
 
           (*_excess)[n] = excess;
 
-          if (excess != 0) {
+          if (_tolerance.nonZero(excess)) {
             if (new_level + 1 < _level->maxLevel()) {
               _level->liftHighestActive(new_level + 1);
             } else {
@@ -720,7 +720,7 @@
 
           (*_excess)[n] = excess;
 
-          if (excess != 0) {
+          if (_tolerance.nonZero(excess)) {
             if (new_level + 1 < _level->maxLevel()) {
               _level->liftActiveOn(level, new_level + 1);
             } else {
@@ -791,7 +791,7 @@
       for (NodeIt n(_graph); n != INVALID; ++n) {
         if (!reached[n]) {
           _level->dirtyTopButOne(n);
-        } else if ((*_excess)[n] > 0 && _target != n) {
+        } else if (_tolerance.positive((*_excess)[n]) && _target != n) {
           _level->activate(n);
         }
       }
@@ -852,7 +852,7 @@
 
         (*_excess)[n] = excess;
 
-        if (excess != 0) {
+        if (_tolerance.nonZero(excess)) {
           if (new_level + 1 < _level->maxLevel()) {
             _level->liftHighestActive(new_level + 1);
           } else {
diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
--- a/test/max_flow_test.cc
+++ b/test/max_flow_test.cc
@@ -66,6 +66,38 @@
   "source 1\n"
   "target 8\n";
 
+char test_lgf_float[] =
+  "@nodes\n"
+  "label\n"
+  "0\n"
+  "1\n"
+  "2\n"
+  "3\n"
+  "4\n"
+  "5\n"
+  "6\n"
+  "7\n"
+  "8\n"
+  "9\n"
+  "@arcs\n"
+  "      capacity\n"
+  "0 1 0.1\n"
+  "0 2 0.1\n"
+  "0 3 0.1\n"
+  "1 4 0.1\n"
+  "2 4 0.1\n"
+  "3 4 0.1\n"
+  "4 5 0.3\n"
+  "5 6 0.1\n"
+  "5 7 0.1\n"
+  "5 8 0.1\n"
+  "6 9 0.1\n"
+  "7 9 0.1\n"
+  "8 9 0.1\n"
+  "@attributes\n"
+  "source 0\n"
+  "target 9\n";
+
 // Checks the general interface of a max flow algorithm
 template <typename GR, typename CAP>
 struct MaxFlowClassConcept
@@ -258,10 +290,10 @@
   Node s, t;
   CapMap cap(g);
   std::istringstream input(input_lgf);
-  DigraphReader<Digraph>(g,input)
+  DigraphReader<Digraph>(g, input)
       .arcMap("capacity", cap)
-      .node("source",s)
-      .node("target",t)
+      .node("source", s)
+      .node("target", t)
       .run();
 
   MF max_flow(g, cap, s, t);
@@ -280,8 +312,8 @@
         "Incorrect min cut value.");
 
   FlowMap flow(g);
-  for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
-  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
+  for (ArcIt e(g); e != INVALID; ++e) flow[e] = 13 * max_flow.flowMap()[e];
+  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 17 * cap[e];
   max_flow.init(flow);
 
   SF::startFirstPhase(max_flow);       // start first phase of the algorithm
@@ -290,9 +322,9 @@
   max_flow.minCutMap(min_cut1);
   min_cut_value = cutValue(g, min_cut1, cap);
 
-  check(!tol.different(2 * expected, max_flow.flowValue()),
+  check(!tol.different(17 * expected, max_flow.flowValue()),
         "Incorrect max flow value.");
-  check(!tol.different(2 * expected, min_cut_value),
+  check(!tol.different(17 * expected, min_cut_value),
         "Incorrect min cut value.");
 
   SF::startSecondPhase(max_flow);       // start second phase of the algorithm
@@ -304,9 +336,9 @@
   max_flow.minCutMap(min_cut2);
   min_cut_value = cutValue(g, min_cut2, cap);
 
-  check(!tol.different(2 * expected, max_flow.flowValue()),
+  check(!tol.different(17 * expected, max_flow.flowValue()),
         "Incorrect max flow value.");
-  check(!tol.different(2 * expected, min_cut_value),
+  check(!tol.different(17 * expected, min_cut_value),
         "Incorrect min cut value.");
 
   max_flow.flowMap(flow);
@@ -382,19 +414,27 @@
   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
   typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<double> > PType3;
+
   checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(test_lgf, 13);
   checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf, 13);
   checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf, 13);
 
+  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf_float, 0.3);
+  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf_float, 0.3);
+
   checkInitPreflow();
 
   // Check EdmondsKarp
   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
   typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<double> > EKType3;
+
   checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(test_lgf, 13);
   checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf, 13);
   checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf, 13);
 
+  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf_float, 0.3);
+  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf_float, 0.3);
+
   return 0;
 }


More information about the Lemon-commits mailing list