COIN-OR::LEMON - Graph Library

Ticket #608: 608-all-e0ccc1f0268f--8db773f19586.patch

File 608-all-e0ccc1f0268f--8db773f19586.patch, 17.1 KB (added by Peter Kovacs, 5 years ago)
  • test/max_flow_test.cc

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1521741301 -3600
    #      Thu Mar 22 18:55:01 2018 +0100
    # Node ID e0ccc1f0268f086456eb14044fcbaaaf11824dd2
    # Parent  dceba191c00dbe9bb4867fab619aac7a9c232ae9
    Remove unused typedefs in max_flow_test.cc (#608)
    
    diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
    a b  
    165165  typedef int Value;
    166166  typedef concepts::Digraph Digraph;
    167167  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
    168   typedef Elevator<Digraph, Digraph::Node> Elev;
    169   typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
    170168
    171169  Digraph g;
    172170  Digraph::Node n;
  • test/max_flow_test.cc

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1521741331 -3600
    #      Thu Mar 22 18:55:31 2018 +0100
    # Node ID e2732b9da429ccdd732e43e62c580640a36af15e
    # Parent  e0ccc1f0268f086456eb14044fcbaaaf11824dd2
    Refactoring and code formatting in max_flow_test.cc (#608)
    
    diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
    a b  
    182182
    183183
    184184template <typename T>
    185 T cutValue (const SmartDigraph& g,
    186               const SmartDigraph::NodeMap<bool>& cut,
    187               const SmartDigraph::ArcMap<T>& cap) {
     185T cutValue(const SmartDigraph& g,
     186           const SmartDigraph::NodeMap<bool>& cut,
     187           const SmartDigraph::ArcMap<T>& cap) {
    188188
    189   T c=0;
    190   for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
    191     if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
     189  T c = 0;
     190  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
     191    if (cut[g.source(e)] && !cut[g.target(e)]) c += cap[e];
    192192  }
    193193  return c;
    194194}
     
    217217  return true;
    218218}
    219219
    220 void initFlowTest()
     220void checkInitPreflow()
    221221{
    222222  DIGRAPH_TYPEDEFS(SmartDigraph);
    223223
    224224  SmartDigraph g;
    225   SmartDigraph::ArcMap<int> cap(g),iflow(g);
    226   Node s=g.addNode(); Node t=g.addNode();
    227   Node n1=g.addNode(); Node n2=g.addNode();
     225  SmartDigraph::ArcMap<int> cap(g), iflow(g);
     226  Node s = g.addNode(); Node t = g.addNode();
     227  Node n1 = g.addNode(); Node n2 = g.addNode();
    228228  Arc a;
    229   a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
    230   a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
    231   a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
     229  a = g.addArc(s, n1); cap[a] = 20; iflow[a] = 20;
     230  a = g.addArc(n1, n2); cap[a] = 10; iflow[a] = 0;
     231  a = g.addArc(n2, t); cap[a] = 20; iflow[a] = 0;
    232232
    233   Preflow<SmartDigraph> pre(g,cap,s,t);
     233  Preflow<SmartDigraph> pre(g, cap, s, t);
    234234  pre.init(iflow);
    235235  pre.startFirstPhase();
    236   check(pre.flowValue() == 10, "The incorrect max flow value.");
     236
     237  check(pre.flowValue() == 10, "Incorrect max flow value.");
    237238  check(pre.minCut(s), "Wrong min cut (Node s).");
    238239  check(pre.minCut(n1), "Wrong min cut (Node n1).");
    239240  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
     
    302303
    303304  check(max_flow.flowValue() == min_cut_value &&
    304305        min_cut_value == 2 * flow_value,
    305         "The max flow value or the min cut value was not doubled");
    306 
     306        "The max flow value or the min cut value was not doubled.");
    307307
    308308  max_flow.flowMap(flow);
    309309
     
    322322
    323323  CutMap min_cut3(g);
    324324  max_flow.minCutMap(min_cut3);
    325   min_cut_value=cutValue(g, min_cut3, cap);
     325  min_cut_value = cutValue(g, min_cut3, cap);
    326326
    327327  check(max_flow.flowValue() == min_cut_value,
    328328        "The max flow value or the min cut value is wrong.");
     
    379379  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
    380380  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
    381381  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
    382   initFlowTest();
     382
     383  checkInitPreflow();
    383384
    384385  // Check EdmondsKarp
    385386  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
     
    387388  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
    388389  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
    389390
    390   initFlowTest();
    391 
    392391  return 0;
    393392}
  • test/max_flow_test.cc

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1521741359 -3600
    #      Thu Mar 22 18:55:59 2018 +0100
    # Node ID e018899c2926e73e5f825f893cd3cea8edc1d54b
    # Parent  e2732b9da429ccdd732e43e62c580640a36af15e
    Use tolerance in max_flow_test.cc (#608)
    
    diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
    a b  
    2626#include <lemon/concepts/maps.h>
    2727#include <lemon/lgf_reader.h>
    2828#include <lemon/elevator.h>
     29#include <lemon/tolerance.h>
    2930
    3031using namespace lemon;
    3132
     
    6566  "source 1\n"
    6667  "target 8\n";
    6768
    68 
    6969// Checks the general interface of a max flow algorithm
    7070template <typename GR, typename CAP>
    7171struct MaxFlowClassConcept
     
    197197bool checkFlow(const SmartDigraph& g,
    198198               const SmartDigraph::ArcMap<T>& flow,
    199199               const SmartDigraph::ArcMap<T>& cap,
    200                SmartDigraph::Node s, SmartDigraph::Node t) {
     200               SmartDigraph::Node s, SmartDigraph::Node t,
     201               const Tolerance<T>& tol) {
    201202
    202203  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
    203     if (flow[e] < 0 || flow[e] > cap[e]) return false;
     204    if (tol.negative(flow[e]) || tol.less(cap[e], flow[e])) return false;
    204205  }
    205206
    206207  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
     
    212213    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
    213214      sum -= flow[e];
    214215    }
    215     if (sum != 0) return false;
     216    if (tol.nonZero(sum)) return false;
    216217  }
    217218  return true;
    218219}
     
    251252  typedef CapMap FlowMap;
    252253  typedef BoolNodeMap CutMap;
    253254
     255  Tolerance<Value> tol;
     256
    254257  Digraph g;
    255258  Node s, t;
    256259  CapMap cap(g);
     
    264267  MF max_flow(g, cap, s, t);
    265268  max_flow.run();
    266269
    267   check(checkFlow(g, max_flow.flowMap(), cap, s, t),
     270  check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol),
    268271        "The flow is not feasible.");
    269272
    270273  CutMap min_cut(g);
    271274  max_flow.minCutMap(min_cut);
    272275  Value min_cut_value = cutValue(g, min_cut, cap);
    273276
    274   check(max_flow.flowValue() == min_cut_value,
     277  check(!tol.different(max_flow.flowValue(), min_cut_value),
    275278        "The max flow value is not equal to the min cut value.");
    276279
    277280  FlowMap flow(g);
     
    288291  max_flow.minCutMap(min_cut1);
    289292  min_cut_value = cutValue(g, min_cut1, cap);
    290293
    291   check(max_flow.flowValue() == min_cut_value &&
    292         min_cut_value == 2 * flow_value,
     294  check(!tol.different(max_flow.flowValue(), min_cut_value) &&
     295        !tol.different(min_cut_value, 2 * flow_value),
    293296        "The max flow value or the min cut value is wrong.");
    294297
    295298  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
    296299
    297   check(checkFlow(g, max_flow.flowMap(), cap, s, t),
     300  check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol),
    298301        "The flow is not feasible.");
    299302
    300303  CutMap min_cut2(g);
    301304  max_flow.minCutMap(min_cut2);
    302305  min_cut_value = cutValue(g, min_cut2, cap);
    303306
    304   check(max_flow.flowValue() == min_cut_value &&
    305         min_cut_value == 2 * flow_value,
     307  check(!tol.different(max_flow.flowValue(), min_cut_value) &&
     308        !tol.different(min_cut_value, 2 * flow_value),
    306309        "The max flow value or the min cut value was not doubled.");
    307310
    308311  max_flow.flowMap(flow);
     
    324327  max_flow.minCutMap(min_cut3);
    325328  min_cut_value = cutValue(g, min_cut3, cap);
    326329
    327   check(max_flow.flowValue() == min_cut_value,
     330  check(!tol.different(max_flow.flowValue(), min_cut_value),
    328331        "The max flow value or the min cut value is wrong.");
    329332}
    330333
  • test/max_flow_test.cc

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1521741386 -3600
    #      Thu Mar 22 18:56:26 2018 +0100
    # Node ID 259e3a90ad9762ec1d5adfe8f259aeb59acc79f1
    # Parent  e018899c2926e73e5f825f893cd3cea8edc1d54b
    Improve max flow test method: set expected flow value (#608)
    
    diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
    a b  
    243243}
    244244
    245245template <typename MF, typename SF>
    246 void checkMaxFlowAlg() {
     246void checkMaxFlowAlg(const char *input_lgf,  typename MF::Value expected) {
    247247  typedef SmartDigraph Digraph;
    248248  DIGRAPH_TYPEDEFS(Digraph);
    249249
     
    257257  Digraph g;
    258258  Node s, t;
    259259  CapMap cap(g);
    260   std::istringstream input(test_lgf);
     260  std::istringstream input(input_lgf);
    261261  DigraphReader<Digraph>(g,input)
    262262      .arcMap("capacity", cap)
    263263      .node("source",s)
     
    267267  MF max_flow(g, cap, s, t);
    268268  max_flow.run();
    269269
     270  check(!tol.different(expected, max_flow.flowValue()),
     271        "Incorrect max flow value.");
    270272  check(checkFlow(g, max_flow.flowMap(), cap, s, t, tol),
    271273        "The flow is not feasible.");
    272274
     
    274276  max_flow.minCutMap(min_cut);
    275277  Value min_cut_value = cutValue(g, min_cut, cap);
    276278
    277   check(!tol.different(max_flow.flowValue(), min_cut_value),
    278         "The max flow value is not equal to the min cut value.");
     279  check(!tol.different(expected, min_cut_value),
     280        "Incorrect min cut value.");
    279281
    280282  FlowMap flow(g);
    281283  for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
    282 
    283   Value flow_value = max_flow.flowValue();
    284 
    285284  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
    286285  max_flow.init(flow);
    287286
     
    291290  max_flow.minCutMap(min_cut1);
    292291  min_cut_value = cutValue(g, min_cut1, cap);
    293292
    294   check(!tol.different(max_flow.flowValue(), min_cut_value) &&
    295         !tol.different(min_cut_value, 2 * flow_value),
    296         "The max flow value or the min cut value is wrong.");
     293  check(!tol.different(2 * expected, max_flow.flowValue()),
     294        "Incorrect max flow value.");
     295  check(!tol.different(2 * expected, min_cut_value),
     296        "Incorrect min cut value.");
    297297
    298298  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
    299299
     
    304304  max_flow.minCutMap(min_cut2);
    305305  min_cut_value = cutValue(g, min_cut2, cap);
    306306
    307   check(!tol.different(max_flow.flowValue(), min_cut_value) &&
    308         !tol.different(min_cut_value, 2 * flow_value),
    309         "The max flow value or the min cut value was not doubled.");
     307  check(!tol.different(2 * expected, max_flow.flowValue()),
     308        "Incorrect max flow value.");
     309  check(!tol.different(2 * expected, min_cut_value),
     310        "Incorrect min cut value.");
    310311
    311312  max_flow.flowMap(flow);
    312313
     
    380381  // Check Preflow
    381382  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
    382383  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
    383   checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
    384   checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
     384  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<double> > PType3;
     385  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(test_lgf, 13);
     386  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf, 13);
     387  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf, 13);
    385388
    386389  checkInitPreflow();
    387390
    388391  // Check EdmondsKarp
    389392  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
    390393  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
    391   checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
    392   checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
     394  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<double> > EKType3;
     395  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(test_lgf, 13);
     396  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf, 13);
     397  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf, 13);
    393398
    394399  return 0;
    395400}
  • lemon/preflow.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1521741407 -3600
    #      Thu Mar 22 18:56:47 2018 +0100
    # Node ID 8db773f19586549b6df21c715965f16113267092
    # Parent  259e3a90ad9762ec1d5adfe8f259aeb59acc79f1
    Fix tolerance usage in Preflow algorithm (#608)
    
    diff --git a/lemon/preflow.h b/lemon/preflow.h
    a b  
    476476    /// Initializes the internal data structures and sets the initial
    477477    /// flow to the given \c flowMap. The \c flowMap should contain a
    478478    /// flow or at least a preflow, i.e. at each node excluding the
    479     /// source node the incoming flow should greater or equal to the
     479    /// source node the incoming flow should be greater or equal to the
    480480    /// outgoing flow.
    481481    /// \return \c false if the given \c flowMap is not a preflow.
    482482    template <typename FlowMap>
     
    495495        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
    496496          excess -= (*_flow)[e];
    497497        }
    498         if (excess < 0 && n != _source) return false;
     498        if (_tolerance.negative(excess) && n != _source) return false;
    499499        (*_excess)[n] = excess;
    500500      }
    501501
     
    639639
    640640          (*_excess)[n] = excess;
    641641
    642           if (excess != 0) {
     642          if (_tolerance.nonZero(excess)) {
    643643            if (new_level + 1 < _level->maxLevel()) {
    644644              _level->liftHighestActive(new_level + 1);
    645645            } else {
     
    720720
    721721          (*_excess)[n] = excess;
    722722
    723           if (excess != 0) {
     723          if (_tolerance.nonZero(excess)) {
    724724            if (new_level + 1 < _level->maxLevel()) {
    725725              _level->liftActiveOn(level, new_level + 1);
    726726            } else {
     
    791791      for (NodeIt n(_graph); n != INVALID; ++n) {
    792792        if (!reached[n]) {
    793793          _level->dirtyTopButOne(n);
    794         } else if ((*_excess)[n] > 0 && _target != n) {
     794        } else if (_tolerance.positive((*_excess)[n]) && _target != n) {
    795795          _level->activate(n);
    796796        }
    797797      }
     
    852852
    853853        (*_excess)[n] = excess;
    854854
    855         if (excess != 0) {
     855        if (_tolerance.nonZero(excess)) {
    856856          if (new_level + 1 < _level->maxLevel()) {
    857857            _level->liftHighestActive(new_level + 1);
    858858          } else {
  • test/max_flow_test.cc

    diff --git a/test/max_flow_test.cc b/test/max_flow_test.cc
    a b  
    6666  "source 1\n"
    6767  "target 8\n";
    6868
     69char test_lgf_float[] =
     70  "@nodes\n"
     71  "label\n"
     72  "0\n"
     73  "1\n"
     74  "2\n"
     75  "3\n"
     76  "4\n"
     77  "5\n"
     78  "6\n"
     79  "7\n"
     80  "8\n"
     81  "9\n"
     82  "@arcs\n"
     83  "      capacity\n"
     84  "0 1 0.1\n"
     85  "0 2 0.1\n"
     86  "0 3 0.1\n"
     87  "1 4 0.1\n"
     88  "2 4 0.1\n"
     89  "3 4 0.1\n"
     90  "4 5 0.3\n"
     91  "5 6 0.1\n"
     92  "5 7 0.1\n"
     93  "5 8 0.1\n"
     94  "6 9 0.1\n"
     95  "7 9 0.1\n"
     96  "8 9 0.1\n"
     97  "@attributes\n"
     98  "source 0\n"
     99  "target 9\n";
     100
    69101// Checks the general interface of a max flow algorithm
    70102template <typename GR, typename CAP>
    71103struct MaxFlowClassConcept
     
    258290  Node s, t;
    259291  CapMap cap(g);
    260292  std::istringstream input(input_lgf);
    261   DigraphReader<Digraph>(g,input)
     293  DigraphReader<Digraph>(g, input)
    262294      .arcMap("capacity", cap)
    263       .node("source",s)
    264       .node("target",t)
     295      .node("source", s)
     296      .node("target", t)
    265297      .run();
    266298
    267299  MF max_flow(g, cap, s, t);
     
    280312        "Incorrect min cut value.");
    281313
    282314  FlowMap flow(g);
    283   for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
    284   for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
     315  for (ArcIt e(g); e != INVALID; ++e) flow[e] = 13 * max_flow.flowMap()[e];
     316  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 17 * cap[e];
    285317  max_flow.init(flow);
    286318
    287319  SF::startFirstPhase(max_flow);       // start first phase of the algorithm
     
    290322  max_flow.minCutMap(min_cut1);
    291323  min_cut_value = cutValue(g, min_cut1, cap);
    292324
    293   check(!tol.different(2 * expected, max_flow.flowValue()),
     325  check(!tol.different(17 * expected, max_flow.flowValue()),
    294326        "Incorrect max flow value.");
    295   check(!tol.different(2 * expected, min_cut_value),
     327  check(!tol.different(17 * expected, min_cut_value),
    296328        "Incorrect min cut value.");
    297329
    298330  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
     
    304336  max_flow.minCutMap(min_cut2);
    305337  min_cut_value = cutValue(g, min_cut2, cap);
    306338
    307   check(!tol.different(2 * expected, max_flow.flowValue()),
     339  check(!tol.different(17 * expected, max_flow.flowValue()),
    308340        "Incorrect max flow value.");
    309   check(!tol.different(2 * expected, min_cut_value),
     341  check(!tol.different(17 * expected, min_cut_value),
    310342        "Incorrect min cut value.");
    311343
    312344  max_flow.flowMap(flow);
     
    382414  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
    383415  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
    384416  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<double> > PType3;
     417
    385418  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >(test_lgf, 13);
    386419  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf, 13);
    387420  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf, 13);
    388421
     422  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >(test_lgf_float, 0.3);
     423  checkMaxFlowAlg<PType3, PreflowStartFunctions<PType3> >(test_lgf_float, 0.3);
     424
    389425  checkInitPreflow();
    390426
    391427  // Check EdmondsKarp
    392428  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
    393429  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
    394430  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<double> > EKType3;
     431
    395432  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >(test_lgf, 13);
    396433  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf, 13);
    397434  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf, 13);
    398435
     436  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >(test_lgf_float, 0.3);
     437  checkMaxFlowAlg<EKType3, GeneralStartFunctions<EKType3> >(test_lgf_float, 0.3);
     438
    399439  return 0;
    400440}