COIN-OR::LEMON - Graph Library

Ticket #177: 177-patches-87df475c2753--2ecc1e07d4ff.patch

File 177-patches-87df475c2753--2ecc1e07d4ff.patch, 37.6 KB (added by Peter Kovacs, 7 years ago)
  • lemon/edmonds_karp.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1362071873 -3600
    # Node ID 87df475c275311687b9a1dccb0c6fb993d81cd2f
    # Parent  be2b4a8d4548920c639259882b72429302c514ab
    Improve and fix API doc of EdmondsKarp according to Preflow (#177)
    
    diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
    a b  
    4545    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
    4646    typedef CAP CapacityMap;
    4747
    48     /// \brief The type of the length of the arcs.
     48    /// \brief The type of the flow values.
    4949    typedef typename CapacityMap::Value Value;
    5050
    51     /// \brief The map type that stores the flow values.
     51    /// \brief The type of the map that stores the flow values.
    5252    ///
    53     /// The map type that stores the flow values.
     53    /// The type of the map that stores the flow values.
    5454    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
     55#ifdef DOXYGEN
     56    typedef GR::ArcMap<Value> FlowMap;
     57#else
    5558    typedef typename Digraph::template ArcMap<Value> FlowMap;
     59#endif
    5660
    5761    /// \brief Instantiates a FlowMap.
    5862    ///
    5963    /// This function instantiates a \ref FlowMap.
    60     /// \param digraph The digraph, to which we would like to define the flow map.
     64    /// \param digraph The digraph for which we would like to define
     65    /// the flow map.
    6166    static FlowMap* createFlowMap(const Digraph& digraph) {
    6267      return new FlowMap(digraph);
    6368    }
     
    7479  /// \brief Edmonds-Karp algorithms class.
    7580  ///
    7681  /// This class provides an implementation of the \e Edmonds-Karp \e
    77   /// algorithm producing a flow of maximum value in directed
    78   /// digraphs. The Edmonds-Karp algorithm is slower than the Preflow
    79   /// algorithm but it has an advantage of the step-by-step execution
     82  /// algorithm producing a \ref max_flow "flow of maximum value" in a
     83  /// digraph \ref clrs01algorithms, \ref amo93networkflows,
     84  /// \ref edmondskarp72theoretical.
     85  /// The Edmonds-Karp algorithm is slower than the Preflow
     86  /// algorithm, but it has an advantage of the step-by-step execution
    8087  /// control with feasible flow solutions. The \e source node, the \e
    8188  /// target node, the \e capacity of the arcs and the \e starting \e
    8289  /// flow value of the arcs should be passed to the algorithm
    8390  /// through the constructor.
    8491  ///
    8592  /// The time complexity of the algorithm is \f$ O(nm^2) \f$ in
    86   /// worst case.  Always try the preflow algorithm instead of this if
     93  /// worst case. Always try the Preflow algorithm instead of this if
    8794  /// you just want to compute the optimal flow.
    8895  ///
    89   /// \param GR The digraph type the algorithm runs on.
    90   /// \param CAP The capacity map type.
    91   /// \param TR Traits class to set various data types used by
    92   /// the algorithm.  The default traits class is \ref
    93   /// EdmondsKarpDefaultTraits.  See \ref EdmondsKarpDefaultTraits for the
    94   /// documentation of a Edmonds-Karp traits class.
     96  /// \tparam GR The type of the digraph the algorithm runs on.
     97  /// \tparam CAP The type of the capacity map. The default map
     98  /// type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
     99  /// \tparam TR The traits class that defines various types used by the
     100  /// algorithm. By default, it is \ref EdmondsKarpDefaultTraits
     101  /// "EdmondsKarpDefaultTraits<GR, CAP>".
     102  /// In most cases, this parameter should not be set directly,
     103  /// consider to use the named template parameters instead.
    95104
    96105#ifdef DOXYGEN
    97106  template <typename GR, typename CAP, typename TR>
     
    103112  class EdmondsKarp {
    104113  public:
    105114
     115    /// The \ref EdmondsKarpDefaultTraits "traits class" of the algorithm.
    106116    typedef TR Traits;
     117    /// The type of the digraph the algorithm runs on.
    107118    typedef typename Traits::Digraph Digraph;
     119    /// The type of the capacity map.
    108120    typedef typename Traits::CapacityMap CapacityMap;
     121    /// The type of the flow values.
    109122    typedef typename Traits::Value Value;
    110123
     124    /// The type of the flow map.
    111125    typedef typename Traits::FlowMap FlowMap;
     126    /// The type of the tolerance.
    112127    typedef typename Traits::Tolerance Tolerance;
    113128
    114129  private:
     
    160175    struct DefFlowMapTraits : public Traits {
    161176      typedef T FlowMap;
    162177      static FlowMap *createFlowMap(const Digraph&) {
    163         LEMON_ASSERT(false,"Uninitialized parameter.");
     178        LEMON_ASSERT(false, "FlowMap is not initialized");
    164179        return 0;
    165180      }
    166181    };
     
    173188    template <typename T>
    174189    struct DefFlowMap
    175190      : public EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > {
    176       typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > 
     191      typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> >
    177192      Create;
    178193    };
    179194
    180 
    181195    /// @}
    182196
    183197  protected:
     
    198212      : _graph(digraph), _capacity(&capacity), _source(source), _target(target),
    199213        _flow(0), _local_flow(false), _pred(0), _tolerance(), _flow_value()
    200214    {
    201       LEMON_ASSERT(_source != _target,"Flow source and target are the same nodes.");
     215      LEMON_ASSERT(_source != _target,
     216                   "Flow source and target are the same nodes.");
    202217    }
    203218
    204219    /// \brief Destructor.
     
    211226    /// \brief Sets the capacity map.
    212227    ///
    213228    /// Sets the capacity map.
    214     /// \return \c (*this)
     229    /// \return <tt>(*this)</tt>
    215230    EdmondsKarp& capacityMap(const CapacityMap& map) {
    216231      _capacity = &map;
    217232      return *this;
     
    220235    /// \brief Sets the flow map.
    221236    ///
    222237    /// Sets the flow map.
    223     /// \return \c (*this)
     238    /// If you don't use this function before calling \ref run() or
     239    /// \ref init(), an instance will be allocated automatically.
     240    /// The destructor deallocates this automatically allocated map,
     241    /// of course.
     242    /// \return <tt>(*this)</tt>
    224243    EdmondsKarp& flowMap(FlowMap& map) {
    225244      if (_local_flow) {
    226245        delete _flow;
     
    230249      return *this;
    231250    }
    232251
    233     /// \brief Returns the flow map.
    234     ///
    235     /// \return The flow map.
    236     const FlowMap& flowMap() const {
    237       return *_flow;
    238     }
    239 
    240252    /// \brief Sets the source node.
    241253    ///
    242254    /// Sets the source node.
    243     /// \return \c (*this)
     255    /// \return <tt>(*this)</tt>
    244256    EdmondsKarp& source(const Node& node) {
    245257      _source = node;
    246258      return *this;
     
    249261    /// \brief Sets the target node.
    250262    ///
    251263    /// Sets the target node.
    252     /// \return \c (*this)
     264    /// \return <tt>(*this)</tt>
    253265    EdmondsKarp& target(const Node& node) {
    254266      _target = node;
    255267      return *this;
     
    258270    /// \brief Sets the tolerance used by algorithm.
    259271    ///
    260272    /// Sets the tolerance used by algorithm.
     273    /// \return <tt>(*this)</tt>
    261274    EdmondsKarp& tolerance(const Tolerance& tolerance) {
    262275      _tolerance = tolerance;
    263276      return *this;
    264277    }
    265278
    266     /// \brief Returns the tolerance used by algorithm.
     279    /// \brief Returns a const reference to the tolerance.
    267280    ///
    268     /// Returns the tolerance used by algorithm.
     281    /// Returns a const reference to the tolerance object used by
     282    /// the algorithm.
    269283    const Tolerance& tolerance() const {
    270284      return _tolerance;
    271285    }
    272286
    273287    /// \name Execution control
    274     /// The simplest way to execute the
    275     /// algorithm is to use the \c run() member functions.
    276     /// \n
    277     /// If you need more control on initial solution or
    278     /// execution then you have to call one \ref init() function and then
    279     /// the start() or multiple times the \c augment() member function. 
     288    /// The simplest way to execute the algorithm is to use \ref run().\n
     289    /// If you need better control on the initial solution or the execution,
     290    /// you have to call one of the \ref init() functions first, then
     291    /// \ref start() or multiple times the \ref augment() function.
    280292   
    281293    ///@{
    282294
    283     /// \brief Initializes the algorithm
    284     ///
    285     /// Sets the flow to empty flow.
     295    /// \brief Initializes the algorithm.
     296    ///
     297    /// Initializes the internal data structures and sets the initial
     298    /// flow to zero on each arc.
    286299    void init() {
    287300      createStructures();
    288301      for (ArcIt it(_graph); it != INVALID; ++it) {
     
    291304      _flow_value = 0;
    292305    }
    293306   
    294     /// \brief Initializes the algorithm
    295     ///
    296     /// Initializes the flow to the \c flowMap. The \c flowMap should
    297     /// contain a feasible flow, ie. in each node excluding the source
    298     /// and the target the incoming flow should be equal to the
     307    /// \brief Initializes the algorithm using the given flow map.
     308    ///
     309    /// Initializes the internal data structures and sets the initial
     310    /// flow to the given \c flowMap. The \c flowMap should
     311    /// contain a feasible flow, i.e. at each node excluding the source
     312    /// and the target, the incoming flow should be equal to the
    299313    /// outgoing flow.
    300314    template <typename FlowMap>
    301315    void flowInit(const FlowMap& flowMap) {
     
    312326      }
    313327    }
    314328
    315     /// \brief Initializes the algorithm
    316     ///
    317     /// Initializes the flow to the \c flowMap. The \c flowMap should
    318     /// contain a feasible flow, ie. in each node excluding the source
    319     /// and the target the incoming flow should be equal to the
    320     /// outgoing flow. 
    321     /// \return %False when the given flowMap does not contain
     329    /// \brief Initializes the algorithm using the given flow map.
     330    ///
     331    /// Initializes the internal data structures and sets the initial
     332    /// flow to the given \c flowMap. The \c flowMap should
     333    /// contain a feasible flow, i.e. at each node excluding the source
     334    /// and the target, the incoming flow should be equal to the
     335    /// outgoing flow.
     336    /// \return \c false when the given \c flowMap does not contain a
    322337    /// feasible flow.
    323338    template <typename FlowMap>
    324339    bool checkedFlowInit(const FlowMap& flowMap) {
     
    354369      return true;
    355370    }
    356371
    357     /// \brief Augment the solution on an arc shortest path.
     372    /// \brief Augments the solution along a shortest path.
    358373    ///
    359     /// Augment the solution on an arc shortest path. It searches an
    360     /// arc shortest path between the source and the target
    361     /// in the residual digraph by the bfs algoritm.
     374    /// Augments the solution along a shortest path. This function searches a
     375    /// shortest path between the source and the target
     376    /// in the residual digraph by the Bfs algoritm.
    362377    /// Then it increases the flow on this path with the minimal residual
    363     /// capacity on the path. If there is no such path it gives back
     378    /// capacity on the path. If there is no such path, it gives back
    364379    /// false.
    365     /// \return %False when the augmenting didn't success so the
     380    /// \return \c false when the augmenting did not success, i.e. the
    366381    /// current flow is a feasible and optimal solution.
    367382    bool augment() {
    368383      for (NodeIt n(_graph); n != INVALID; ++n) {
     
    439454
    440455    /// \brief Executes the algorithm
    441456    ///
    442     /// It runs augmenting phases until the optimal solution is reached.
     457    /// Executes the algorithm by performing augmenting phases until the
     458    /// optimal solution is reached.
     459    /// \pre One of the \ref init() functions must be called before
     460    /// using this function.
    443461    void start() {
    444462      while (augment()) {}
    445463    }
    446464
    447465    /// \brief Runs the algorithm.
    448466    ///
    449     /// It is just a shorthand for:
    450     ///
     467    /// Runs the Edmonds-Karp algorithm.
     468    /// \note ek.run() is just a shortcut of the following code.
    451469    ///\code
    452470    /// ek.init();
    453471    /// ek.start();
     
    462480    /// \name Query Functions
    463481    /// The result of the Edmonds-Karp algorithm can be obtained using these
    464482    /// functions.\n
    465     /// Before the use of these functions,
    466     /// either run() or start() must be called.
     483    /// Either \ref run() or \ref start() should be called before using them.
    467484   
    468485    ///@{
    469486
    470487    /// \brief Returns the value of the maximum flow.
    471488    ///
    472     /// Returns the value of the maximum flow by returning the excess
    473     /// of the target node \c t.
    474 
     489    /// Returns the value of the maximum flow found by the algorithm.
     490    ///
     491    /// \pre Either \ref run() or \ref init() must be called before
     492    /// using this function.
    475493    Value flowValue() const {
    476494      return _flow_value;
    477495    }
    478496
    479 
    480     /// \brief Returns the flow on the arc.
     497    /// \brief Returns the flow value on the given arc.
    481498    ///
    482     /// Sets the \c flowMap to the flow on the arcs.
     499    /// Returns the flow value on the given arc.
     500    ///
     501    /// \pre Either \ref run() or \ref init() must be called before
     502    /// using this function.
    483503    Value flow(const Arc& arc) const {
    484504      return (*_flow)[arc];
    485505    }
    486506
    487     /// \brief Returns true when the node is on the source side of minimum cut.
     507    /// \brief Returns a const reference to the flow map.
    488508    ///
     509    /// Returns a const reference to the arc map storing the found flow.
     510    ///
     511    /// \pre Either \ref run() or \ref init() must be called before
     512    /// using this function.
     513    const FlowMap& flowMap() const {
     514      return *_flow;
     515    }
    489516
    490     /// Returns true when the node is on the source side of minimum
    491     /// cut.
    492 
     517    /// \brief Returns \c true when the node is on the source side of the
     518    /// minimum cut.
     519    ///
     520    /// Returns true when the node is on the source side of the found
     521    /// minimum cut.
     522    ///
     523    /// \pre Either \ref run() or \ref init() must be called before
     524    /// using this function.
    493525    bool minCut(const Node& node) const {
    494526      return ((*_pred)[node] != INVALID) or node == _source;
    495527    }
    496528
    497     /// \brief Returns a minimum value cut.
     529    /// \brief Gives back a minimum value cut.
    498530    ///
    499     /// Sets \c cutMap to the characteristic vector of a minimum value cut.
    500 
     531    /// Sets \c cutMap to the characteristic vector of a minimum value
     532    /// cut. \c cutMap should be a \ref concepts::WriteMap "writable"
     533    /// node map with \c bool (or convertible) value type.
     534    ///
     535    /// \note This function calls \ref minCut() for each node, so it runs in
     536    /// O(n) time.
     537    ///
     538    /// \pre Either \ref run() or \ref init() must be called before
     539    /// using this function.
    501540    template <typename CutMap>
    502541    void minCutMap(CutMap& cutMap) const {
    503542      for (NodeIt n(_graph); n != INVALID; ++n) {
  • lemon/edmonds_karp.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1362071156 -3600
    # Node ID 0ad9454fd0b6f0307d01e0baf23ac9642983e6a1
    # Parent  87df475c275311687b9a1dccb0c6fb993d81cd2f
    Rename DefFlowMap named parameter to SetFlowMap (#177)
    in EdmondsKarp according to Preflow
    
    diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
    a b  
    172172    ///@{
    173173
    174174    template <typename T>
    175     struct DefFlowMapTraits : public Traits {
     175    struct SetFlowMapTraits : public Traits {
    176176      typedef T FlowMap;
    177177      static FlowMap *createFlowMap(const Digraph&) {
    178178        LEMON_ASSERT(false, "FlowMap is not initialized");
     
    186186    /// \ref named-templ-param "Named parameter" for setting FlowMap
    187187    /// type
    188188    template <typename T>
    189     struct DefFlowMap
    190       : public EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> > {
    191       typedef EdmondsKarp<Digraph, CapacityMap, DefFlowMapTraits<T> >
    192       Create;
     189    struct SetFlowMap
     190      : public EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > {
     191      typedef EdmondsKarp<Digraph, CapacityMap, SetFlowMapTraits<T> > Create;
    193192    };
    194193
    195194    /// @}
  • test/edmonds_karp_test.cc

    diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc
    a b  
    8383  bool b;
    8484
    8585  typedef EdmondsKarp<Digraph, CapMap>
    86               ::DefFlowMap<FlowMap>
     86              ::SetFlowMap<FlowMap>
    8787              ::Create EKType;
    8888  EKType ek_test(g, cap, n, n);
    8989  const EKType& const_ek_test = ek_test;
  • lemon/edmonds_karp.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1362071628 -3600
    # Node ID d1c4ed808574081acf145cb252f5ad5cca6ba772
    # Parent  0ad9454fd0b6f0307d01e0baf23ac9642983e6a1
    Rename flow init functions according to Preflow (#177)
    
    diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
    a b  
    311311    /// and the target, the incoming flow should be equal to the
    312312    /// outgoing flow.
    313313    template <typename FlowMap>
    314     void flowInit(const FlowMap& flowMap) {
     314    void init(const FlowMap& flowMap) {
    315315      createStructures();
    316316      for (ArcIt e(_graph); e != INVALID; ++e) {
    317317        _flow->set(e, flowMap[e]);
     
    335335    /// \return \c false when the given \c flowMap does not contain a
    336336    /// feasible flow.
    337337    template <typename FlowMap>
    338     bool checkedFlowInit(const FlowMap& flowMap) {
     338    bool checkedInit(const FlowMap& flowMap) {
    339339      createStructures();
    340340      for (ArcIt e(_graph); e != INVALID; ++e) {
    341341        _flow->set(e, flowMap[e]);
  • test/edmonds_karp_test.cc

    diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc
    a b  
    186186  int flow_value=ek_test.flowValue();
    187187
    188188  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
    189   ek_test.flowInit(flow);
     189  ek_test.init(flow);
    190190  ek_test.start();
    191191
    192192  CutMap min_cut1(g);
  • lemon/edmonds_karp.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1362091475 -3600
    # Node ID 67ffe67e28de610b4114d0669f538eed1d435f97
    # Parent  d1c4ed808574081acf145cb252f5ad5cca6ba772
    Merge test files of Preflow and EdmondsKarp (#177)
    
    diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
    a b  
    167167   
    168168  public:
    169169
     170    typedef EdmondsKarp Create;
     171
    170172    ///\name Named template parameters
    171173
    172174    ///@{
  • test/CMakeLists.txt

    diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
    a b  
    1919  dijkstra_test
    2020  dim_test
    2121  edge_set_test
    22   edmonds_karp_test
    2322  error_test
    2423  euler_test
    2524  fractional_matching_test
     
    3433  matching_test
    3534  max_cardinality_search_test
    3635  max_clique_test
     36  max_flow_test
    3737  min_cost_arborescence_test
    3838  min_cost_flow_test
    3939  min_mean_cycle_test
    4040  nagamochi_ibaraki_test
    4141  path_test
    4242  planarity_test
    43   preflow_test
    4443  radix_sort_test
    4544  random_test
    4645  suurballe_test
  • test/Makefile.am

    diff --git a/test/Makefile.am b/test/Makefile.am
    a b  
    2121        test/dijkstra_test \
    2222        test/dim_test \
    2323        test/edge_set_test \
    24         test/edmonds_karp_test \
    2524        test/error_test \
    2625        test/euler_test \
    2726        test/fractional_matching_test \
     
    3635        test/matching_test \
    3736        test/max_cardinality_search_test \
    3837        test/max_clique_test \
     38        test/max_flow_test \
    3939        test/min_cost_arborescence_test \
    4040        test/min_cost_flow_test \
    4141        test/min_mean_cycle_test \
    4242        test/nagamochi_ibaraki_test \
    4343        test/path_test \
    4444        test/planarity_test \
    45         test/preflow_test \
    4645        test/radix_sort_test \
    4746        test/random_test \
    4847        test/suurballe_test \
     
    7473test_dijkstra_test_SOURCES = test/dijkstra_test.cc
    7574test_dim_test_SOURCES = test/dim_test.cc
    7675test_edge_set_test_SOURCES = test/edge_set_test.cc
    77 test_edmonds_karp_test_SOURCES = test/edmonds_karp_test.cc
    7876test_error_test_SOURCES = test/error_test.cc
    7977test_euler_test_SOURCES = test/euler_test.cc
    8078test_fractional_matching_test_SOURCES = test/fractional_matching_test.cc
     
    9189test_matching_test_SOURCES = test/matching_test.cc
    9290test_max_cardinality_search_test_SOURCES = test/max_cardinality_search_test.cc
    9391test_max_clique_test_SOURCES = test/max_clique_test.cc
     92test_max_flow_test_SOURCES = test/max_flow_test.cc
    9493test_min_cost_arborescence_test_SOURCES = test/min_cost_arborescence_test.cc
    9594test_min_cost_flow_test_SOURCES = test/min_cost_flow_test.cc
    9695test_min_mean_cycle_test_SOURCES = test/min_mean_cycle_test.cc
    9796test_nagamochi_ibaraki_test_SOURCES = test/nagamochi_ibaraki_test.cc
    9897test_path_test_SOURCES = test/path_test.cc
    9998test_planarity_test_SOURCES = test/planarity_test.cc
    100 test_preflow_test_SOURCES = test/preflow_test.cc
    10199test_radix_sort_test_SOURCES = test/radix_sort_test.cc
    102100test_suurballe_test_SOURCES = test/suurballe_test.cc
    103101test_random_test_SOURCES = test/random_test.cc
  • deleted file test/edmonds_karp_test.cc

    diff --git a/test/edmonds_karp_test.cc b/test/edmonds_karp_test.cc
    deleted file mode 100644
    + -  
    1 /* -*- mode: C++; indent-tabs-mode: nil; -*-
    2  *
    3  * This file is a part of LEMON, a generic C++ optimization library.
    4  *
    5  * Copyright (C) 2003-2010
    6  * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    7  * (Egervary Research Group on Combinatorial Optimization, EGRES).
    8  *
    9  * Permission to use, modify and distribute this software is granted
    10  * provided that this copyright notice appears in all copies. For
    11  * precise terms see the accompanying LICENSE file.
    12  *
    13  * This software is provided "AS IS" with no warranty of any kind,
    14  * express or implied, and with no claim as to its suitability for any
    15  * purpose.
    16  *
    17  */
    18 
    19 #include<iostream>
    20 
    21 #include "test_tools.h"
    22 #include<lemon/smart_graph.h>
    23 #include<lemon/edmonds_karp.h>
    24 #include <lemon/concepts/digraph.h>
    25 #include <lemon/concepts/maps.h>
    26 #include <lemon/lgf_reader.h>
    27 
    28 using namespace lemon;
    29 
    30 char test_lgf[] =
    31   "@nodes\n"
    32   "label\n"
    33   "0\n"
    34   "1\n"
    35   "2\n"
    36   "3\n"
    37   "4\n"
    38   "5\n"
    39   "6\n"
    40   "7\n"
    41   "8\n"
    42   "9\n"
    43   "@arcs\n"
    44   "    label capacity\n"
    45   "0 1 0     20\n"
    46   "0 2 1     0\n"
    47   "1 1 2     3\n"
    48   "1 2 3     8\n"
    49   "1 3 4     8\n"
    50   "2 5 5     5\n"
    51   "3 2 6     5\n"
    52   "3 5 7     5\n"
    53   "3 6 8     5\n"
    54   "4 3 9     3\n"
    55   "5 7 10    3\n"
    56   "5 6 11    10\n"
    57   "5 8 12    10\n"
    58   "6 8 13    8\n"
    59   "8 9 14    20\n"
    60   "8 1 15    5\n"
    61   "9 5 16    5\n"
    62   "@attributes\n"
    63   "source 1\n"
    64   "target 8\n";
    65 
    66 void checkEdmondKarpCompile() {
    67   typedef int VType;
    68   typedef concepts::Digraph Digraph;
    69 
    70   typedef Digraph::Node Node;
    71   typedef Digraph::Arc Arc;
    72   typedef concepts::ReadMap<Arc,VType> CapMap;
    73   typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
    74   typedef concepts::WriteMap<Node,bool> CutMap;
    75 
    76   Digraph g;
    77   Node n;
    78   Arc e;
    79   CapMap cap;
    80   FlowMap flow;
    81   CutMap cut;
    82   VType v;
    83   bool b;
    84 
    85   typedef EdmondsKarp<Digraph, CapMap>
    86               ::SetFlowMap<FlowMap>
    87               ::Create EKType;
    88   EKType ek_test(g, cap, n, n);
    89   const EKType& const_ek_test = ek_test;
    90 
    91   EKType::Tolerance tol = const_ek_test.tolerance();
    92   ek_test.tolerance(tol);
    93 
    94   ek_test
    95     .capacityMap(cap)
    96     .flowMap(flow)
    97     .source(n)
    98     .target(n);
    99 
    100   ek_test.init();
    101   ek_test.start();
    102 
    103   v = const_ek_test.flowValue();
    104   v = const_ek_test.flow(e);
    105 
    106   const FlowMap& fm = const_ek_test.flowMap();
    107   b = const_ek_test.minCut(n);
    108   const_ek_test.minCutMap(cut);
    109 
    110   ignore_unused_variable_warning(fm);
    111 }
    112 
    113 int cutValue (const SmartDigraph& g,
    114               const SmartDigraph::NodeMap<bool>& cut,
    115               const SmartDigraph::ArcMap<int>& cap) {
    116 
    117   int c=0;
    118   for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
    119     if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
    120   }
    121   return c;
    122 }
    123 
    124 bool checkFlow(const SmartDigraph& g,
    125                const SmartDigraph::ArcMap<int>& flow,
    126                const SmartDigraph::ArcMap<int>& cap,
    127                SmartDigraph::Node s, SmartDigraph::Node t) {
    128 
    129   for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
    130     if (flow[e] < 0 || flow[e] > cap[e]) return false;
    131   }
    132 
    133   for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
    134     if (n == s || n == t) continue;
    135     int sum = 0;
    136     for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
    137       sum += flow[e];
    138     }
    139     for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
    140       sum -= flow[e];
    141     }
    142     if (sum != 0) return false;
    143   }
    144   return true;
    145 }
    146 
    147 int main() {
    148 
    149   typedef SmartDigraph Digraph;
    150 
    151   typedef Digraph::Node Node;
    152   typedef Digraph::NodeIt NodeIt;
    153   typedef Digraph::ArcIt ArcIt;
    154   typedef Digraph::ArcMap<int> CapMap;
    155   typedef Digraph::ArcMap<int> FlowMap;
    156   typedef Digraph::NodeMap<bool> CutMap;
    157 
    158   typedef EdmondsKarp<Digraph, CapMap> EKType;
    159 
    160   Digraph g;
    161   Node s, t;
    162   CapMap cap(g);
    163   std::istringstream input(test_lgf);
    164   DigraphReader<Digraph>(g,input).
    165     arcMap("capacity", cap).
    166     node("source",s).
    167     node("target",t).
    168     run();
    169 
    170   EKType ek_test(g, cap, s, t);
    171   ek_test.run();
    172 
    173   check(checkFlow(g, ek_test.flowMap(), cap, s, t),
    174         "The flow is not feasible.");
    175 
    176   CutMap min_cut(g);
    177   ek_test.minCutMap(min_cut);
    178   int min_cut_value=cutValue(g,min_cut,cap);
    179 
    180   check(ek_test.flowValue() == min_cut_value,
    181         "The max flow value is not equal to the three min cut values.");
    182 
    183   FlowMap flow(g);
    184   for(ArcIt e(g); e!=INVALID; ++e) flow[e] = ek_test.flowMap()[e];
    185 
    186   int flow_value=ek_test.flowValue();
    187 
    188   for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
    189   ek_test.init(flow);
    190   ek_test.start();
    191 
    192   CutMap min_cut1(g);
    193   ek_test.minCutMap(min_cut1);
    194   min_cut_value=cutValue(g,min_cut1,cap);
    195 
    196   check(ek_test.flowValue() == min_cut_value &&
    197         min_cut_value == 2*flow_value,
    198         "The max flow value or the min cut value is wrong.");
    199 
    200   check(checkFlow(g, ek_test.flowMap(), cap, s, t),
    201         "The flow is not feasible.");
    202 
    203   CutMap min_cut2(g);
    204   ek_test.minCutMap(min_cut2);
    205   min_cut_value=cutValue(g,min_cut2,cap);
    206 
    207   check(ek_test.flowValue() == min_cut_value &&
    208         min_cut_value == 2*flow_value,
    209         "The max flow value or the three min cut values were not doubled.");
    210 
    211 
    212   ek_test.flowMap(flow);
    213 
    214   NodeIt tmp1(g,s);
    215   ++tmp1;
    216   if ( tmp1 != INVALID ) s=tmp1;
    217 
    218   NodeIt tmp2(g,t);
    219   ++tmp2;
    220   if ( tmp2 != INVALID ) t=tmp2;
    221 
    222   ek_test.source(s);
    223   ek_test.target(t);
    224 
    225   ek_test.run();
    226 
    227   CutMap min_cut3(g);
    228   ek_test.minCutMap(min_cut3);
    229   min_cut_value=cutValue(g,min_cut3,cap);
    230 
    231 
    232   check(ek_test.flowValue() == min_cut_value,
    233         "The max flow value or the three min cut values are incorrect.");
    234 
    235   return 0;
    236 }
  • .cc

    diff --git a/test/preflow_test.cc b/test/max_flow_test.cc
    rename from test/preflow_test.cc
    rename to test/max_flow_test.cc
    old new  
    2121#include "test_tools.h"
    2222#include <lemon/smart_graph.h>
    2323#include <lemon/preflow.h>
     24#include <lemon/edmonds_karp.h>
    2425#include <lemon/concepts/digraph.h>
    2526#include <lemon/concepts/maps.h>
    2627#include <lemon/lgf_reader.h>
     
    6465  "source 1\n"
    6566  "target 8\n";
    6667
     68
     69// Checks the general interface of a max flow algorithm
     70template <typename GR, typename CAP>
     71struct MaxFlowClassConcept
     72{
     73
     74  template <typename MF>
     75  struct Constraints {
     76
     77    typedef typename GR::Node Node;
     78    typedef typename GR::Arc Arc;
     79    typedef typename CAP::Value Value;
     80    typedef concepts::ReadWriteMap<Arc, Value> FlowMap;
     81    typedef concepts::WriteMap<Node, bool> CutMap;
     82
     83    GR g;
     84    Node n;
     85    Arc e;
     86    CAP cap;
     87    FlowMap flow;
     88    CutMap cut;
     89    Value v;
     90    bool b;
     91
     92    void constraints() {
     93      checkConcept<concepts::Digraph, GR>();
     94
     95      const Constraints& me = *this;
     96
     97      typedef typename MF
     98          ::template SetFlowMap<FlowMap>
     99          ::Create MaxFlowType;
     100      typedef typename MF::Create MaxFlowType2;
     101      MaxFlowType max_flow(me.g, me.cap, me.n, me.n);
     102      const MaxFlowType& const_max_flow = max_flow;
     103
     104      max_flow
     105          .capacityMap(cap)
     106          .flowMap(flow)
     107          .source(n)
     108          .target(n);
     109
     110      typename MaxFlowType::Tolerance tol = const_max_flow.tolerance();
     111      max_flow.tolerance(tol);
     112
     113      max_flow.init();
     114      max_flow.init(cap);
     115      max_flow.run();
     116
     117      v = const_max_flow.flowValue();
     118      v = const_max_flow.flow(e);
     119      const FlowMap& fm = const_max_flow.flowMap();
     120
     121      b = const_max_flow.minCut(n);
     122      const_max_flow.minCutMap(cut);
     123
     124      ignore_unused_variable_warning(fm);
     125    }
     126
     127  };
     128
     129};
     130
     131// Checks the specific parts of Preflow's interface
    67132void checkPreflowCompile()
    68133{
    69   typedef int VType;
     134  typedef int Value;
    70135  typedef concepts::Digraph Digraph;
    71 
    72   typedef Digraph::Node Node;
    73   typedef Digraph::Arc Arc;
    74   typedef concepts::ReadMap<Arc,VType> CapMap;
    75   typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
    76   typedef concepts::WriteMap<Node,bool> CutMap;
    77 
     136  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
    78137  typedef Elevator<Digraph, Digraph::Node> Elev;
    79138  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
    80139
    81140  Digraph g;
    82   Node n;
    83   Arc e;
     141  Digraph::Node n;
    84142  CapMap cap;
    85   FlowMap flow;
    86   CutMap cut;
    87   VType v;
    88   bool b;
    89143
    90144  typedef Preflow<Digraph, CapMap>
    91             ::SetFlowMap<FlowMap>
    92             ::SetElevator<Elev>
    93             ::SetStandardElevator<LinkedElev>
    94             ::Create PreflowType;
     145      ::SetElevator<Elev>
     146      ::SetStandardElevator<LinkedElev>
     147      ::Create PreflowType;
    95148  PreflowType preflow_test(g, cap, n, n);
    96149  const PreflowType& const_preflow_test = preflow_test;
    97150
    98151  const PreflowType::Elevator& elev = const_preflow_test.elevator();
    99152  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
    100   PreflowType::Tolerance tol = const_preflow_test.tolerance();
    101   preflow_test.tolerance(tol);
    102153
    103   preflow_test
    104     .capacityMap(cap)
    105     .flowMap(flow)
    106     .source(n)
    107     .target(n);
    108 
    109   preflow_test.init();
    110   preflow_test.init(cap);
     154  bool b = preflow_test.init(cap);
    111155  preflow_test.startFirstPhase();
    112156  preflow_test.startSecondPhase();
    113   preflow_test.run();
    114157  preflow_test.runMinCut();
    115158
    116   v = const_preflow_test.flowValue();
    117   v = const_preflow_test.flow(e);
    118   const FlowMap& fm = const_preflow_test.flowMap();
    119   b = const_preflow_test.minCut(n);
    120   const_preflow_test.minCutMap(cut);
    121 
    122   ignore_unused_variable_warning(fm);
     159  ignore_unused_variable_warning(b);
    123160}
    124161
    125 int cutValue (const SmartDigraph& g,
     162// Checks the specific parts of EdmondsKarp's interface
     163void checkEdmondsKarpCompile()
     164{
     165  typedef int Value;
     166  typedef concepts::Digraph Digraph;
     167  typedef concepts::ReadMap<Digraph::Arc, Value> CapMap;
     168  typedef Elevator<Digraph, Digraph::Node> Elev;
     169  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
     170
     171  Digraph g;
     172  Digraph::Node n;
     173  CapMap cap;
     174
     175  EdmondsKarp<Digraph, CapMap> ek_test(g, cap, n, n);
     176
     177  ek_test.init(cap);
     178  bool b = ek_test.checkedInit(cap);
     179  b = ek_test.augment();
     180  ek_test.start();
     181
     182  ignore_unused_variable_warning(b);
     183}
     184
     185
     186template <typename T>
     187T cutValue (const SmartDigraph& g,
    126188              const SmartDigraph::NodeMap<bool>& cut,
    127               const SmartDigraph::ArcMap<int>& cap) {
     189              const SmartDigraph::ArcMap<T>& cap) {
    128190
    129   int c=0;
     191  T c=0;
    130192  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
    131193    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
    132194  }
    133195  return c;
    134196}
    135197
     198template <typename T>
    136199bool checkFlow(const SmartDigraph& g,
    137                const SmartDigraph::ArcMap<int>& flow,
    138                const SmartDigraph::ArcMap<int>& cap,
     200               const SmartDigraph::ArcMap<T>& flow,
     201               const SmartDigraph::ArcMap<T>& cap,
    139202               SmartDigraph::Node s, SmartDigraph::Node t) {
    140203
    141204  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
     
    144207
    145208  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
    146209    if (n == s || n == t) continue;
    147     int sum = 0;
     210    T sum = 0;
    148211    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
    149212      sum += flow[e];
    150213    }
     
    156219  return true;
    157220}
    158221
    159 int main() {
     222template <typename MF, typename SF>
     223void checkMaxFlowAlg() {
     224  typedef SmartDigraph Digraph;
     225  DIGRAPH_TYPEDEFS(Digraph);
    160226
    161   typedef SmartDigraph Digraph;
    162 
    163   typedef Digraph::Node Node;
    164   typedef Digraph::NodeIt NodeIt;
    165   typedef Digraph::ArcIt ArcIt;
    166   typedef Digraph::ArcMap<int> CapMap;
    167   typedef Digraph::ArcMap<int> FlowMap;
    168   typedef Digraph::NodeMap<bool> CutMap;
    169 
    170   typedef Preflow<Digraph, CapMap> PType;
     227  typedef typename MF::Value Value;
     228  typedef Digraph::ArcMap<Value> CapMap;
     229  typedef CapMap FlowMap;
     230  typedef BoolNodeMap CutMap;
    171231
    172232  Digraph g;
    173233  Node s, t;
    174234  CapMap cap(g);
    175235  std::istringstream input(test_lgf);
    176   DigraphReader<Digraph>(g,input).
    177     arcMap("capacity", cap).
    178     node("source",s).
    179     node("target",t).
    180     run();
     236  DigraphReader<Digraph>(g,input)
     237      .arcMap("capacity", cap)
     238      .node("source",s)
     239      .node("target",t)
     240      .run();
    181241
    182   PType preflow_test(g, cap, s, t);
    183   preflow_test.run();
     242  MF max_flow(g, cap, s, t);
     243  max_flow.run();
    184244
    185   check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
     245  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
    186246        "The flow is not feasible.");
    187247
    188248  CutMap min_cut(g);
    189   preflow_test.minCutMap(min_cut);
    190   int min_cut_value=cutValue(g,min_cut,cap);
     249  max_flow.minCutMap(min_cut);
     250  Value min_cut_value = cutValue(g, min_cut, cap);
    191251
    192   check(preflow_test.flowValue() == min_cut_value,
    193         "The max flow value is not equal to the three min cut values.");
     252  check(max_flow.flowValue() == min_cut_value,
     253        "The max flow value is not equal to the min cut value.");
    194254
    195255  FlowMap flow(g);
    196   for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
     256  for (ArcIt e(g); e != INVALID; ++e) flow[e] = max_flow.flowMap()[e];
    197257
    198   int flow_value=preflow_test.flowValue();
     258  Value flow_value = max_flow.flowValue();
    199259
    200   for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
    201   preflow_test.init(flow);
    202   preflow_test.startFirstPhase();
     260  for (ArcIt e(g); e != INVALID; ++e) cap[e] = 2 * cap[e];
     261  max_flow.init(flow);
     262
     263  SF::startFirstPhase(max_flow);       // start first phase of the algorithm
    203264
    204265  CutMap min_cut1(g);
    205   preflow_test.minCutMap(min_cut1);
    206   min_cut_value=cutValue(g,min_cut1,cap);
     266  max_flow.minCutMap(min_cut1);
     267  min_cut_value = cutValue(g, min_cut1, cap);
    207268
    208   check(preflow_test.flowValue() == min_cut_value &&
    209         min_cut_value == 2*flow_value,
     269  check(max_flow.flowValue() == min_cut_value &&
     270        min_cut_value == 2 * flow_value,
    210271        "The max flow value or the min cut value is wrong.");
    211272
    212   preflow_test.startSecondPhase();
     273  SF::startSecondPhase(max_flow);       // start second phase of the algorithm
    213274
    214   check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
     275  check(checkFlow(g, max_flow.flowMap(), cap, s, t),
    215276        "The flow is not feasible.");
    216277
    217278  CutMap min_cut2(g);
    218   preflow_test.minCutMap(min_cut2);
    219   min_cut_value=cutValue(g,min_cut2,cap);
     279  max_flow.minCutMap(min_cut2);
     280  min_cut_value = cutValue(g, min_cut2, cap);
    220281
    221   check(preflow_test.flowValue() == min_cut_value &&
    222         min_cut_value == 2*flow_value,
    223         "The max flow value or the three min cut values were not doubled");
     282  check(max_flow.flowValue() == min_cut_value &&
     283        min_cut_value == 2 * flow_value,
     284        "The max flow value or the min cut value was not doubled");
    224285
    225286
    226   preflow_test.flowMap(flow);
     287  max_flow.flowMap(flow);
    227288
    228   NodeIt tmp1(g,s);
     289  NodeIt tmp1(g, s);
    229290  ++tmp1;
    230   if ( tmp1 != INVALID ) s=tmp1;
     291  if (tmp1 != INVALID) s = tmp1;
    231292
    232   NodeIt tmp2(g,t);
     293  NodeIt tmp2(g, t);
    233294  ++tmp2;
    234   if ( tmp2 != INVALID ) t=tmp2;
     295  if (tmp2 != INVALID) t = tmp2;
    235296
    236   preflow_test.source(s);
    237   preflow_test.target(t);
     297  max_flow.source(s);
     298  max_flow.target(t);
    238299
    239   preflow_test.run();
     300  max_flow.run();
    240301
    241302  CutMap min_cut3(g);
    242   preflow_test.minCutMap(min_cut3);
    243   min_cut_value=cutValue(g,min_cut3,cap);
     303  max_flow.minCutMap(min_cut3);
     304  min_cut_value=cutValue(g, min_cut3, cap);
    244305
     306  check(max_flow.flowValue() == min_cut_value,
     307        "The max flow value or the min cut value is wrong.");
     308}
    245309
    246   check(preflow_test.flowValue() == min_cut_value,
    247         "The max flow value or the three min cut values are incorrect.");
     310// Struct for calling start functions of a general max flow algorithm
     311template <typename MF>
     312struct GeneralStartFunctions {
     313
     314  static void startFirstPhase(MF& mf) {
     315    mf.start();
     316  }
     317
     318  static void startSecondPhase(MF& mf) {
     319    ignore_unused_variable_warning(mf);
     320  }
     321
     322};
     323
     324// Struct for calling start functions of Preflow
     325template <typename MF>
     326struct PreflowStartFunctions {
     327
     328  static void startFirstPhase(MF& mf) {
     329    mf.startFirstPhase();
     330  }
     331
     332  static void startSecondPhase(MF& mf) {
     333    mf.startSecondPhase();
     334  }
     335
     336};
     337
     338int main() {
     339
     340  typedef concepts::Digraph GR;
     341  typedef concepts::ReadMap<GR::Arc, int> CM1;
     342  typedef concepts::ReadMap<GR::Arc, double> CM2;
     343
     344  // Check the interface of Preflow
     345  checkConcept< MaxFlowClassConcept<GR, CM1>,
     346                Preflow<GR, CM1> >();
     347  checkConcept< MaxFlowClassConcept<GR, CM2>,
     348                Preflow<GR, CM2> >();
     349
     350  // Check the interface of EdmondsKarp
     351  checkConcept< MaxFlowClassConcept<GR, CM1>,
     352                EdmondsKarp<GR, CM1> >();
     353  checkConcept< MaxFlowClassConcept<GR, CM2>,
     354                EdmondsKarp<GR, CM2> >();
     355
     356  // Check Preflow
     357  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<int> > PType1;
     358  typedef Preflow<SmartDigraph, SmartDigraph::ArcMap<float> > PType2;
     359  checkMaxFlowAlg<PType1, PreflowStartFunctions<PType1> >();
     360  checkMaxFlowAlg<PType2, PreflowStartFunctions<PType2> >();
     361
     362  // Check EdmondsKarp
     363  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<int> > EKType1;
     364  typedef EdmondsKarp<SmartDigraph, SmartDigraph::ArcMap<float> > EKType2;
     365  checkMaxFlowAlg<EKType1, GeneralStartFunctions<EKType1> >();
     366  checkMaxFlowAlg<EKType2, GeneralStartFunctions<EKType2> >();
    248367
    249368  return 0;
    250369}
  • lemon/edmonds_karp.h

    # HG changeset patch
    # User Peter Kovacs <kpeter@inf.elte.hu>
    # Date 1362091539 -3600
    # Node ID 2ecc1e07d4ff28b7e344dc04cd4595b9c8558afb
    # Parent  67ffe67e28de610b4114d0669f538eed1d435f97
    Avoid usage of alternative operator (#177)
    
    diff --git a/lemon/edmonds_karp.h b/lemon/edmonds_karp.h
    a b  
    524524    /// \pre Either \ref run() or \ref init() must be called before
    525525    /// using this function.
    526526    bool minCut(const Node& node) const {
    527       return ((*_pred)[node] != INVALID) or node == _source;
     527      return ((*_pred)[node] != INVALID) || node == _source;
    528528    }
    529529
    530530    /// \brief Gives back a minimum value cut.