↑ Collapse diff ↑
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
namespace lemon {
20 20
/*!
21 21

	
22 22

	
23 23

	
24 24
\page lgf-format LEMON Graph Format (LGF)
25 25

	
26 26
The \e LGF is a <em>column oriented</em>
27 27
file format for storing graphs and associated data like
28 28
node and edge maps.
29 29

	
30 30
Each line with \c '#' first non-whitespace
31 31
character is considered as a comment line.
32 32

	
33 33
Otherwise the file consists of sections starting with
34 34
a header line. The header lines starts with an \c '@' character followed by the
35 35
type of section. The standard section types are \c \@nodes, \c
36 36
\@arcs and \c \@edges
37 37
and \@attributes. Each header line may also have an optional
38 38
\e name, which can be use to distinguish the sections of the same
39 39
type.
40 40

	
41 41
The standard sections are column oriented, each line consists of
42 42
<em>token</em>s separated by whitespaces. A token can be \e plain or
43 43
\e quoted. A plain token is just a sequence of non-whitespace characters,
44 44
while a quoted token is a
45 45
character sequence surrounded by double quotes, and it can also
46 46
contain whitespaces and escape sequences.
47 47

	
48 48
The \c \@nodes section describes a set of nodes and associated
49 49
maps. The first is a header line, its columns are the names of the
50 50
maps appearing in the following lines.
51 51
One of the maps must be called \c
52 52
"label", which plays special role in the file.
53 53
The following
54 54
non-empty lines until the next section describes nodes of the
55 55
graph. Each line contains the values of the node maps
56 56
associated to the current node.
57 57

	
58 58
\code
59 59
 @nodes
60 60
 label  coordinates  size    title
61 61
 1      (10,20)      10      "First node"
62 62
 2      (80,80)      8       "Second node"
63 63
 3      (40,10)      10      "Third node"
64 64
\endcode
65 65

	
66 66
The \c \@arcs section is very similar to the \c \@nodes section, it
67 67
again starts with a header line describing the names of the maps, but
68 68
the \c "label" map is not obligatory here. The following lines
69 69
describe the arcs. The first two tokens of each line are the source
70 70
and the target node of the arc, respectively, then come the map
71 71
values. The source and target tokens must be node labels.
72 72

	
73 73
\code
74 74
 @arcs
75 75
         capacity
76 76
 1   2   16
77 77
 1   3   12
78 78
 2   3   18
79 79
\endcode
80 80

	
81 81
If there is no map in the \c \@arcs section at all, then it must be
82 82
indicated by a sole '-' sign in the first line.
83 83

	
84 84
\code
85 85
 @arcs
86 86
         -
87 87
 1   2
88 88
 1   3
89 89
 2   3
90 90
\endcode
91 91

	
92 92
The \c \@edges is just a synonym of \c \@arcs. The \@arcs section can
93 93
also store the edge set of an undirected graph. In such case there is
94 94
a conventional method for store arc maps in the file, if two columns
95 95
have the same caption with \c '+' and \c '-' prefix, then these columns
96 96
can be regarded as the values of an arc map.
97 97

	
98 98
The \c \@attributes section contains key-value pairs, each line
99 99
consists of two tokens, an attribute name, and then an attribute
100 100
value. The value of the attribute could be also a label value of a
101 101
node or an edge, or even an edge label prefixed with \c '+' or \c '-',
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
20 20
#define LEMON_BITS_GRAPH_ADAPTOR_EXTENDER_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/error.h>
24 24

	
25 25
namespace lemon {
26 26

	
27 27
  template <typename _Digraph>
28 28
  class DigraphAdaptorExtender : public _Digraph {
29 29
    typedef _Digraph Parent;
30 30

	
31 31
  public:
32 32

	
33 33
    typedef _Digraph Digraph;
34 34
    typedef DigraphAdaptorExtender Adaptor;
35 35

	
36 36
    // Base extensions
37 37

	
38 38
    typedef typename Parent::Node Node;
39 39
    typedef typename Parent::Arc Arc;
40 40

	
41 41
    int maxId(Node) const {
42 42
      return Parent::maxNodeId();
43 43
    }
44 44

	
45 45
    int maxId(Arc) const {
46 46
      return Parent::maxArcId();
47 47
    }
48 48

	
49 49
    Node fromId(int id, Node) const {
50 50
      return Parent::nodeFromId(id);
51 51
    }
52 52

	
53 53
    Arc fromId(int id, Arc) const {
54 54
      return Parent::arcFromId(id);
55 55
    }
56 56

	
57 57
    Node oppositeNode(const Node &n, const Arc &e) const {
58 58
      if (n == Parent::source(e))
59 59
        return Parent::target(e);
60 60
      else if(n==Parent::target(e))
61 61
        return Parent::source(e);
62 62
      else
63 63
        return INVALID;
64 64
    }
65 65

	
66 66
    class NodeIt : public Node {
67 67
      const Adaptor* _adaptor;
68 68
    public:
69 69

	
70 70
      NodeIt() {}
71 71

	
72 72
      NodeIt(Invalid i) : Node(i) { }
73 73

	
74 74
      explicit NodeIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
75 75
        _adaptor->first(static_cast<Node&>(*this));
76 76
      }
77 77

	
78 78
      NodeIt(const Adaptor& adaptor, const Node& node)
79 79
        : Node(node), _adaptor(&adaptor) {}
80 80

	
81 81
      NodeIt& operator++() {
82 82
        _adaptor->next(*this);
83 83
        return *this;
84 84
      }
85 85

	
86 86
    };
87 87

	
88 88

	
89 89
    class ArcIt : public Arc {
90 90
      const Adaptor* _adaptor;
91 91
    public:
92 92

	
93 93
      ArcIt() { }
94 94

	
95 95
      ArcIt(Invalid i) : Arc(i) { }
96 96

	
97 97
      explicit ArcIt(const Adaptor& adaptor) : _adaptor(&adaptor) {
98 98
        _adaptor->first(static_cast<Arc&>(*this));
99 99
      }
100 100

	
101 101
      ArcIt(const Adaptor& adaptor, const Arc& e) :
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_BITS_PATH_DUMP_H
20 20
#define LEMON_BITS_PATH_DUMP_H
21 21

	
22 22
#include <lemon/core.h>
23 23
#include <lemon/concept_check.h>
24 24

	
25 25
namespace lemon {
26 26

	
27 27
  template <typename _Digraph, typename _PredMap>
28 28
  class PredMapPath {
29 29
  public:
30 30
    typedef True RevPathTag;
31 31

	
32 32
    typedef _Digraph Digraph;
33 33
    typedef typename Digraph::Arc Arc;
34 34
    typedef _PredMap PredMap;
35 35

	
36 36
    PredMapPath(const Digraph& _digraph, const PredMap& _predMap,
37 37
                typename Digraph::Node _target)
38 38
      : digraph(_digraph), predMap(_predMap), target(_target) {}
39 39

	
40 40
    int length() const {
41 41
      int len = 0;
42 42
      typename Digraph::Node node = target;
43 43
      typename Digraph::Arc arc;
44 44
      while ((arc = predMap[node]) != INVALID) {
45 45
        node = digraph.source(arc);
46 46
        ++len;
47 47
      }
48 48
      return len;
49 49
    }
50 50

	
51 51
    bool empty() const {
52 52
      return predMap[target] == INVALID;
53 53
    }
54 54

	
55 55
    class RevArcIt {
56 56
    public:
57 57
      RevArcIt() {}
58 58
      RevArcIt(Invalid) : path(0), current(INVALID) {}
59 59
      RevArcIt(const PredMapPath& _path)
60 60
        : path(&_path), current(_path.target) {
61 61
        if (path->predMap[current] == INVALID) current = INVALID;
62 62
      }
63 63

	
64 64
      operator const typename Digraph::Arc() const {
65 65
        return path->predMap[current];
66 66
      }
67 67

	
68 68
      RevArcIt& operator++() {
69 69
        current = path->digraph.source(path->predMap[current]);
70 70
        if (path->predMap[current] == INVALID) current = INVALID;
71 71
        return *this;
72 72
      }
73 73

	
74 74
      bool operator==(const RevArcIt& e) const {
75 75
        return current == e.current;
76 76
      }
77 77

	
78 78
      bool operator!=(const RevArcIt& e) const {
79 79
        return current != e.current;
80 80
      }
81 81

	
82 82
      bool operator<(const RevArcIt& e) const {
83 83
        return current < e.current;
84 84
      }
85 85

	
86 86
    private:
87 87
      const PredMapPath* path;
88 88
      typename Digraph::Node current;
89 89
    };
90 90

	
91 91
  private:
92 92
    const Digraph& digraph;
93 93
    const PredMap& predMap;
94 94
    typename Digraph::Node target;
95 95
  };
96 96

	
97 97

	
98 98
  template <typename _Digraph, typename _PredMatrixMap>
99 99
  class PredMatrixMapPath {
100 100
  public:
101 101
    typedef True RevPathTag;
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
///\file
20 20
///\brief Some basic non-inline functions and static global data.
21 21

	
22 22
#include<lemon/bits/windows.h>
23 23

	
24 24
#ifdef WIN32
25 25
#ifndef WIN32_LEAN_AND_MEAN
26 26
#define WIN32_LEAN_AND_MEAN
27 27
#endif
28 28
#ifndef NOMINMAX
29 29
#define NOMINMAX
30 30
#endif
31 31
#ifdef UNICODE
32 32
#undef UNICODE
33 33
#endif
34 34
#include <windows.h>
35 35
#ifdef LOCALE_INVARIANT
36 36
#define MY_LOCALE LOCALE_INVARIANT
37 37
#else
38 38
#define MY_LOCALE LOCALE_NEUTRAL
39 39
#endif
40 40
#else
41 41
#include <unistd.h>
42 42
#include <ctime>
43 43
#ifndef WIN32
44 44
#include <sys/times.h>
45 45
#endif
46 46
#include <sys/time.h>
47 47
#endif
48 48

	
49 49
#include <cmath>
50 50
#include <sstream>
51 51

	
52 52
namespace lemon {
53 53
  namespace bits {
54 54
    void getWinProcTimes(double &rtime,
55 55
                         double &utime, double &stime,
56 56
                         double &cutime, double &cstime)
57 57
    {
58 58
#ifdef WIN32
59 59
      static const double ch = 4294967296.0e-7;
60 60
      static const double cl = 1.0e-7;
61 61

	
62 62
      FILETIME system;
63 63
      GetSystemTimeAsFileTime(&system);
64 64
      rtime = ch * system.dwHighDateTime + cl * system.dwLowDateTime;
65 65

	
66 66
      FILETIME create, exit, kernel, user;
67 67
      if (GetProcessTimes(GetCurrentProcess(),&create, &exit, &kernel, &user)) {
68 68
        utime = ch * user.dwHighDateTime + cl * user.dwLowDateTime;
69 69
        stime = ch * kernel.dwHighDateTime + cl * kernel.dwLowDateTime;
70 70
        cutime = 0;
71 71
        cstime = 0;
72 72
      } else {
73 73
        rtime = 0;
74 74
        utime = 0;
75 75
        stime = 0;
76 76
        cutime = 0;
77 77
        cstime = 0;
78 78
      }
79 79
#else
80 80
      timeval tv;
81 81
      gettimeofday(&tv, 0);
82 82
      rtime=tv.tv_sec+double(tv.tv_usec)/1e6;
83 83

	
84 84
      tms ts;
85 85
      double tck=sysconf(_SC_CLK_TCK);
86 86
      times(&ts);
87 87
      utime=ts.tms_utime/tck;
88 88
      stime=ts.tms_stime/tck;
89 89
      cutime=ts.tms_cutime/tck;
90 90
      cstime=ts.tms_cstime/tck;
91 91
#endif
92 92
    }
93 93

	
94 94
    std::string getWinFormattedDate()
95 95
    {
96 96
      std::ostringstream os;
97 97
#ifdef WIN32
98 98
      SYSTEMTIME time;
99 99
      GetSystemTime(&time);
100 100
      char buf1[11], buf2[9], buf3[5];
101 101
          if (GetDateFormat(MY_LOCALE, 0, &time,
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_COST_SCALING_H
20 20
#define LEMON_COST_SCALING_H
21 21

	
22 22
/// \ingroup min_cost_flow_algs
23 23
/// \file
24 24
/// \brief Cost scaling algorithm for finding a minimum cost flow.
25 25

	
26 26
#include <vector>
27 27
#include <deque>
28 28
#include <limits>
29 29

	
30 30
#include <lemon/core.h>
31 31
#include <lemon/maps.h>
32 32
#include <lemon/math.h>
33 33
#include <lemon/static_graph.h>
34 34
#include <lemon/circulation.h>
35 35
#include <lemon/bellman_ford.h>
36 36

	
37 37
namespace lemon {
38 38

	
39 39
  /// \brief Default traits class of CostScaling algorithm.
40 40
  ///
41 41
  /// Default traits class of CostScaling algorithm.
42 42
  /// \tparam GR Digraph type.
43 43
  /// \tparam V The number type used for flow amounts, capacity bounds
44 44
  /// and supply values. By default it is \c int.
45 45
  /// \tparam C The number type used for costs and potentials.
46 46
  /// By default it is the same as \c V.
47 47
#ifdef DOXYGEN
48 48
  template <typename GR, typename V = int, typename C = V>
49 49
#else
50 50
  template < typename GR, typename V = int, typename C = V,
51 51
             bool integer = std::numeric_limits<C>::is_integer >
52 52
#endif
53 53
  struct CostScalingDefaultTraits
54 54
  {
55 55
    /// The type of the digraph
56 56
    typedef GR Digraph;
57 57
    /// The type of the flow amounts, capacity bounds and supply values
58 58
    typedef V Value;
59 59
    /// The type of the arc costs
60 60
    typedef C Cost;
61 61

	
62 62
    /// \brief The large cost type used for internal computations
63 63
    ///
64 64
    /// The large cost type used for internal computations.
65 65
    /// It is \c long \c long if the \c Cost type is integer,
66 66
    /// otherwise it is \c double.
67 67
    /// \c Cost must be convertible to \c LargeCost.
68 68
    typedef double LargeCost;
69 69
  };
70 70

	
71 71
  // Default traits class for integer cost types
72 72
  template <typename GR, typename V, typename C>
73 73
  struct CostScalingDefaultTraits<GR, V, C, true>
74 74
  {
75 75
    typedef GR Digraph;
76 76
    typedef V Value;
77 77
    typedef C Cost;
78 78
#ifdef LEMON_HAVE_LONG_LONG
79 79
    typedef long long LargeCost;
80 80
#else
81 81
    typedef long LargeCost;
82 82
#endif
83 83
  };
84 84

	
85 85

	
86 86
  /// \addtogroup min_cost_flow_algs
87 87
  /// @{
88 88

	
89 89
  /// \brief Implementation of the Cost Scaling algorithm for
90 90
  /// finding a \ref min_cost_flow "minimum cost flow".
91 91
  ///
92 92
  /// \ref CostScaling implements a cost scaling algorithm that performs
93 93
  /// push/augment and relabel operations for finding a \ref min_cost_flow
94 94
  /// "minimum cost flow" \ref amo93networkflows, \ref goldberg90approximation,
95 95
  /// \ref goldberg97efficient, \ref bunnagel98efficient.
96 96
  /// It is a highly efficient primal-dual solution method, which
97 97
  /// can be viewed as the generalization of the \ref Preflow
98 98
  /// "preflow push-relabel" algorithm for the maximum flow problem.
99 99
  ///
100 100
  /// Most of the parameters of the problem (except for the digraph)
101 101
  /// can be given using separate functions, and the algorithm can be
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_MAPS_H
20 20
#define LEMON_MAPS_H
21 21

	
22 22
#include <iterator>
23 23
#include <functional>
24 24
#include <vector>
25 25
#include <map>
26 26

	
27 27
#include <lemon/core.h>
28 28

	
29 29
///\file
30 30
///\ingroup maps
31 31
///\brief Miscellaneous property maps
32 32

	
33 33
namespace lemon {
34 34

	
35 35
  /// \addtogroup maps
36 36
  /// @{
37 37

	
38 38
  /// Base class of maps.
39 39

	
40 40
  /// Base class of maps. It provides the necessary type definitions
41 41
  /// required by the map %concepts.
42 42
  template<typename K, typename V>
43 43
  class MapBase {
44 44
  public:
45 45
    /// \brief The key type of the map.
46 46
    typedef K Key;
47 47
    /// \brief The value type of the map.
48 48
    /// (The type of objects associated with the keys).
49 49
    typedef V Value;
50 50
  };
51 51

	
52 52

	
53 53
  /// Null map. (a.k.a. DoNothingMap)
54 54

	
55 55
  /// This map can be used if you have to provide a map only for
56 56
  /// its type definitions, or if you have to provide a writable map,
57 57
  /// but data written to it is not required (i.e. it will be sent to
58 58
  /// <tt>/dev/null</tt>).
59 59
  /// It conforms to the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
60 60
  ///
61 61
  /// \sa ConstMap
62 62
  template<typename K, typename V>
63 63
  class NullMap : public MapBase<K, V> {
64 64
  public:
65 65
    ///\e
66 66
    typedef K Key;
67 67
    ///\e
68 68
    typedef V Value;
69 69

	
70 70
    /// Gives back a default constructed element.
71 71
    Value operator[](const Key&) const { return Value(); }
72 72
    /// Absorbs the value.
73 73
    void set(const Key&, const Value&) {}
74 74
  };
75 75

	
76 76
  /// Returns a \c NullMap class
77 77

	
78 78
  /// This function just returns a \c NullMap class.
79 79
  /// \relates NullMap
80 80
  template <typename K, typename V>
81 81
  NullMap<K, V> nullMap() {
82 82
    return NullMap<K, V>();
83 83
  }
84 84

	
85 85

	
86 86
  /// Constant map.
87 87

	
88 88
  /// This \ref concepts::ReadMap "readable map" assigns a specified
89 89
  /// value to each key.
90 90
  ///
91 91
  /// In other aspects it is equivalent to \c NullMap.
92 92
  /// So it conforms to the \ref concepts::ReadWriteMap "ReadWriteMap"
93 93
  /// concept, but it absorbs the data written to it.
94 94
  ///
95 95
  /// The simplest way of using this map is through the constMap()
96 96
  /// function.
97 97
  ///
98 98
  /// \sa NullMap
99 99
  /// \sa IdentityMap
100 100
  template<typename K, typename V>
101 101
  class ConstMap : public MapBase<K, V> {
Ignore white space 192 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#ifndef LEMON_PREFLOW_H
20 20
#define LEMON_PREFLOW_H
21 21

	
22 22
#include <lemon/tolerance.h>
23 23
#include <lemon/elevator.h>
24 24

	
25 25
/// \file
26 26
/// \ingroup max_flow
27 27
/// \brief Implementation of the preflow algorithm.
28 28

	
29 29
namespace lemon {
30 30

	
31 31
  /// \brief Default traits class of Preflow class.
32 32
  ///
33 33
  /// Default traits class of Preflow class.
34 34
  /// \tparam GR Digraph type.
35 35
  /// \tparam CAP Capacity map type.
36 36
  template <typename GR, typename CAP>
37 37
  struct PreflowDefaultTraits {
38 38

	
39 39
    /// \brief The type of the digraph the algorithm runs on.
40 40
    typedef GR Digraph;
41 41

	
42 42
    /// \brief The type of the map that stores the arc capacities.
43 43
    ///
44 44
    /// The type of the map that stores the arc capacities.
45 45
    /// It must meet the \ref concepts::ReadMap "ReadMap" concept.
46 46
    typedef CAP CapacityMap;
47 47

	
48 48
    /// \brief The type of the flow values.
49 49
    typedef typename CapacityMap::Value Value;
50 50

	
51 51
    /// \brief The type of the map that stores the flow values.
52 52
    ///
53 53
    /// The type of the map that stores the flow values.
54 54
    /// It must meet the \ref concepts::ReadWriteMap "ReadWriteMap" concept.
55 55
#ifdef DOXYGEN
56 56
    typedef GR::ArcMap<Value> FlowMap;
57 57
#else
58 58
    typedef typename Digraph::template ArcMap<Value> FlowMap;
59 59
#endif
60 60

	
61 61
    /// \brief Instantiates a FlowMap.
62 62
    ///
63 63
    /// This function instantiates a \ref FlowMap.
64 64
    /// \param digraph The digraph for which we would like to define
65 65
    /// the flow map.
66 66
    static FlowMap* createFlowMap(const Digraph& digraph) {
67 67
      return new FlowMap(digraph);
68 68
    }
69 69

	
70 70
    /// \brief The elevator type used by Preflow algorithm.
71 71
    ///
72 72
    /// The elevator type used by Preflow algorithm.
73 73
    ///
74 74
    /// \sa Elevator, LinkedElevator
75 75
#ifdef DOXYGEN
76 76
    typedef lemon::Elevator<GR, GR::Node> Elevator;
77 77
#else
78 78
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
79 79
#endif
80 80

	
81 81
    /// \brief Instantiates an Elevator.
82 82
    ///
83 83
    /// This function instantiates an \ref Elevator.
84 84
    /// \param digraph The digraph for which we would like to define
85 85
    /// the elevator.
86 86
    /// \param max_level The maximum level of the elevator.
87 87
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
88 88
      return new Elevator(digraph, max_level);
89 89
    }
90 90

	
91 91
    /// \brief The tolerance used by the algorithm
92 92
    ///
93 93
    /// The tolerance used by the algorithm to handle inexact computation.
94 94
    typedef lemon::Tolerance<Value> Tolerance;
95 95

	
96 96
  };
97 97

	
98 98

	
99 99
  /// \ingroup max_flow
100 100
  ///
101 101
  /// \brief %Preflow algorithm class.
... ...
@@ -461,224 +461,224 @@
461 461
        if (_tolerance.positive((*_capacity)[e])) {
462 462
          Node u = _graph.target(e);
463 463
          if ((*_level)[u] == _level->maxLevel()) continue;
464 464
          _flow->set(e, (*_capacity)[e]);
465 465
          (*_excess)[u] += (*_capacity)[e];
466 466
          if (u != _target && !_level->active(u)) {
467 467
            _level->activate(u);
468 468
          }
469 469
        }
470 470
      }
471 471
    }
472 472

	
473 473
    /// \brief Initializes the internal data structures using the
474 474
    /// given flow map.
475 475
    ///
476 476
    /// Initializes the internal data structures and sets the initial
477 477
    /// flow to the given \c flowMap. The \c flowMap should contain a
478 478
    /// flow or at least a preflow, i.e. at each node excluding the
479 479
    /// source node the incoming flow should greater or equal to the
480 480
    /// outgoing flow.
481 481
    /// \return \c false if the given \c flowMap is not a preflow.
482 482
    template <typename FlowMap>
483 483
    bool init(const FlowMap& flowMap) {
484 484
      createStructures();
485 485

	
486 486
      for (ArcIt e(_graph); e != INVALID; ++e) {
487 487
        _flow->set(e, flowMap[e]);
488 488
      }
489 489

	
490 490
      for (NodeIt n(_graph); n != INVALID; ++n) {
491 491
        Value excess = 0;
492 492
        for (InArcIt e(_graph, n); e != INVALID; ++e) {
493 493
          excess += (*_flow)[e];
494 494
        }
495 495
        for (OutArcIt e(_graph, n); e != INVALID; ++e) {
496 496
          excess -= (*_flow)[e];
497 497
        }
498 498
        if (excess < 0 && n != _source) return false;
499 499
        (*_excess)[n] = excess;
500 500
      }
501 501

	
502 502
      typename Digraph::template NodeMap<bool> reached(_graph, false);
503 503

	
504 504
      _level->initStart();
505 505
      _level->initAddItem(_target);
506 506

	
507 507
      std::vector<Node> queue;
508 508
      reached[_source] = true;
509 509

	
510 510
      queue.push_back(_target);
511 511
      reached[_target] = true;
512 512
      while (!queue.empty()) {
513 513
        _level->initNewLevel();
514 514
        std::vector<Node> nqueue;
515 515
        for (int i = 0; i < int(queue.size()); ++i) {
516 516
          Node n = queue[i];
517 517
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
518 518
            Node u = _graph.source(e);
519 519
            if (!reached[u] &&
520 520
                _tolerance.positive((*_capacity)[e] - (*_flow)[e])) {
521 521
              reached[u] = true;
522 522
              _level->initAddItem(u);
523 523
              nqueue.push_back(u);
524 524
            }
525 525
          }
526 526
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
527 527
            Node v = _graph.target(e);
528 528
            if (!reached[v] && _tolerance.positive((*_flow)[e])) {
529 529
              reached[v] = true;
530 530
              _level->initAddItem(v);
531 531
              nqueue.push_back(v);
532 532
            }
533 533
          }
534 534
        }
535 535
        queue.swap(nqueue);
536 536
      }
537 537
      _level->initFinish();
538 538

	
539 539
      for (OutArcIt e(_graph, _source); e != INVALID; ++e) {
540 540
        Value rem = (*_capacity)[e] - (*_flow)[e];
541 541
        if (_tolerance.positive(rem)) {
542 542
          Node u = _graph.target(e);
543 543
          if ((*_level)[u] == _level->maxLevel()) continue;
544 544
          _flow->set(e, (*_capacity)[e]);
545 545
          (*_excess)[u] += rem;
546 546
        }
547 547
      }
548 548
      for (InArcIt e(_graph, _source); e != INVALID; ++e) {
549 549
        Value rem = (*_flow)[e];
550 550
        if (_tolerance.positive(rem)) {
551 551
          Node v = _graph.source(e);
552 552
          if ((*_level)[v] == _level->maxLevel()) continue;
553 553
          _flow->set(e, 0);
554 554
          (*_excess)[v] += rem;
555 555
        }
556 556
      }
557
      for (NodeIt n(_graph); n != INVALID; ++n) 
557
      for (NodeIt n(_graph); n != INVALID; ++n)
558 558
        if(n!=_source && n!=_target && _tolerance.positive((*_excess)[n]))
559 559
          _level->activate(n);
560
          
560

	
561 561
      return true;
562 562
    }
563 563

	
564 564
    /// \brief Starts the first phase of the preflow algorithm.
565 565
    ///
566 566
    /// The preflow algorithm consists of two phases, this method runs
567 567
    /// the first phase. After the first phase the maximum flow value
568 568
    /// and a minimum value cut can already be computed, although a
569 569
    /// maximum flow is not yet obtained. So after calling this method
570 570
    /// \ref flowValue() returns the value of a maximum flow and \ref
571 571
    /// minCut() returns a minimum cut.
572 572
    /// \pre One of the \ref init() functions must be called before
573 573
    /// using this function.
574 574
    void startFirstPhase() {
575 575
      _phase = true;
576 576

	
577 577
      while (true) {
578 578
        int num = _node_num;
579 579

	
580 580
        Node n = INVALID;
581 581
        int level = -1;
582 582

	
583 583
        while (num > 0) {
584 584
          n = _level->highestActive();
585 585
          if (n == INVALID) goto first_phase_done;
586 586
          level = _level->highestActiveLevel();
587 587
          --num;
588
          
588

	
589 589
          Value excess = (*_excess)[n];
590 590
          int new_level = _level->maxLevel();
591 591

	
592 592
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
593 593
            Value rem = (*_capacity)[e] - (*_flow)[e];
594 594
            if (!_tolerance.positive(rem)) continue;
595 595
            Node v = _graph.target(e);
596 596
            if ((*_level)[v] < level) {
597 597
              if (!_level->active(v) && v != _target) {
598 598
                _level->activate(v);
599 599
              }
600 600
              if (!_tolerance.less(rem, excess)) {
601 601
                _flow->set(e, (*_flow)[e] + excess);
602 602
                (*_excess)[v] += excess;
603 603
                excess = 0;
604 604
                goto no_more_push_1;
605 605
              } else {
606 606
                excess -= rem;
607 607
                (*_excess)[v] += rem;
608 608
                _flow->set(e, (*_capacity)[e]);
609 609
              }
610 610
            } else if (new_level > (*_level)[v]) {
611 611
              new_level = (*_level)[v];
612 612
            }
613 613
          }
614 614

	
615 615
          for (InArcIt e(_graph, n); e != INVALID; ++e) {
616 616
            Value rem = (*_flow)[e];
617 617
            if (!_tolerance.positive(rem)) continue;
618 618
            Node v = _graph.source(e);
619 619
            if ((*_level)[v] < level) {
620 620
              if (!_level->active(v) && v != _target) {
621 621
                _level->activate(v);
622 622
              }
623 623
              if (!_tolerance.less(rem, excess)) {
624 624
                _flow->set(e, (*_flow)[e] - excess);
625 625
                (*_excess)[v] += excess;
626 626
                excess = 0;
627 627
                goto no_more_push_1;
628 628
              } else {
629 629
                excess -= rem;
630 630
                (*_excess)[v] += rem;
631 631
                _flow->set(e, 0);
632 632
              }
633 633
            } else if (new_level > (*_level)[v]) {
634 634
              new_level = (*_level)[v];
635 635
            }
636 636
          }
637 637

	
638 638
        no_more_push_1:
639 639

	
640 640
          (*_excess)[n] = excess;
641 641

	
642 642
          if (excess != 0) {
643 643
            if (new_level + 1 < _level->maxLevel()) {
644 644
              _level->liftHighestActive(new_level + 1);
645 645
            } else {
646 646
              _level->liftHighestActiveToTop();
647 647
            }
648 648
            if (_level->emptyLevel(level)) {
649 649
              _level->liftToTop(level);
650 650
            }
651 651
          } else {
652 652
            _level->deactivate(n);
653 653
          }
654 654
        }
655 655

	
656 656
        num = _node_num * 20;
657 657
        while (num > 0) {
658 658
          while (level >= 0 && _level->activeFree(level)) {
659 659
            --level;
660 660
          }
661 661
          if (level == -1) {
662 662
            n = _level->highestActive();
663 663
            level = _level->highestActiveLevel();
664 664
            if (n == INVALID) goto first_phase_done;
665 665
          } else {
666 666
            n = _level->activeOn(level);
667 667
          }
668 668
          --num;
669 669

	
670 670
          Value excess = (*_excess)[n];
671 671
          int new_level = _level->maxLevel();
672 672

	
673 673
          for (OutArcIt e(_graph, n); e != INVALID; ++e) {
674 674
            Value rem = (*_capacity)[e] - (*_flow)[e];
675 675
            if (!_tolerance.positive(rem)) continue;
676 676
            Node v = _graph.target(e);
677 677
            if ((*_level)[v] < level) {
678 678
              if (!_level->active(v) && v != _target) {
679 679
                _level->activate(v);
680 680
              }
681 681
              if (!_tolerance.less(rem, excess)) {
682 682
                _flow->set(e, (*_flow)[e] + excess);
683 683
                (*_excess)[v] += excess;
684 684
                excess = 0;
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/concepts/digraph.h>
20 20
#include <lemon/smart_graph.h>
21 21
#include <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/dfs.h>
24 24
#include <lemon/path.h>
25 25

	
26 26
#include "graph_test.h"
27 27
#include "test_tools.h"
28 28

	
29 29
using namespace lemon;
30 30

	
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "@arcs\n"
42 42
  "     label\n"
43 43
  "0 1  0\n"
44 44
  "1 2  1\n"
45 45
  "2 3  2\n"
46 46
  "1 4  3\n"
47 47
  "4 2  4\n"
48 48
  "4 5  5\n"
49 49
  "5 0  6\n"
50 50
  "6 3  7\n"
51 51
  "@attributes\n"
52 52
  "source 0\n"
53 53
  "target 5\n"
54 54
  "source1 6\n"
55 55
  "target1 3\n";
56 56

	
57 57

	
58 58
void checkDfsCompile()
59 59
{
60 60
  typedef concepts::Digraph Digraph;
61 61
  typedef Dfs<Digraph> DType;
62 62
  typedef Digraph::Node Node;
63 63
  typedef Digraph::Arc Arc;
64 64

	
65 65
  Digraph G;
66 66
  Node s, t;
67 67
  Arc e;
68 68
  int l, i;
69 69
  bool b;
70 70
  DType::DistMap d(G);
71 71
  DType::PredMap p(G);
72 72
  Path<Digraph> pp;
73 73
  concepts::ReadMap<Arc,bool> am;
74 74

	
75 75
  {
76 76
    DType dfs_test(G);
77 77
    const DType& const_dfs_test = dfs_test;
78 78

	
79 79
    dfs_test.run(s);
80 80
    dfs_test.run(s,t);
81 81
    dfs_test.run();
82 82

	
83 83
    dfs_test.init();
84 84
    dfs_test.addSource(s);
85 85
    e = dfs_test.processNextArc();
86 86
    e = const_dfs_test.nextArc();
87 87
    b = const_dfs_test.emptyQueue();
88 88
    i = const_dfs_test.queueSize();
89 89

	
90 90
    dfs_test.start();
91 91
    dfs_test.start(t);
92 92
    dfs_test.start(am);
93 93

	
94 94
    l  = const_dfs_test.dist(t);
95 95
    e  = const_dfs_test.predArc(t);
96 96
    s  = const_dfs_test.predNode(t);
97 97
    b  = const_dfs_test.reached(t);
98 98
    d  = const_dfs_test.distMap();
99 99
    p  = const_dfs_test.predMap();
100 100
    pp = const_dfs_test.path(t);
101 101
  }
... ...
@@ -126,109 +126,109 @@
126 126

	
127 127
    dfs_test.addSource(s);
128 128
    e = dfs_test.processNextArc();
129 129
    e = dfs_test.nextArc();
130 130
    b = dfs_test.emptyQueue();
131 131
    i = dfs_test.queueSize();
132 132

	
133 133
    dfs_test.start();
134 134
    dfs_test.start(t);
135 135
    dfs_test.start(am);
136 136

	
137 137
    l  = dfs_test.dist(t);
138 138
    e  = dfs_test.predArc(t);
139 139
    s  = dfs_test.predNode(t);
140 140
    b  = dfs_test.reached(t);
141 141
    pp = dfs_test.path(t);
142 142
  }
143 143
}
144 144

	
145 145
void checkDfsFunctionCompile()
146 146
{
147 147
  typedef int VType;
148 148
  typedef concepts::Digraph Digraph;
149 149
  typedef Digraph::Arc Arc;
150 150
  typedef Digraph::Node Node;
151 151

	
152 152
  Digraph g;
153 153
  bool b;
154 154
  dfs(g).run(Node());
155 155
  b=dfs(g).run(Node(),Node());
156 156
  dfs(g).run();
157 157
  dfs(g)
158 158
    .predMap(concepts::ReadWriteMap<Node,Arc>())
159 159
    .distMap(concepts::ReadWriteMap<Node,VType>())
160 160
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
161 161
    .processedMap(concepts::WriteMap<Node,bool>())
162 162
    .run(Node());
163 163
  b=dfs(g)
164 164
    .predMap(concepts::ReadWriteMap<Node,Arc>())
165 165
    .distMap(concepts::ReadWriteMap<Node,VType>())
166 166
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
167 167
    .processedMap(concepts::WriteMap<Node,bool>())
168 168
    .path(concepts::Path<Digraph>())
169 169
    .dist(VType())
170 170
    .run(Node(),Node());
171 171
  dfs(g)
172 172
    .predMap(concepts::ReadWriteMap<Node,Arc>())
173 173
    .distMap(concepts::ReadWriteMap<Node,VType>())
174 174
    .reachedMap(concepts::ReadWriteMap<Node,bool>())
175 175
    .processedMap(concepts::WriteMap<Node,bool>())
176 176
    .run();
177 177
}
178 178

	
179 179
template <class Digraph>
180 180
void checkDfs() {
181 181
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
182 182

	
183 183
  Digraph G;
184 184
  Node s, t;
185 185
  Node s1, t1;
186 186

	
187 187
  std::istringstream input(test_lgf);
188 188
  digraphReader(G, input).
189 189
    node("source", s).
190 190
    node("target", t).
191 191
    node("source1", s1).
192 192
    node("target1", t1).
193 193
    run();
194 194

	
195 195
  Dfs<Digraph> dfs_test(G);
196 196
  dfs_test.run(s);
197 197

	
198 198
  Path<Digraph> p = dfs_test.path(t);
199 199
  check(p.length() == dfs_test.dist(t),"path() found a wrong path.");
200 200
  check(checkPath(G, p),"path() found a wrong path.");
201 201
  check(pathSource(G, p) == s,"path() found a wrong path.");
202 202
  check(pathTarget(G, p) == t,"path() found a wrong path.");
203 203

	
204 204
  for(NodeIt v(G); v!=INVALID; ++v) {
205 205
    if (dfs_test.reached(v)) {
206 206
      check(v==s || dfs_test.predArc(v)!=INVALID, "Wrong tree.");
207 207
      if (dfs_test.predArc(v)!=INVALID ) {
208 208
        Arc e=dfs_test.predArc(v);
209 209
        Node u=G.source(e);
210 210
        check(u==dfs_test.predNode(v),"Wrong tree.");
211 211
        check(dfs_test.dist(v) - dfs_test.dist(u) == 1,
212 212
              "Wrong distance. (" << dfs_test.dist(u) << "->"
213 213
              << dfs_test.dist(v) << ")");
214 214
      }
215 215
    }
216 216
  }
217 217

	
218 218
  {
219 219
  Dfs<Digraph> dfs(G);
220 220
  check(dfs.run(s1,t1) && dfs.reached(t1),"Node 3 is reachable from Node 6.");
221 221
  }
222
  
222

	
223 223
  {
224 224
    NullMap<Node,Arc> myPredMap;
225 225
    dfs(G).predMap(myPredMap).run(s);
226 226
  }
227 227
}
228 228

	
229 229
int main()
230 230
{
231 231
  checkDfs<ListDigraph>();
232 232
  checkDfs<SmartDigraph>();
233 233
  return 0;
234 234
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/smart_graph.h>
20 20
#include <lemon/list_graph.h>
21 21
#include <lemon/lgf_reader.h>
22 22
#include <lemon/error.h>
23 23

	
24 24
#include "test_tools.h"
25 25

	
26 26
using namespace std;
27 27
using namespace lemon;
28 28

	
29 29
void digraph_copy_test() {
30 30
  const int nn = 10;
31 31

	
32 32
  // Build a digraph
33 33
  SmartDigraph from;
34 34
  SmartDigraph::NodeMap<int> fnm(from);
35 35
  SmartDigraph::ArcMap<int> fam(from);
36 36
  SmartDigraph::Node fn = INVALID;
37 37
  SmartDigraph::Arc fa = INVALID;
38 38

	
39 39
  std::vector<SmartDigraph::Node> fnv;
40 40
  for (int i = 0; i < nn; ++i) {
41 41
    SmartDigraph::Node node = from.addNode();
42 42
    fnv.push_back(node);
43 43
    fnm[node] = i * i;
44 44
    if (i == 0) fn = node;
45 45
  }
46 46

	
47 47
  for (int i = 0; i < nn; ++i) {
48 48
    for (int j = 0; j < nn; ++j) {
49 49
      SmartDigraph::Arc arc = from.addArc(fnv[i], fnv[j]);
50 50
      fam[arc] = i + j * j;
51 51
      if (i == 0 && j == 0) fa = arc;
52 52
    }
53 53
  }
54 54

	
55 55
  // Test digraph copy
56 56
  ListDigraph to;
57 57
  ListDigraph::NodeMap<int> tnm(to);
58 58
  ListDigraph::ArcMap<int> tam(to);
59 59
  ListDigraph::Node tn;
60 60
  ListDigraph::Arc ta;
61 61

	
62 62
  SmartDigraph::NodeMap<ListDigraph::Node> nr(from);
63 63
  SmartDigraph::ArcMap<ListDigraph::Arc> er(from);
64 64

	
65 65
  ListDigraph::NodeMap<SmartDigraph::Node> ncr(to);
66 66
  ListDigraph::ArcMap<SmartDigraph::Arc> ecr(to);
67 67

	
68 68
  digraphCopy(from, to).
69 69
    nodeMap(fnm, tnm).arcMap(fam, tam).
70 70
    nodeRef(nr).arcRef(er).
71 71
    nodeCrossRef(ncr).arcCrossRef(ecr).
72 72
    node(fn, tn).arc(fa, ta).run();
73
  
73

	
74 74
  check(countNodes(from) == countNodes(to), "Wrong copy.");
75 75
  check(countArcs(from) == countArcs(to), "Wrong copy.");
76 76

	
77 77
  for (SmartDigraph::NodeIt it(from); it != INVALID; ++it) {
78 78
    check(ncr[nr[it]] == it, "Wrong copy.");
79 79
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
80 80
  }
81 81

	
82 82
  for (SmartDigraph::ArcIt it(from); it != INVALID; ++it) {
83 83
    check(ecr[er[it]] == it, "Wrong copy.");
84 84
    check(fam[it] == tam[er[it]], "Wrong copy.");
85 85
    check(nr[from.source(it)] == to.source(er[it]), "Wrong copy.");
86 86
    check(nr[from.target(it)] == to.target(er[it]), "Wrong copy.");
87 87
  }
88 88

	
89 89
  for (ListDigraph::NodeIt it(to); it != INVALID; ++it) {
90 90
    check(nr[ncr[it]] == it, "Wrong copy.");
91 91
  }
92 92

	
93 93
  for (ListDigraph::ArcIt it(to); it != INVALID; ++it) {
94 94
    check(er[ecr[it]] == it, "Wrong copy.");
95 95
  }
96 96
  check(tn == nr[fn], "Wrong copy.");
97 97
  check(ta == er[fa], "Wrong copy.");
98 98

	
99 99
  // Test repeated copy
100 100
  digraphCopy(from, to).run();
101
  
101

	
102 102
  check(countNodes(from) == countNodes(to), "Wrong copy.");
103 103
  check(countArcs(from) == countArcs(to), "Wrong copy.");
104 104
}
105 105

	
106 106
void graph_copy_test() {
107 107
  const int nn = 10;
108 108

	
109 109
  // Build a graph
110 110
  SmartGraph from;
111 111
  SmartGraph::NodeMap<int> fnm(from);
112 112
  SmartGraph::ArcMap<int> fam(from);
113 113
  SmartGraph::EdgeMap<int> fem(from);
114 114
  SmartGraph::Node fn = INVALID;
115 115
  SmartGraph::Arc fa = INVALID;
116 116
  SmartGraph::Edge fe = INVALID;
117 117

	
118 118
  std::vector<SmartGraph::Node> fnv;
119 119
  for (int i = 0; i < nn; ++i) {
120 120
    SmartGraph::Node node = from.addNode();
121 121
    fnv.push_back(node);
122 122
    fnm[node] = i * i;
123 123
    if (i == 0) fn = node;
124 124
  }
125 125

	
126 126
  for (int i = 0; i < nn; ++i) {
127 127
    for (int j = 0; j < nn; ++j) {
128 128
      SmartGraph::Edge edge = from.addEdge(fnv[i], fnv[j]);
129 129
      fem[edge] = i * i + j * j;
130 130
      fam[from.direct(edge, true)] = i + j * j;
131 131
      fam[from.direct(edge, false)] = i * i + j;
132 132
      if (i == 0 && j == 0) fa = from.direct(edge, true);
133 133
      if (i == 0 && j == 0) fe = edge;
134 134
    }
135 135
  }
136 136

	
137 137
  // Test graph copy
138 138
  ListGraph to;
139 139
  ListGraph::NodeMap<int> tnm(to);
140 140
  ListGraph::ArcMap<int> tam(to);
141 141
  ListGraph::EdgeMap<int> tem(to);
142 142
  ListGraph::Node tn;
143 143
  ListGraph::Arc ta;
144 144
  ListGraph::Edge te;
145 145

	
146 146
  SmartGraph::NodeMap<ListGraph::Node> nr(from);
147 147
  SmartGraph::ArcMap<ListGraph::Arc> ar(from);
148 148
  SmartGraph::EdgeMap<ListGraph::Edge> er(from);
149 149

	
150 150
  ListGraph::NodeMap<SmartGraph::Node> ncr(to);
151 151
  ListGraph::ArcMap<SmartGraph::Arc> acr(to);
152 152
  ListGraph::EdgeMap<SmartGraph::Edge> ecr(to);
153 153

	
154 154
  graphCopy(from, to).
155 155
    nodeMap(fnm, tnm).arcMap(fam, tam).edgeMap(fem, tem).
156 156
    nodeRef(nr).arcRef(ar).edgeRef(er).
157 157
    nodeCrossRef(ncr).arcCrossRef(acr).edgeCrossRef(ecr).
158 158
    node(fn, tn).arc(fa, ta).edge(fe, te).run();
159 159

	
160 160
  check(countNodes(from) == countNodes(to), "Wrong copy.");
161 161
  check(countEdges(from) == countEdges(to), "Wrong copy.");
162 162
  check(countArcs(from) == countArcs(to), "Wrong copy.");
163 163

	
164 164
  for (SmartGraph::NodeIt it(from); it != INVALID; ++it) {
165 165
    check(ncr[nr[it]] == it, "Wrong copy.");
166 166
    check(fnm[it] == tnm[nr[it]], "Wrong copy.");
167 167
  }
168 168

	
169 169
  for (SmartGraph::ArcIt it(from); it != INVALID; ++it) {
170 170
    check(acr[ar[it]] == it, "Wrong copy.");
171 171
    check(fam[it] == tam[ar[it]], "Wrong copy.");
172 172
    check(nr[from.source(it)] == to.source(ar[it]), "Wrong copy.");
173 173
    check(nr[from.target(it)] == to.target(ar[it]), "Wrong copy.");
174 174
  }
175 175

	
176 176
  for (SmartGraph::EdgeIt it(from); it != INVALID; ++it) {
177 177
    check(ecr[er[it]] == it, "Wrong copy.");
178 178
    check(fem[it] == tem[er[it]], "Wrong copy.");
179 179
    check(nr[from.u(it)] == to.u(er[it]) || nr[from.u(it)] == to.v(er[it]),
180 180
          "Wrong copy.");
181 181
    check(nr[from.v(it)] == to.u(er[it]) || nr[from.v(it)] == to.v(er[it]),
182 182
          "Wrong copy.");
183 183
    check((from.u(it) != from.v(it)) == (to.u(er[it]) != to.v(er[it])),
184 184
          "Wrong copy.");
185 185
  }
186 186

	
187 187
  for (ListGraph::NodeIt it(to); it != INVALID; ++it) {
188 188
    check(nr[ncr[it]] == it, "Wrong copy.");
189 189
  }
190 190

	
191 191
  for (ListGraph::ArcIt it(to); it != INVALID; ++it) {
192 192
    check(ar[acr[it]] == it, "Wrong copy.");
193 193
  }
194 194
  for (ListGraph::EdgeIt it(to); it != INVALID; ++it) {
195 195
    check(er[ecr[it]] == it, "Wrong copy.");
196 196
  }
197 197
  check(tn == nr[fn], "Wrong copy.");
198 198
  check(ta == ar[fa], "Wrong copy.");
199 199
  check(te == er[fe], "Wrong copy.");
200 200

	
201 201
  // Test repeated copy
202 202
  graphCopy(from, to).run();
203
  
203

	
204 204
  check(countNodes(from) == countNodes(to), "Wrong copy.");
205 205
  check(countEdges(from) == countEdges(to), "Wrong copy.");
206 206
  check(countArcs(from) == countArcs(to), "Wrong copy.");
207 207
}
208 208

	
209 209

	
210 210
int main() {
211 211
  digraph_copy_test();
212 212
  graph_copy_test();
213 213

	
214 214
  return 0;
215 215
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2009
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20
#include <fstream>
21 21
#include <string>
22 22
#include <vector>
23 23

	
24 24
#include <lemon/concept_check.h>
25 25
#include <lemon/concepts/heap.h>
26 26

	
27 27
#include <lemon/smart_graph.h>
28 28
#include <lemon/lgf_reader.h>
29 29
#include <lemon/dijkstra.h>
30 30
#include <lemon/maps.h>
31 31

	
32 32
#include <lemon/bin_heap.h>
33 33
#include <lemon/quad_heap.h>
34 34
#include <lemon/dheap.h>
35 35
#include <lemon/fib_heap.h>
36 36
#include <lemon/pairing_heap.h>
37 37
#include <lemon/radix_heap.h>
38 38
#include <lemon/binomial_heap.h>
39 39
#include <lemon/bucket_heap.h>
40 40

	
41 41
#include "test_tools.h"
42 42

	
43 43
using namespace lemon;
44 44
using namespace lemon::concepts;
45 45

	
46 46
typedef ListDigraph Digraph;
47 47
DIGRAPH_TYPEDEFS(Digraph);
48 48

	
49 49
char test_lgf[] =
50 50
  "@nodes\n"
51 51
  "label\n"
52 52
  "0\n"
53 53
  "1\n"
54 54
  "2\n"
55 55
  "3\n"
56 56
  "4\n"
57 57
  "5\n"
58 58
  "6\n"
59 59
  "7\n"
60 60
  "8\n"
61 61
  "9\n"
62 62
  "@arcs\n"
63 63
  "                label   capacity\n"
64 64
  "0       5       0       94\n"
65 65
  "3       9       1       11\n"
66 66
  "8       7       2       83\n"
67 67
  "1       2       3       94\n"
68 68
  "5       7       4       35\n"
69 69
  "7       4       5       84\n"
70 70
  "9       5       6       38\n"
71 71
  "0       4       7       96\n"
72 72
  "6       7       8       6\n"
73 73
  "3       1       9       27\n"
74 74
  "5       2       10      77\n"
75 75
  "5       6       11      69\n"
76 76
  "6       5       12      41\n"
77 77
  "4       6       13      70\n"
78 78
  "3       2       14      45\n"
79 79
  "7       9       15      93\n"
80 80
  "5       9       16      50\n"
81 81
  "9       0       17      94\n"
82 82
  "9       6       18      67\n"
83 83
  "0       9       19      86\n"
84 84
  "@attributes\n"
85 85
  "source 3\n";
86 86

	
87 87
int test_seq[] = { 2, 28, 19, 27, 33, 25, 13, 41, 10, 26,  1,  9,  4, 34};
88 88
int test_inc[] = {20, 28, 34, 16,  0, 46, 44,  0, 42, 32, 14,  8,  6, 37};
89 89

	
90 90
int test_len = sizeof(test_seq) / sizeof(test_seq[0]);
91 91

	
92 92
template <typename Heap>
93 93
void heapSortTest() {
94 94
  RangeMap<int> map(test_len, -1);
95 95
  Heap heap(map);
96 96

	
97 97
  std::vector<int> v(test_len);
98 98
  for (int i = 0; i < test_len; ++i) {
99 99
    v[i] = test_seq[i];
100 100
    heap.push(i, v[i]);
101 101
  }
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5 5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <lemon/list_graph.h>
20 20
#include <lemon/lgf_reader.h>
21 21
#include "test_tools.h"
22 22

	
23 23
using namespace lemon;
24 24

	
25 25
char test_lgf[] =
26 26
  "@nodes\n"
27 27
  "label\n"
28 28
  "0\n"
29 29
  "1\n"
30 30
  "@arcs\n"
31 31
  "     label\n"
32 32
  "0 1  0\n"
33 33
  "1 0  1\n"
34 34
  "@attributes\n"
35 35
  "source 0\n"
36 36
  "target 1\n";
37 37

	
38 38
char test_lgf_nomap[] =
39 39
  "@nodes\n"
40 40
  "label\n"
41 41
  "0\n"
42 42
  "1\n"
43 43
  "@arcs\n"
44 44
  "     -\n"
45 45
  "0 1\n";
46 46

	
47 47
char test_lgf_bad1[] =
48 48
  "@nodes\n"
49 49
  "label\n"
50 50
  "0\n"
51 51
  "1\n"
52 52
  "@arcs\n"
53 53
  "     - another\n"
54 54
  "0 1\n";
55 55

	
56 56
char test_lgf_bad2[] =
57 57
  "@nodes\n"
58 58
  "label\n"
59 59
  "0\n"
60 60
  "1\n"
61 61
  "@arcs\n"
62 62
  "     label -\n"
63 63
  "0 1\n";
64 64

	
65 65

	
66
int main() 
66
int main()
67 67
{
68 68
  {
69
    ListDigraph d; 
69
    ListDigraph d;
70 70
    ListDigraph::Node s,t;
71 71
    ListDigraph::ArcMap<int> label(d);
72 72
    std::istringstream input(test_lgf);
73 73
    digraphReader(d, input).
74 74
      node("source", s).
75 75
      node("target", t).
76 76
      arcMap("label", label).
77 77
      run();
78 78
    check(countNodes(d) == 2,"There should be 2 nodes");
79 79
    check(countArcs(d) == 2,"There should be 2 arcs");
80 80
  }
81 81
  {
82 82
    ListGraph g;
83 83
    ListGraph::Node s,t;
84 84
    ListGraph::EdgeMap<int> label(g);
85 85
    std::istringstream input(test_lgf);
86 86
    graphReader(g, input).
87 87
      node("source", s).
88 88
      node("target", t).
89 89
      edgeMap("label", label).
90 90
      run();
91 91
    check(countNodes(g) == 2,"There should be 2 nodes");
92 92
    check(countEdges(g) == 2,"There should be 2 arcs");
93 93
  }
94 94

	
95 95
  {
96
    ListDigraph d; 
96
    ListDigraph d;
97 97
    std::istringstream input(test_lgf_nomap);
98 98
    digraphReader(d, input).
99 99
      run();
100 100
    check(countNodes(d) == 2,"There should be 2 nodes");
101 101
    check(countArcs(d) == 1,"There should be 1 arc");
102 102
  }
103 103
  {
104 104
    ListGraph g;
105 105
    std::istringstream input(test_lgf_nomap);
106 106
    graphReader(g, input).
107 107
      run();
108 108
    check(countNodes(g) == 2,"There should be 2 nodes");
109 109
    check(countEdges(g) == 1,"There should be 1 edge");
110 110
  }
111 111

	
112 112
  {
113
    ListDigraph d; 
113
    ListDigraph d;
114 114
    std::istringstream input(test_lgf_bad1);
115 115
    bool ok=false;
116 116
    try {
117 117
      digraphReader(d, input).
118 118
        run();
119 119
    }
120
    catch (FormatError& error) 
120
    catch (FormatError& error)
121 121
      {
122 122
        ok = true;
123 123
      }
124 124
    check(ok,"FormatError exception should have occured");
125 125
  }
126 126
  {
127 127
    ListGraph g;
128 128
    std::istringstream input(test_lgf_bad1);
129 129
    bool ok=false;
130 130
    try {
131 131
      graphReader(g, input).
132 132
        run();
133 133
    }
134 134
    catch (FormatError& error)
135 135
      {
136 136
        ok = true;
137 137
      }
138 138
    check(ok,"FormatError exception should have occured");
139 139
  }
140 140

	
141 141
  {
142
    ListDigraph d; 
142
    ListDigraph d;
143 143
    std::istringstream input(test_lgf_bad2);
144 144
    bool ok=false;
145 145
    try {
146 146
      digraphReader(d, input).
147 147
        run();
148 148
    }
149 149
    catch (FormatError& error)
150 150
      {
151 151
        ok = true;
152 152
      }
153 153
    check(ok,"FormatError exception should have occured");
154 154
  }
155 155
  {
156 156
    ListGraph g;
157 157
    std::istringstream input(test_lgf_bad2);
158 158
    bool ok=false;
159 159
    try {
160 160
      graphReader(g, input).
161 161
        run();
162 162
    }
163 163
    catch (FormatError& error)
164 164
      {
165 165
        ok = true;
166 166
      }
167 167
    check(ok,"FormatError exception should have occured");
168 168
  }
169 169
}
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <deque>
20 20
#include <set>
21 21

	
22 22
#include <lemon/concept_check.h>
23 23
#include <lemon/concepts/maps.h>
24 24
#include <lemon/maps.h>
25 25
#include <lemon/list_graph.h>
26 26
#include <lemon/smart_graph.h>
27 27
#include <lemon/adaptors.h>
28 28
#include <lemon/dfs.h>
29 29
#include <algorithm>
30 30

	
31 31
#include "test_tools.h"
32 32

	
33 33
using namespace lemon;
34 34
using namespace lemon::concepts;
35 35

	
36 36
struct A {};
37 37
inline bool operator<(A, A) { return true; }
38 38
struct B {};
39 39

	
40 40
class C {
41 41
  int _x;
42 42
public:
43 43
  C(int x) : _x(x) {}
44 44
  int get() const { return _x; }
45 45
};
46 46
inline bool operator<(C c1, C c2) { return c1.get() < c2.get(); }
47 47
inline bool operator==(C c1, C c2) { return c1.get() == c2.get(); }
48 48

	
49 49
C createC(int x) { return C(x); }
50 50

	
51 51
template <typename T>
52 52
class Less {
53 53
  T _t;
54 54
public:
55 55
  Less(T t): _t(t) {}
56 56
  bool operator()(const T& t) const { return t < _t; }
57 57
};
58 58

	
59 59
class F {
60 60
public:
61 61
  typedef A argument_type;
62 62
  typedef B result_type;
63 63

	
64 64
  B operator()(const A&) const { return B(); }
65 65
private:
66 66
  F& operator=(const F&);
67 67
};
68 68

	
69 69
int func(A) { return 3; }
70 70

	
71 71
int binc(int a, B) { return a+1; }
72 72

	
73 73
template <typename T>
74 74
class Sum {
75 75
  T& _sum;
76 76
public:
77 77
  Sum(T& sum) : _sum(sum) {}
78 78
  void operator()(const T& t) { _sum += t; }
79 79
};
80 80

	
81 81
typedef ReadMap<A, double> DoubleMap;
82 82
typedef ReadWriteMap<A, double> DoubleWriteMap;
83 83
typedef ReferenceMap<A, double, double&, const double&> DoubleRefMap;
84 84

	
85 85
typedef ReadMap<A, bool> BoolMap;
86 86
typedef ReadWriteMap<A, bool> BoolWriteMap;
87 87
typedef ReferenceMap<A, bool, bool&, const bool&> BoolRefMap;
88 88

	
89 89
int main()
90 90
{
91 91
  // Map concepts
92 92
  checkConcept<ReadMap<A,B>, ReadMap<A,B> >();
93 93
  checkConcept<ReadMap<A,C>, ReadMap<A,C> >();
94 94
  checkConcept<WriteMap<A,B>, WriteMap<A,B> >();
95 95
  checkConcept<WriteMap<A,C>, WriteMap<A,C> >();
96 96
  checkConcept<ReadWriteMap<A,B>, ReadWriteMap<A,B> >();
97 97
  checkConcept<ReadWriteMap<A,C>, ReadWriteMap<A,C> >();
98 98
  checkConcept<ReferenceMap<A,B,B&,const B&>, ReferenceMap<A,B,B&,const B&> >();
99 99
  checkConcept<ReferenceMap<A,C,C&,const C&>, ReferenceMap<A,C,C&,const C&> >();
100 100

	
101 101
  // NullMap
Ignore white space 6 line context
1 1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
2 2
 *
3 3
 * This file is a part of LEMON, a generic C++ optimization library.
4 4
 *
5
 * Copyright (C) 2003-2010
5
 * Copyright (C) 2003-2011
6 6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
8 8
 *
9 9
 * Permission to use, modify and distribute this software is granted
10 10
 * provided that this copyright notice appears in all copies. For
11 11
 * precise terms see the accompanying LICENSE file.
12 12
 *
13 13
 * This software is provided "AS IS" with no warranty of any kind,
14 14
 * express or implied, and with no claim as to its suitability for any
15 15
 * purpose.
16 16
 *
17 17
 */
18 18

	
19 19
#include <iostream>
20 20

	
21 21
#include "test_tools.h"
22 22
#include <lemon/smart_graph.h>
23 23
#include <lemon/preflow.h>
24 24
#include <lemon/concepts/digraph.h>
25 25
#include <lemon/concepts/maps.h>
26 26
#include <lemon/lgf_reader.h>
27 27
#include <lemon/elevator.h>
28 28

	
29 29
using namespace lemon;
30 30

	
31 31
char test_lgf[] =
32 32
  "@nodes\n"
33 33
  "label\n"
34 34
  "0\n"
35 35
  "1\n"
36 36
  "2\n"
37 37
  "3\n"
38 38
  "4\n"
39 39
  "5\n"
40 40
  "6\n"
41 41
  "7\n"
42 42
  "8\n"
43 43
  "9\n"
44 44
  "@arcs\n"
45 45
  "    label capacity\n"
46 46
  "0 1 0     20\n"
47 47
  "0 2 1     0\n"
48 48
  "1 1 2     3\n"
49 49
  "1 2 3     8\n"
50 50
  "1 3 4     8\n"
51 51
  "2 5 5     5\n"
52 52
  "3 2 6     5\n"
53 53
  "3 5 7     5\n"
54 54
  "3 6 8     5\n"
55 55
  "4 3 9     3\n"
56 56
  "5 7 10    3\n"
57 57
  "5 6 11    10\n"
58 58
  "5 8 12    10\n"
59 59
  "6 8 13    8\n"
60 60
  "8 9 14    20\n"
61 61
  "8 1 15    5\n"
62 62
  "9 5 16    5\n"
63 63
  "@attributes\n"
64 64
  "source 1\n"
65 65
  "target 8\n";
66 66

	
67 67
void checkPreflowCompile()
68 68
{
69 69
  typedef int VType;
70 70
  typedef concepts::Digraph Digraph;
71 71

	
72 72
  typedef Digraph::Node Node;
73 73
  typedef Digraph::Arc Arc;
74 74
  typedef concepts::ReadMap<Arc,VType> CapMap;
75 75
  typedef concepts::ReadWriteMap<Arc,VType> FlowMap;
76 76
  typedef concepts::WriteMap<Node,bool> CutMap;
77 77

	
78 78
  typedef Elevator<Digraph, Digraph::Node> Elev;
79 79
  typedef LinkedElevator<Digraph, Digraph::Node> LinkedElev;
80 80

	
81 81
  Digraph g;
82 82
  Node n;
83 83
  Arc e;
84 84
  CapMap cap;
85 85
  FlowMap flow;
86 86
  CutMap cut;
87 87
  VType v;
88 88
  bool b;
89 89

	
90 90
  typedef Preflow<Digraph, CapMap>
91 91
            ::SetFlowMap<FlowMap>
92 92
            ::SetElevator<Elev>
93 93
            ::SetStandardElevator<LinkedElev>
94 94
            ::Create PreflowType;
95 95
  PreflowType preflow_test(g, cap, n, n);
96 96
  const PreflowType& const_preflow_test = preflow_test;
97 97

	
98 98
  const PreflowType::Elevator& elev = const_preflow_test.elevator();
99 99
  preflow_test.elevator(const_cast<PreflowType::Elevator&>(elev));
100 100
  PreflowType::Tolerance tol = const_preflow_test.tolerance();
101 101
  preflow_test.tolerance(tol);
102 102

	
103 103
  preflow_test
104 104
    .capacityMap(cap)
105 105
    .flowMap(flow)
106 106
    .source(n)
107 107
    .target(n);
108 108

	
109 109
  preflow_test.init();
110 110
  preflow_test.init(cap);
111 111
  preflow_test.startFirstPhase();
112 112
  preflow_test.startSecondPhase();
113 113
  preflow_test.run();
114 114
  preflow_test.runMinCut();
115 115

	
116 116
  v = const_preflow_test.flowValue();
117 117
  v = const_preflow_test.flow(e);
118 118
  const FlowMap& fm = const_preflow_test.flowMap();
119 119
  b = const_preflow_test.minCut(n);
120 120
  const_preflow_test.minCutMap(cut);
121 121

	
122 122
  ignore_unused_variable_warning(fm);
123 123
}
124 124

	
125 125
int cutValue (const SmartDigraph& g,
126 126
              const SmartDigraph::NodeMap<bool>& cut,
127 127
              const SmartDigraph::ArcMap<int>& cap) {
128 128

	
129 129
  int c=0;
130 130
  for(SmartDigraph::ArcIt e(g); e!=INVALID; ++e) {
131 131
    if (cut[g.source(e)] && !cut[g.target(e)]) c+=cap[e];
132 132
  }
133 133
  return c;
134 134
}
135 135

	
136 136
bool checkFlow(const SmartDigraph& g,
137 137
               const SmartDigraph::ArcMap<int>& flow,
138 138
               const SmartDigraph::ArcMap<int>& cap,
139 139
               SmartDigraph::Node s, SmartDigraph::Node t) {
140 140

	
141 141
  for (SmartDigraph::ArcIt e(g); e != INVALID; ++e) {
142 142
    if (flow[e] < 0 || flow[e] > cap[e]) return false;
143 143
  }
144 144

	
145 145
  for (SmartDigraph::NodeIt n(g); n != INVALID; ++n) {
146 146
    if (n == s || n == t) continue;
147 147
    int sum = 0;
148 148
    for (SmartDigraph::OutArcIt e(g, n); e != INVALID; ++e) {
149 149
      sum += flow[e];
150 150
    }
151 151
    for (SmartDigraph::InArcIt e(g, n); e != INVALID; ++e) {
152 152
      sum -= flow[e];
153 153
    }
154 154
    if (sum != 0) return false;
155 155
  }
156 156
  return true;
157 157
}
158 158

	
159 159
void initFlowTest()
160 160
{
161 161
  DIGRAPH_TYPEDEFS(SmartDigraph);
162
  
162

	
163 163
  SmartDigraph g;
164 164
  SmartDigraph::ArcMap<int> cap(g),iflow(g);
165 165
  Node s=g.addNode(); Node t=g.addNode();
166 166
  Node n1=g.addNode(); Node n2=g.addNode();
167 167
  Arc a;
168 168
  a=g.addArc(s,n1); cap[a]=20; iflow[a]=20;
169 169
  a=g.addArc(n1,n2); cap[a]=10; iflow[a]=0;
170 170
  a=g.addArc(n2,t); cap[a]=20; iflow[a]=0;
171 171

	
172 172
  Preflow<SmartDigraph> pre(g,cap,s,t);
173 173
  pre.init(iflow);
174 174
  pre.startFirstPhase();
175 175
  check(pre.flowValue() == 10, "The incorrect max flow value.");
176 176
  check(pre.minCut(s), "Wrong min cut (Node s).");
177 177
  check(pre.minCut(n1), "Wrong min cut (Node n1).");
178 178
  check(!pre.minCut(n2), "Wrong min cut (Node n2).");
179 179
  check(!pre.minCut(t), "Wrong min cut (Node t).");
180 180
}
181 181

	
182 182

	
183 183
int main() {
184 184

	
185 185
  typedef SmartDigraph Digraph;
186 186

	
187 187
  typedef Digraph::Node Node;
188 188
  typedef Digraph::NodeIt NodeIt;
189 189
  typedef Digraph::ArcIt ArcIt;
190 190
  typedef Digraph::ArcMap<int> CapMap;
191 191
  typedef Digraph::ArcMap<int> FlowMap;
192 192
  typedef Digraph::NodeMap<bool> CutMap;
193 193

	
194 194
  typedef Preflow<Digraph, CapMap> PType;
195 195

	
196 196
  Digraph g;
197 197
  Node s, t;
198 198
  CapMap cap(g);
199 199
  std::istringstream input(test_lgf);
200 200
  DigraphReader<Digraph>(g,input).
201 201
    arcMap("capacity", cap).
202 202
    node("source",s).
203 203
    node("target",t).
204 204
    run();
205 205

	
206 206
  PType preflow_test(g, cap, s, t);
207 207
  preflow_test.run();
208 208

	
209 209
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
210 210
        "The flow is not feasible.");
211 211

	
212 212
  CutMap min_cut(g);
213 213
  preflow_test.minCutMap(min_cut);
214 214
  int min_cut_value=cutValue(g,min_cut,cap);
215 215

	
216 216
  check(preflow_test.flowValue() == min_cut_value,
217 217
        "The max flow value is not equal to the three min cut values.");
218 218

	
219 219
  FlowMap flow(g);
220 220
  for(ArcIt e(g); e!=INVALID; ++e) flow[e] = preflow_test.flowMap()[e];
221 221

	
222 222
  int flow_value=preflow_test.flowValue();
223 223

	
224 224
  for(ArcIt e(g); e!=INVALID; ++e) cap[e]=2*cap[e];
225 225
  preflow_test.init(flow);
226 226
  preflow_test.startFirstPhase();
227 227

	
228 228
  CutMap min_cut1(g);
229 229
  preflow_test.minCutMap(min_cut1);
230 230
  min_cut_value=cutValue(g,min_cut1,cap);
231 231

	
232 232
  check(preflow_test.flowValue() == min_cut_value &&
233 233
        min_cut_value == 2*flow_value,
234 234
        "The max flow value or the min cut value is wrong.");
235 235

	
236 236
  preflow_test.startSecondPhase();
237 237

	
238 238
  check(checkFlow(g, preflow_test.flowMap(), cap, s, t),
239 239
        "The flow is not feasible.");
240 240

	
241 241
  CutMap min_cut2(g);
242 242
  preflow_test.minCutMap(min_cut2);
243 243
  min_cut_value=cutValue(g,min_cut2,cap);
244 244

	
245 245
  check(preflow_test.flowValue() == min_cut_value &&
246 246
        min_cut_value == 2*flow_value,
247 247
        "The max flow value or the three min cut values were not doubled");
248 248

	
249 249

	
250 250
  preflow_test.flowMap(flow);
251 251

	
252 252
  NodeIt tmp1(g,s);
253 253
  ++tmp1;
254 254
  if ( tmp1 != INVALID ) s=tmp1;
255 255

	
256 256
  NodeIt tmp2(g,t);
257 257
  ++tmp2;
258 258
  if ( tmp2 != INVALID ) t=tmp2;
259 259

	
260 260
  preflow_test.source(s);
261 261
  preflow_test.target(t);
262 262

	
263 263
  preflow_test.run();
264 264

	
265 265
  CutMap min_cut3(g);
266 266
  preflow_test.minCutMap(min_cut3);
267 267
  min_cut_value=cutValue(g,min_cut3,cap);
268 268

	
269 269

	
270 270
  check(preflow_test.flowValue() == min_cut_value,
271 271
        "The max flow value or the three min cut values are incorrect.");
272 272

	
273 273
  initFlowTest();
274
  
274

	
275 275
  return 0;
276 276
}
0 comments (0 inline)