↑ Collapse diff ↑
Ignore white space 6 line context
1
SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
2

	
3
FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
4
  PATHS ${COIN_ROOT_DIR}/include)
5

	
6
FIND_LIBRARY(COIN_CBC_LIBRARY libCbc
7
  PATHS ${COIN_ROOT_DIR}/lib)
8
FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY libCbcSolver
9
  PATHS ${COIN_ROOT_DIR}/lib)
10
FIND_LIBRARY(COIN_CGL_LIBRARY libCgl
11
  PATHS ${COIN_ROOT_DIR}/lib)
12
FIND_LIBRARY(COIN_CLP_LIBRARY libClp
13
  PATHS ${COIN_ROOT_DIR}/lib)
14
FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY libCoinUtils
15
  PATHS ${COIN_ROOT_DIR}/lib)
16
FIND_LIBRARY(COIN_OSI_LIBRARY libOsi
17
  PATHS ${COIN_ROOT_DIR}/lib)
18
FIND_LIBRARY(COIN_OSI_CBC_LIBRARY libOsiCbc
19
  PATHS ${COIN_ROOT_DIR}/lib)
20
FIND_LIBRARY(COIN_OSI_CLP_LIBRARY libOsiClp
21
  PATHS ${COIN_ROOT_DIR}/lib)
22
FIND_LIBRARY(COIN_OSI_VOL_LIBRARY libOsiVol
23
  PATHS ${COIN_ROOT_DIR}/lib)
24
FIND_LIBRARY(COIN_VOL_LIBRARY libVol
25
  PATHS ${COIN_ROOT_DIR}/lib)
26

	
27
INCLUDE(FindPackageHandleStandardArgs)
28
FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
29
  COIN_INCLUDE_DIR
30
  COIN_CBC_LIBRARY
31
  COIN_CBC_SOLVER_LIBRARY
32
  COIN_CGL_LIBRARY
33
  COIN_CLP_LIBRARY
34
  COIN_COIN_UTILS_LIBRARY
35
  COIN_OSI_LIBRARY
36
  COIN_OSI_CBC_LIBRARY
37
  COIN_OSI_CLP_LIBRARY
38
  COIN_OSI_VOL_LIBRARY
39
  COIN_VOL_LIBRARY
40
)
41

	
42
IF(COIN_FOUND)
43
  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
44
  SET(COIN_LIBRARIES "${COIN_CBC_LIBRARY};${COIN_CBC_SOLVER_LIBRARY};${COIN_CGL_LIBRARY};${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY};${COIN_OSI_LIBRARY};${COIN_OSI_CBC_LIBRARY};${COIN_OSI_CLP_LIBRARY};${COIN_OSI_VOL_LIBRARY};${COIN_VOL_LIBRARY}")
45
  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
46
  SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES})
47
ENDIF(COIN_FOUND)
48

	
49
MARK_AS_ADVANCED(
50
  COIN_INCLUDE_DIR
51
  COIN_CBC_LIBRARY
52
  COIN_CBC_SOLVER_LIBRARY
53
  COIN_CGL_LIBRARY
54
  COIN_CLP_LIBRARY
55
  COIN_COIN_UTILS_LIBRARY
56
  COIN_OSI_LIBRARY
57
  COIN_OSI_CBC_LIBRARY
58
  COIN_OSI_CLP_LIBRARY
59
  COIN_OSI_VOL_LIBRARY
60
  COIN_VOL_LIBRARY
61
)
62

	
63
IF(COIN_FOUND)
64
  SET(HAVE_LP TRUE)
65
  SET(HAVE_MIP TRUE)
66
  SET(HAVE_CLP TRUE)
67
  SET(HAVE_CBC TRUE)
68
ENDIF(COIN_FOUND)
Ignore white space 6 line context
1
FIND_PATH(CPLEX_INCLUDE_DIR
2
  ilcplex/cplex.h
3
  PATHS "C:/ILOG/CPLEX91/include")
4

	
5
FIND_LIBRARY(CPLEX_LIBRARY
6
  NAMES cplex91
7
  PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda")
8

	
9
INCLUDE(FindPackageHandleStandardArgs)
10
FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
11

	
12
FIND_PATH(CPLEX_BIN_DIR
13
  cplex91.dll
14
  PATHS "C:/ILOG/CPLEX91/bin/x86_win32")
15

	
16
IF(CPLEX_FOUND)
17
  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
18
  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
19
ENDIF(CPLEX_FOUND)
20

	
21
MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
22

	
23
IF(CPLEX_FOUND)
24
  SET(HAVE_LP TRUE)
25
  SET(HAVE_MIP TRUE)
26
  SET(HAVE_CPLEX TRUE)
27
ENDIF(CPLEX_FOUND)
Ignore white space 6 line context
1 1
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
2 2

	
3 3
IF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
4 4
  INCLUDE(${CMAKE_SOURCE_DIR}/cmake/version.cmake)
5 5
ELSE(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
6 6
  SET(PROJECT_NAME "LEMON")
7 7
  SET(PROJECT_VERSION "hg-tip" CACHE STRING "LEMON version string.")
8 8
ENDIF(EXISTS ${CMAKE_SOURCE_DIR}/cmake/version.cmake)
9 9

	
10 10
PROJECT(${PROJECT_NAME})
11 11

	
12 12
SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
13 13

	
14 14
INCLUDE(FindDoxygen)
15 15
INCLUDE(FindGhostscript)
16 16
FIND_PACKAGE(GLPK 4.33)
17
FIND_PACKAGE(CPLEX)
18
FIND_PACKAGE(COIN)
17 19

	
18 20
ADD_DEFINITIONS(-DHAVE_CONFIG_H)
19 21

	
20 22
IF(MSVC)
21 23
  SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4250 /wd4355 /wd4800 /wd4996")
22 24
# Suppressed warnings:
23 25
# C4250: 'class1' : inherits 'class2::member' via dominance
24 26
# C4355: 'this' : used in base member initializer list
25 27
# C4800: 'type' : forcing value to bool 'true' or 'false' (performance warning)
26 28
# C4996: 'function': was declared deprecated
27 29
ENDIF(MSVC)
28 30

	
29
IF(GLPK_FOUND)
30
  SET(HAVE_LP TRUE)
31
  SET(HAVE_MIP TRUE)
32
  SET(HAVE_GLPK TRUE)
33
ENDIF(GLPK_FOUND)
34

	
35 31
INCLUDE(CheckTypeSize)
36 32
CHECK_TYPE_SIZE("long long" LONG_LONG)
37 33

	
38 34
ENABLE_TESTING()
39 35

	
40 36
ADD_SUBDIRECTORY(lemon)
41 37
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
42 38
  ADD_SUBDIRECTORY(demo)
43 39
  ADD_SUBDIRECTORY(tools)
44 40
  ADD_SUBDIRECTORY(doc)
45 41
  ADD_SUBDIRECTORY(test)
46 42
ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
47 43

	
48 44
IF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
49 45
  IF(WIN32)
50 46
    SET(CPACK_PACKAGE_NAME ${PROJECT_NAME})
51 47
    SET(CPACK_PACKAGE_VENDOR "EGRES")
52 48
    SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
53 49
      "LEMON - Library of Efficient Models and Optimization in Networks")
54 50
    SET(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
55 51

	
56 52
    SET(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
57 53

	
58 54
    SET(CPACK_PACKAGE_INSTALL_DIRECTORY
59 55
      "${PROJECT_NAME} ${PROJECT_VERSION}")
60 56
    SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY
61 57
      "${PROJECT_NAME} ${PROJECT_VERSION}")
62 58

	
63 59
    SET(CPACK_COMPONENTS_ALL headers library html_documentation bin)
64 60

	
65 61
    SET(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "C++ headers")
66 62
    SET(CPACK_COMPONENT_LIBRARY_DISPLAY_NAME "Dynamic-link library")
67 63
    SET(CPACK_COMPONENT_BIN_DISPLAY_NAME "Command line utilities")
68 64
    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DISPLAY_NAME "HTML documentation")
69 65

	
70 66
    SET(CPACK_COMPONENT_HEADERS_DESCRIPTION
71 67
      "C++ header files")
72 68
    SET(CPACK_COMPONENT_LIBRARY_DESCRIPTION
73 69
      "DLL and import library")
74 70
    SET(CPACK_COMPONENT_BIN_DESCRIPTION
75 71
      "Command line utilities")
76 72
    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_DESCRIPTION
77 73
      "Doxygen generated documentation")
78 74

	
79 75
    SET(CPACK_COMPONENT_HEADERS_DEPENDS library)
80 76

	
81 77
    SET(CPACK_COMPONENT_HEADERS_GROUP "Development")
82 78
    SET(CPACK_COMPONENT_LIBRARY_GROUP "Development")
83 79
    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_GROUP "Documentation")
84 80

	
85 81
    SET(CPACK_COMPONENT_GROUP_DEVELOPMENT_DESCRIPTION
86 82
      "Components needed to develop software using LEMON")
87 83
    SET(CPACK_COMPONENT_GROUP_DOCUMENTATION_DESCRIPTION
88 84
      "Documentation of LEMON")
89 85

	
90 86
    SET(CPACK_ALL_INSTALL_TYPES Full Developer)
91 87

	
92 88
    SET(CPACK_COMPONENT_HEADERS_INSTALL_TYPES Developer Full)
93 89
    SET(CPACK_COMPONENT_LIBRARY_INSTALL_TYPES Developer Full)
94 90
    SET(CPACK_COMPONENT_HTML_DOCUMENTATION_INSTALL_TYPES Full)
95 91

	
96 92
    SET(CPACK_GENERATOR "NSIS")
97 93
    SET(CPACK_NSIS_MUI_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis/lemon.ico")
98 94
    SET(CPACK_NSIS_MUI_UNIICON "${PROJECT_SOURCE_DIR}/cmake/nsis/uninstall.ico")
99 95
    #SET(CPACK_PACKAGE_ICON "${PROJECT_SOURCE_DIR}/cmake/nsis\\\\installer.bmp")
100 96
    SET(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\lemon.ico")
101 97
    SET(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
102 98
    SET(CPACK_NSIS_HELP_LINK "http:\\\\\\\\lemon.cs.elte.hu")
103 99
    SET(CPACK_NSIS_URL_INFO_ABOUT "http:\\\\\\\\lemon.cs.elte.hu")
104 100
    SET(CPACK_NSIS_CONTACT "lemon-user@lemon.cs.elte.hu")
105 101
    SET(CPACK_NSIS_CREATE_ICONS_EXTRA "
106 102
      CreateShortCut \\\"$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Documentation.lnk\\\" \\\"$INSTDIR\\\\share\\\\doc\\\\index.html\\\"
107 103
      ")
108 104
    SET(CPACK_NSIS_DELETE_ICONS_EXTRA "
109 105
      !insertmacro MUI_STARTMENU_GETFOLDER Application $MUI_TEMP
110 106
      Delete \\\"$SMPROGRAMS\\\\$MUI_TEMP\\\\Documentation.lnk\\\"
111 107
      ")
112 108

	
113 109
    INCLUDE(CPack)
114 110
  ENDIF(WIN32)
115 111
ENDIF(${CMAKE_SOURCE_DIR} STREQUAL ${PROJECT_SOURCE_DIR})
Ignore white space 256 line context
1 1
SET(GLPK_REGKEY "[HKEY_LOCAL_MACHINE\\SOFTWARE\\GnuWin32\\Glpk;InstallPath]")
2 2
GET_FILENAME_COMPONENT(GLPK_ROOT_PATH ${GLPK_REGKEY} ABSOLUTE)
3 3

	
4 4
FIND_PATH(GLPK_INCLUDE_DIR
5 5
  glpk.h
6 6
  PATHS ${GLPK_REGKEY}/include)
7 7

	
8 8
FIND_LIBRARY(GLPK_LIBRARY
9 9
  NAMES glpk
10 10
  PATHS ${GLPK_REGKEY}/lib)
11 11

	
12 12
INCLUDE(FindPackageHandleStandardArgs)
13 13
FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR)
14 14

	
15 15
IF(GLPK_FOUND)
16
  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
16 17
  SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
17 18
  SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
18 19
ENDIF(GLPK_FOUND)
19 20

	
20 21
MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
22

	
23
IF(GLPK_FOUND)
24
  SET(HAVE_LP TRUE)
25
  SET(HAVE_MIP TRUE)
26
  SET(HAVE_GLPK TRUE)
27
ENDIF(GLPK_FOUND)
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6 6
CONFIGURE_FILE(
7 7
  ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
8 8
  ${CMAKE_CURRENT_BINARY_DIR}/config.h
9 9
)
10 10

	
11 11
SET(LEMON_SOURCES
12 12
  arg_parser.cc
13 13
  base.cc
14 14
  color.cc
15 15
  lp_base.cc
16 16
  lp_skeleton.cc
17 17
  random.cc
18 18
  bits/windows.cc
19 19
)
20 20

	
21 21
IF(HAVE_GLPK)
22 22
  SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
23
  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
23
  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
24 24
  IF(WIN32)
25 25
    INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
26 26
    INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
27 27
    INSTALL(FILES ${GLPK_BIN_DIR}/zlib1.dll DESTINATION bin)
28 28
  ENDIF(WIN32)
29 29
ENDIF(HAVE_GLPK)
30 30

	
31
IF(HAVE_CPLEX)
32
  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
33
  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
34
ENDIF(HAVE_CPLEX)
35

	
36
IF(HAVE_CLP)
37
  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
38
  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
39
ENDIF(HAVE_CLP)
40

	
41
IF(HAVE_CBC)
42
  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
43
  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
44
ENDIF(HAVE_CBC)
45

	
31 46
ADD_LIBRARY(lemon ${LEMON_SOURCES})
32 47

	
33 48
INSTALL(
34 49
  TARGETS lemon
35 50
  ARCHIVE DESTINATION lib
36 51
  COMPONENT library)
37 52

	
38 53
INSTALL(
39 54
  DIRECTORY . bits concepts
40 55
  DESTINATION include/lemon
41 56
  COMPONENT headers
42 57
  FILES_MATCHING PATTERN "*.h")
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-2009
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_CIRCULATION_H
20 20
#define LEMON_CIRCULATION_H
21 21

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

	
25 26
///\ingroup max_flow
26 27
///\file
27 28
///\brief Push-relabel algorithm for finding a feasible circulation.
28 29
///
29 30
namespace lemon {
30 31

	
31 32
  /// \brief Default traits class of Circulation class.
32 33
  ///
33 34
  /// Default traits class of Circulation class.
34 35
  ///
35 36
  /// \tparam GR Type of the digraph the algorithm runs on.
36 37
  /// \tparam LM The type of the lower bound map.
37 38
  /// \tparam UM The type of the upper bound (capacity) map.
38 39
  /// \tparam SM The type of the supply map.
39 40
  template <typename GR, typename LM,
40 41
            typename UM, typename SM>
41 42
  struct CirculationDefaultTraits {
42 43

	
43 44
    /// \brief The type of the digraph the algorithm runs on.
44 45
    typedef GR Digraph;
45 46

	
46 47
    /// \brief The type of the lower bound map.
47 48
    ///
48 49
    /// The type of the map that stores the lower bounds on the arcs.
49 50
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
50 51
    typedef LM LowerMap;
51 52

	
52 53
    /// \brief The type of the upper bound (capacity) map.
53 54
    ///
54 55
    /// The type of the map that stores the upper bounds (capacities)
55 56
    /// on the arcs.
56 57
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
57 58
    typedef UM UpperMap;
58 59

	
59 60
    /// \brief The type of supply map.
60 61
    ///
61 62
    /// The type of the map that stores the signed supply values of the 
62 63
    /// nodes. 
63 64
    /// It must conform to the \ref concepts::ReadMap "ReadMap" concept.
64 65
    typedef SM SupplyMap;
65 66

	
66 67
    /// \brief The type of the flow values.
67 68
    typedef typename SupplyMap::Value Flow;
68 69

	
69 70
    /// \brief The type of the map that stores the flow values.
70 71
    ///
71 72
    /// The type of the map that stores the flow values.
72 73
    /// It must conform to the \ref concepts::ReadWriteMap "ReadWriteMap"
73 74
    /// concept.
74 75
    typedef typename Digraph::template ArcMap<Flow> FlowMap;
75 76

	
76 77
    /// \brief Instantiates a FlowMap.
77 78
    ///
78 79
    /// This function instantiates a \ref FlowMap.
79 80
    /// \param digraph The digraph for which we would like to define
80 81
    /// the flow map.
81 82
    static FlowMap* createFlowMap(const Digraph& digraph) {
82 83
      return new FlowMap(digraph);
83 84
    }
84 85

	
85 86
    /// \brief The elevator type used by the algorithm.
86 87
    ///
87 88
    /// The elevator type used by the algorithm.
88 89
    ///
89 90
    /// \sa Elevator
90 91
    /// \sa LinkedElevator
91 92
    typedef lemon::Elevator<Digraph, typename Digraph::Node> Elevator;
92 93

	
93 94
    /// \brief Instantiates an Elevator.
94 95
    ///
95 96
    /// This function instantiates an \ref Elevator.
96 97
    /// \param digraph The digraph for which we would like to define
97 98
    /// the elevator.
98 99
    /// \param max_level The maximum level of the elevator.
99 100
    static Elevator* createElevator(const Digraph& digraph, int max_level) {
100 101
      return new Elevator(digraph, max_level);
101 102
    }
102 103

	
103 104
    /// \brief The tolerance used by the algorithm
104 105
    ///
105 106
    /// The tolerance used by the algorithm to handle inexact computation.
106 107
    typedef lemon::Tolerance<Flow> Tolerance;
107 108

	
108 109
  };
109 110

	
110 111
  /**
111 112
     \brief Push-relabel algorithm for the network circulation problem.
112 113

	
113 114
     \ingroup max_flow
114 115
     This class implements a push-relabel algorithm for the \e network
115 116
     \e circulation problem.
116 117
     It is to find a feasible circulation when lower and upper bounds
117 118
     are given for the flow values on the arcs and lower bounds are
118 119
     given for the difference between the outgoing and incoming flow
119 120
     at the nodes.
120 121

	
121 122
     The exact formulation of this problem is the following.
122
     Let \f$G=(V,A)\f$ be a digraph,
123
     \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and
124
     upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$
123
     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
124
     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
125
     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
125 126
     holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
126 127
     denotes the signed supply values of the nodes.
127 128
     If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
128 129
     supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
129 130
     \f$-sup(u)\f$ demand.
130
     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$
131
     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
131 132
     solution of the following problem.
132 133

	
133 134
     \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
134 135
     \geq sup(u) \quad \forall u\in V, \f]
135 136
     \f[ lower(uv) \leq f(uv) \leq upper(uv) \quad \forall uv\in A. \f]
136 137
     
137 138
     The sum of the supply values, i.e. \f$\sum_{u\in V} sup(u)\f$ must be
138 139
     zero or negative in order to have a feasible solution (since the sum
139 140
     of the expressions on the left-hand side of the inequalities is zero).
140 141
     It means that the total demand must be greater or equal to the total
141 142
     supply and all the supplies have to be carried out from the supply nodes,
142 143
     but there could be demands that are not satisfied.
143 144
     If \f$\sum_{u\in V} sup(u)\f$ is zero, then all the supply/demand
144 145
     constraints have to be satisfied with equality, i.e. all demands
145 146
     have to be satisfied and all supplies have to be used.
146 147
     
147 148
     If you need the opposite inequalities in the supply/demand constraints
148 149
     (i.e. the total demand is less than the total supply and all the demands
149 150
     have to be satisfied while there could be supplies that are not used),
150 151
     then you could easily transform the problem to the above form by reversing
151 152
     the direction of the arcs and taking the negative of the supply values
152 153
     (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
153 154

	
155
     This algorithm either calculates a feasible circulation, or provides
156
     a \ref barrier() "barrier", which prooves that a feasible soultion
157
     cannot exist.
158

	
154 159
     Note that this algorithm also provides a feasible solution for the
155 160
     \ref min_cost_flow "minimum cost flow problem".
156 161

	
157 162
     \tparam GR The type of the digraph the algorithm runs on.
158 163
     \tparam LM The type of the lower bound map. The default
159 164
     map type is \ref concepts::Digraph::ArcMap "GR::ArcMap<int>".
160 165
     \tparam UM The type of the upper bound (capacity) map.
161 166
     The default map type is \c LM.
162 167
     \tparam SM The type of the supply map. The default map type is
163 168
     \ref concepts::Digraph::NodeMap "GR::NodeMap<UM::Value>".
164 169
  */
165 170
#ifdef DOXYGEN
166 171
template< typename GR,
167 172
          typename LM,
168 173
          typename UM,
169 174
          typename SM,
170 175
          typename TR >
171 176
#else
172 177
template< typename GR,
173 178
          typename LM = typename GR::template ArcMap<int>,
174 179
          typename UM = LM,
175 180
          typename SM = typename GR::template NodeMap<typename UM::Value>,
176 181
          typename TR = CirculationDefaultTraits<GR, LM, UM, SM> >
177 182
#endif
178 183
  class Circulation {
179 184
  public:
180 185

	
181 186
    ///The \ref CirculationDefaultTraits "traits class" of the algorithm.
182 187
    typedef TR Traits;
183 188
    ///The type of the digraph the algorithm runs on.
184 189
    typedef typename Traits::Digraph Digraph;
185 190
    ///The type of the flow values.
186 191
    typedef typename Traits::Flow Flow;
187 192

	
188 193
    ///The type of the lower bound map.
189 194
    typedef typename Traits::LowerMap LowerMap;
190 195
    ///The type of the upper bound (capacity) map.
191 196
    typedef typename Traits::UpperMap UpperMap;
192 197
    ///The type of the supply map.
193 198
    typedef typename Traits::SupplyMap SupplyMap;
194 199
    ///The type of the flow map.
195 200
    typedef typename Traits::FlowMap FlowMap;
196 201

	
197 202
    ///The type of the elevator.
198 203
    typedef typename Traits::Elevator Elevator;
199 204
    ///The type of the tolerance.
200 205
    typedef typename Traits::Tolerance Tolerance;
201 206

	
202 207
  private:
203 208

	
204 209
    TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
205 210

	
206 211
    const Digraph &_g;
207 212
    int _node_num;
208 213

	
209 214
    const LowerMap *_lo;
210 215
    const UpperMap *_up;
211 216
    const SupplyMap *_supply;
212 217

	
213 218
    FlowMap *_flow;
214 219
    bool _local_flow;
215 220

	
216 221
    Elevator* _level;
217 222
    bool _local_level;
218 223

	
219 224
    typedef typename Digraph::template NodeMap<Flow> ExcessMap;
220 225
    ExcessMap* _excess;
221 226

	
222 227
    Tolerance _tol;
223 228
    int _el;
224 229

	
225 230
  public:
226 231

	
227 232
    typedef Circulation Create;
228 233

	
229 234
    ///\name Named Template Parameters
230 235

	
231 236
    ///@{
232 237

	
233 238
    template <typename T>
234 239
    struct SetFlowMapTraits : public Traits {
235 240
      typedef T FlowMap;
236 241
      static FlowMap *createFlowMap(const Digraph&) {
237 242
        LEMON_ASSERT(false, "FlowMap is not initialized");
238 243
        return 0; // ignore warnings
239 244
      }
240 245
    };
241 246

	
242 247
    /// \brief \ref named-templ-param "Named parameter" for setting
243 248
    /// FlowMap type
244 249
    ///
245 250
    /// \ref named-templ-param "Named parameter" for setting FlowMap
246 251
    /// type.
247 252
    template <typename T>
248 253
    struct SetFlowMap
249 254
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
250 255
                           SetFlowMapTraits<T> > {
251 256
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
252 257
                          SetFlowMapTraits<T> > Create;
253 258
    };
254 259

	
255 260
    template <typename T>
256 261
    struct SetElevatorTraits : public Traits {
257 262
      typedef T Elevator;
258 263
      static Elevator *createElevator(const Digraph&, int) {
259 264
        LEMON_ASSERT(false, "Elevator is not initialized");
260 265
        return 0; // ignore warnings
261 266
      }
262 267
    };
263 268

	
264 269
    /// \brief \ref named-templ-param "Named parameter" for setting
265 270
    /// Elevator type
266 271
    ///
267 272
    /// \ref named-templ-param "Named parameter" for setting Elevator
268 273
    /// type. If this named parameter is used, then an external
269 274
    /// elevator object must be passed to the algorithm using the
270 275
    /// \ref elevator(Elevator&) "elevator()" function before calling
271 276
    /// \ref run() or \ref init().
272 277
    /// \sa SetStandardElevator
273 278
    template <typename T>
274 279
    struct SetElevator
275 280
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
276 281
                           SetElevatorTraits<T> > {
277 282
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
278 283
                          SetElevatorTraits<T> > Create;
279 284
    };
280 285

	
281 286
    template <typename T>
282 287
    struct SetStandardElevatorTraits : public Traits {
283 288
      typedef T Elevator;
284 289
      static Elevator *createElevator(const Digraph& digraph, int max_level) {
285 290
        return new Elevator(digraph, max_level);
286 291
      }
287 292
    };
288 293

	
289 294
    /// \brief \ref named-templ-param "Named parameter" for setting
290 295
    /// Elevator type with automatic allocation
291 296
    ///
292 297
    /// \ref named-templ-param "Named parameter" for setting Elevator
293 298
    /// type with automatic allocation.
294 299
    /// The Elevator should have standard constructor interface to be
295 300
    /// able to automatically created by the algorithm (i.e. the
296 301
    /// digraph and the maximum level should be passed to it).
297 302
    /// However an external elevator object could also be passed to the
298 303
    /// algorithm with the \ref elevator(Elevator&) "elevator()" function
299 304
    /// before calling \ref run() or \ref init().
300 305
    /// \sa SetElevator
301 306
    template <typename T>
302 307
    struct SetStandardElevator
303 308
      : public Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
304 309
                       SetStandardElevatorTraits<T> > {
305 310
      typedef Circulation<Digraph, LowerMap, UpperMap, SupplyMap,
306 311
                      SetStandardElevatorTraits<T> > Create;
307 312
    };
308 313

	
309 314
    /// @}
310 315

	
311 316
  protected:
312 317

	
313 318
    Circulation() {}
314 319

	
315 320
  public:
316 321

	
317 322
    /// Constructor.
318 323

	
319 324
    /// The constructor of the class.
320 325
    ///
321 326
    /// \param graph The digraph the algorithm runs on.
322 327
    /// \param lower The lower bounds for the flow values on the arcs.
323 328
    /// \param upper The upper bounds (capacities) for the flow values 
324 329
    /// on the arcs.
325 330
    /// \param supply The signed supply values of the nodes.
326 331
    Circulation(const Digraph &graph, const LowerMap &lower,
327 332
                const UpperMap &upper, const SupplyMap &supply)
328 333
      : _g(graph), _lo(&lower), _up(&upper), _supply(&supply),
329 334
        _flow(NULL), _local_flow(false), _level(NULL), _local_level(false),
330 335
        _excess(NULL) {}
331 336

	
332 337
    /// Destructor.
333 338
    ~Circulation() {
334 339
      destroyStructures();
335 340
    }
336 341

	
337 342

	
338 343
  private:
339 344

	
345
    bool checkBoundMaps() {
346
      for (ArcIt e(_g);e!=INVALID;++e) {
347
        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
348
      }
349
      return true;
350
    }
351

	
340 352
    void createStructures() {
341 353
      _node_num = _el = countNodes(_g);
342 354

	
343 355
      if (!_flow) {
344 356
        _flow = Traits::createFlowMap(_g);
345 357
        _local_flow = true;
346 358
      }
347 359
      if (!_level) {
348 360
        _level = Traits::createElevator(_g, _node_num);
349 361
        _local_level = true;
350 362
      }
351 363
      if (!_excess) {
352 364
        _excess = new ExcessMap(_g);
353 365
      }
354 366
    }
355 367

	
356 368
    void destroyStructures() {
357 369
      if (_local_flow) {
358 370
        delete _flow;
359 371
      }
360 372
      if (_local_level) {
361 373
        delete _level;
362 374
      }
363 375
      if (_excess) {
364 376
        delete _excess;
365 377
      }
366 378
    }
367 379

	
368 380
  public:
369 381

	
370 382
    /// Sets the lower bound map.
371 383

	
372 384
    /// Sets the lower bound map.
373 385
    /// \return <tt>(*this)</tt>
374 386
    Circulation& lowerMap(const LowerMap& map) {
375 387
      _lo = &map;
376 388
      return *this;
377 389
    }
378 390

	
379 391
    /// Sets the upper bound (capacity) map.
380 392

	
381 393
    /// Sets the upper bound (capacity) map.
382 394
    /// \return <tt>(*this)</tt>
383
    Circulation& upperMap(const LowerMap& map) {
395
    Circulation& upperMap(const UpperMap& map) {
384 396
      _up = &map;
385 397
      return *this;
386 398
    }
387 399

	
388 400
    /// Sets the supply map.
389 401

	
390 402
    /// Sets the supply map.
391 403
    /// \return <tt>(*this)</tt>
392 404
    Circulation& supplyMap(const SupplyMap& map) {
393 405
      _supply = &map;
394 406
      return *this;
395 407
    }
396 408

	
397 409
    /// \brief Sets the flow map.
398 410
    ///
399 411
    /// Sets the flow map.
400 412
    /// If you don't use this function before calling \ref run() or
401 413
    /// \ref init(), an instance will be allocated automatically.
402 414
    /// The destructor deallocates this automatically allocated map,
403 415
    /// of course.
404 416
    /// \return <tt>(*this)</tt>
405 417
    Circulation& flowMap(FlowMap& map) {
406 418
      if (_local_flow) {
407 419
        delete _flow;
408 420
        _local_flow = false;
409 421
      }
410 422
      _flow = &map;
411 423
      return *this;
412 424
    }
413 425

	
414 426
    /// \brief Sets the elevator used by algorithm.
415 427
    ///
416 428
    /// Sets the elevator used by algorithm.
417 429
    /// If you don't use this function before calling \ref run() or
418 430
    /// \ref init(), an instance will be allocated automatically.
419 431
    /// The destructor deallocates this automatically allocated elevator,
420 432
    /// of course.
421 433
    /// \return <tt>(*this)</tt>
422 434
    Circulation& elevator(Elevator& elevator) {
423 435
      if (_local_level) {
424 436
        delete _level;
425 437
        _local_level = false;
426 438
      }
427 439
      _level = &elevator;
428 440
      return *this;
429 441
    }
430 442

	
431 443
    /// \brief Returns a const reference to the elevator.
432 444
    ///
433 445
    /// Returns a const reference to the elevator.
434 446
    ///
435 447
    /// \pre Either \ref run() or \ref init() must be called before
436 448
    /// using this function.
437 449
    const Elevator& elevator() const {
438 450
      return *_level;
439 451
    }
440 452

	
441 453
    /// \brief Sets the tolerance used by algorithm.
442 454
    ///
443 455
    /// Sets the tolerance used by algorithm.
444 456
    Circulation& tolerance(const Tolerance& tolerance) const {
445 457
      _tol = tolerance;
446 458
      return *this;
447 459
    }
448 460

	
449 461
    /// \brief Returns a const reference to the tolerance.
450 462
    ///
451 463
    /// Returns a const reference to the tolerance.
452 464
    const Tolerance& tolerance() const {
453 465
      return tolerance;
454 466
    }
455 467

	
456 468
    /// \name Execution Control
457 469
    /// The simplest way to execute the algorithm is to call \ref run().\n
458 470
    /// If you need more control on the initial solution or the execution,
459 471
    /// first you have to call one of the \ref init() functions, then
460 472
    /// the \ref start() function.
461 473

	
462 474
    ///@{
463 475

	
464 476
    /// Initializes the internal data structures.
465 477

	
466 478
    /// Initializes the internal data structures and sets all flow values
467 479
    /// to the lower bound.
468 480
    void init()
469 481
    {
482
      LEMON_DEBUG(checkBoundMaps(),
483
        "Upper bounds must be greater or equal to the lower bounds");
484

	
470 485
      createStructures();
471 486

	
472 487
      for(NodeIt n(_g);n!=INVALID;++n) {
473 488
        (*_excess)[n] = (*_supply)[n];
474 489
      }
475 490

	
476 491
      for (ArcIt e(_g);e!=INVALID;++e) {
477 492
        _flow->set(e, (*_lo)[e]);
478 493
        (*_excess)[_g.target(e)] += (*_flow)[e];
479 494
        (*_excess)[_g.source(e)] -= (*_flow)[e];
480 495
      }
481 496

	
482 497
      // global relabeling tested, but in general case it provides
483 498
      // worse performance for random digraphs
484 499
      _level->initStart();
485 500
      for(NodeIt n(_g);n!=INVALID;++n)
486 501
        _level->initAddItem(n);
487 502
      _level->initFinish();
488 503
      for(NodeIt n(_g);n!=INVALID;++n)
489 504
        if(_tol.positive((*_excess)[n]))
490 505
          _level->activate(n);
491 506
    }
492 507

	
493 508
    /// Initializes the internal data structures using a greedy approach.
494 509

	
495 510
    /// Initializes the internal data structures using a greedy approach
496 511
    /// to construct the initial solution.
497 512
    void greedyInit()
498 513
    {
514
      LEMON_DEBUG(checkBoundMaps(),
515
        "Upper bounds must be greater or equal to the lower bounds");
516

	
499 517
      createStructures();
500 518

	
501 519
      for(NodeIt n(_g);n!=INVALID;++n) {
502 520
        (*_excess)[n] = (*_supply)[n];
503 521
      }
504 522

	
505 523
      for (ArcIt e(_g);e!=INVALID;++e) {
506
        if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
524
        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
507 525
          _flow->set(e, (*_up)[e]);
508 526
          (*_excess)[_g.target(e)] += (*_up)[e];
509 527
          (*_excess)[_g.source(e)] -= (*_up)[e];
510
        } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
528
        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
511 529
          _flow->set(e, (*_lo)[e]);
512 530
          (*_excess)[_g.target(e)] += (*_lo)[e];
513 531
          (*_excess)[_g.source(e)] -= (*_lo)[e];
514 532
        } else {
515 533
          Flow fc = -(*_excess)[_g.target(e)];
516 534
          _flow->set(e, fc);
517 535
          (*_excess)[_g.target(e)] = 0;
518 536
          (*_excess)[_g.source(e)] -= fc;
519 537
        }
520 538
      }
521 539

	
522 540
      _level->initStart();
523 541
      for(NodeIt n(_g);n!=INVALID;++n)
524 542
        _level->initAddItem(n);
525 543
      _level->initFinish();
526 544
      for(NodeIt n(_g);n!=INVALID;++n)
527 545
        if(_tol.positive((*_excess)[n]))
528 546
          _level->activate(n);
529 547
    }
530 548

	
531 549
    ///Executes the algorithm
532 550

	
533 551
    ///This function executes the algorithm.
534 552
    ///
535 553
    ///\return \c true if a feasible circulation is found.
536 554
    ///
537 555
    ///\sa barrier()
538 556
    ///\sa barrierMap()
539 557
    bool start()
540 558
    {
541 559

	
542 560
      Node act;
543 561
      Node bact=INVALID;
544 562
      Node last_activated=INVALID;
545 563
      while((act=_level->highestActive())!=INVALID) {
546 564
        int actlevel=(*_level)[act];
547 565
        int mlevel=_node_num;
548 566
        Flow exc=(*_excess)[act];
549 567

	
550 568
        for(OutArcIt e(_g,act);e!=INVALID; ++e) {
551 569
          Node v = _g.target(e);
552 570
          Flow fc=(*_up)[e]-(*_flow)[e];
553 571
          if(!_tol.positive(fc)) continue;
554 572
          if((*_level)[v]<actlevel) {
555 573
            if(!_tol.less(fc, exc)) {
556 574
              _flow->set(e, (*_flow)[e] + exc);
557 575
              (*_excess)[v] += exc;
558 576
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
559 577
                _level->activate(v);
560 578
              (*_excess)[act] = 0;
561 579
              _level->deactivate(act);
562 580
              goto next_l;
563 581
            }
564 582
            else {
565 583
              _flow->set(e, (*_up)[e]);
566 584
              (*_excess)[v] += fc;
567 585
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
568 586
                _level->activate(v);
569 587
              exc-=fc;
570 588
            }
571 589
          }
572 590
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
573 591
        }
574 592
        for(InArcIt e(_g,act);e!=INVALID; ++e) {
575 593
          Node v = _g.source(e);
576 594
          Flow fc=(*_flow)[e]-(*_lo)[e];
577 595
          if(!_tol.positive(fc)) continue;
578 596
          if((*_level)[v]<actlevel) {
579 597
            if(!_tol.less(fc, exc)) {
580 598
              _flow->set(e, (*_flow)[e] - exc);
581 599
              (*_excess)[v] += exc;
582 600
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
583 601
                _level->activate(v);
584 602
              (*_excess)[act] = 0;
585 603
              _level->deactivate(act);
586 604
              goto next_l;
587 605
            }
588 606
            else {
589 607
              _flow->set(e, (*_lo)[e]);
590 608
              (*_excess)[v] += fc;
591 609
              if(!_level->active(v) && _tol.positive((*_excess)[v]))
592 610
                _level->activate(v);
593 611
              exc-=fc;
594 612
            }
595 613
          }
596 614
          else if((*_level)[v]<mlevel) mlevel=(*_level)[v];
597 615
        }
598 616

	
599 617
        (*_excess)[act] = exc;
600 618
        if(!_tol.positive(exc)) _level->deactivate(act);
601 619
        else if(mlevel==_node_num) {
602 620
          _level->liftHighestActiveToTop();
603 621
          _el = _node_num;
604 622
          return false;
605 623
        }
606 624
        else {
607 625
          _level->liftHighestActive(mlevel+1);
608 626
          if(_level->onLevel(actlevel)==0) {
609 627
            _el = actlevel;
610 628
            return false;
611 629
          }
612 630
        }
613 631
      next_l:
614 632
        ;
615 633
      }
616 634
      return true;
617 635
    }
618 636

	
619 637
    /// Runs the algorithm.
620 638

	
621 639
    /// This function runs the algorithm.
622 640
    ///
623 641
    /// \return \c true if a feasible circulation is found.
624 642
    ///
625 643
    /// \note Apart from the return value, c.run() is just a shortcut of
626 644
    /// the following code.
627 645
    /// \code
628 646
    ///   c.greedyInit();
629 647
    ///   c.start();
630 648
    /// \endcode
631 649
    bool run() {
632 650
      greedyInit();
633 651
      return start();
634 652
    }
635 653

	
636 654
    /// @}
637 655

	
638 656
    /// \name Query Functions
639 657
    /// The results of the circulation algorithm can be obtained using
640 658
    /// these functions.\n
641 659
    /// Either \ref run() or \ref start() should be called before
642 660
    /// using them.
643 661

	
644 662
    ///@{
645 663

	
646 664
    /// \brief Returns the flow on the given arc.
647 665
    ///
648 666
    /// Returns the flow on the given arc.
649 667
    ///
650 668
    /// \pre Either \ref run() or \ref init() must be called before
651 669
    /// using this function.
652 670
    Flow flow(const Arc& arc) const {
653 671
      return (*_flow)[arc];
654 672
    }
655 673

	
656 674
    /// \brief Returns a const reference to the flow map.
657 675
    ///
658 676
    /// Returns a const reference to the arc map storing the found flow.
659 677
    ///
660 678
    /// \pre Either \ref run() or \ref init() must be called before
661 679
    /// using this function.
662 680
    const FlowMap& flowMap() const {
663 681
      return *_flow;
664 682
    }
665 683

	
666 684
    /**
667 685
       \brief Returns \c true if the given node is in a barrier.
668 686

	
669 687
       Barrier is a set \e B of nodes for which
670 688

	
671 689
       \f[ \sum_{uv\in A: u\in B} upper(uv) -
672 690
           \sum_{uv\in A: v\in B} lower(uv) < \sum_{v\in B} sup(v) \f]
673 691

	
674 692
       holds. The existence of a set with this property prooves that a
675 693
       feasible circualtion cannot exist.
676 694

	
677 695
       This function returns \c true if the given node is in the found
678 696
       barrier. If a feasible circulation is found, the function
679 697
       gives back \c false for every node.
680 698

	
681 699
       \pre Either \ref run() or \ref init() must be called before
682 700
       using this function.
683 701

	
684 702
       \sa barrierMap()
685 703
       \sa checkBarrier()
686 704
    */
687 705
    bool barrier(const Node& node) const
688 706
    {
689 707
      return (*_level)[node] >= _el;
690 708
    }
691 709

	
692 710
    /// \brief Gives back a barrier.
693 711
    ///
694 712
    /// This function sets \c bar to the characteristic vector of the
695 713
    /// found barrier. \c bar should be a \ref concepts::WriteMap "writable"
696 714
    /// node map with \c bool (or convertible) value type.
697 715
    ///
698 716
    /// If a feasible circulation is found, the function gives back an
699 717
    /// empty set, so \c bar[v] will be \c false for all nodes \c v.
700 718
    ///
701 719
    /// \note This function calls \ref barrier() for each node,
702 720
    /// so it runs in O(n) time.
703 721
    ///
704 722
    /// \pre Either \ref run() or \ref init() must be called before
705 723
    /// using this function.
706 724
    ///
707 725
    /// \sa barrier()
708 726
    /// \sa checkBarrier()
709 727
    template<class BarrierMap>
710 728
    void barrierMap(BarrierMap &bar) const
711 729
    {
712 730
      for(NodeIt n(_g);n!=INVALID;++n)
713 731
        bar.set(n, (*_level)[n] >= _el);
714 732
    }
715 733

	
716 734
    /// @}
717 735

	
718 736
    /// \name Checker Functions
719 737
    /// The feasibility of the results can be checked using
720 738
    /// these functions.\n
721 739
    /// Either \ref run() or \ref start() should be called before
722 740
    /// using them.
723 741

	
724 742
    ///@{
725 743

	
726 744
    ///Check if the found flow is a feasible circulation
727 745

	
728 746
    ///Check if the found flow is a feasible circulation,
729 747
    ///
730 748
    bool checkFlow() const {
731 749
      for(ArcIt e(_g);e!=INVALID;++e)
732 750
        if((*_flow)[e]<(*_lo)[e]||(*_flow)[e]>(*_up)[e]) return false;
733 751
      for(NodeIt n(_g);n!=INVALID;++n)
734 752
        {
735 753
          Flow dif=-(*_supply)[n];
736 754
          for(InArcIt e(_g,n);e!=INVALID;++e) dif-=(*_flow)[e];
737 755
          for(OutArcIt e(_g,n);e!=INVALID;++e) dif+=(*_flow)[e];
738 756
          if(_tol.negative(dif)) return false;
739 757
        }
740 758
      return true;
741 759
    }
742 760

	
743 761
    ///Check whether or not the last execution provides a barrier
744 762

	
745 763
    ///Check whether or not the last execution provides a barrier.
746 764
    ///\sa barrier()
747 765
    ///\sa barrierMap()
748 766
    bool checkBarrier() const
749 767
    {
750 768
      Flow delta=0;
769
      Flow inf_cap = std::numeric_limits<Flow>::has_infinity ?
770
        std::numeric_limits<Flow>::infinity() :
771
        std::numeric_limits<Flow>::max();
751 772
      for(NodeIt n(_g);n!=INVALID;++n)
752 773
        if(barrier(n))
753 774
          delta-=(*_supply)[n];
754 775
      for(ArcIt e(_g);e!=INVALID;++e)
755 776
        {
756 777
          Node s=_g.source(e);
757 778
          Node t=_g.target(e);
758
          if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
779
          if(barrier(s)&&!barrier(t)) {
780
            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
781
            delta+=(*_up)[e];
782
          }
759 783
          else if(barrier(t)&&!barrier(s)) delta-=(*_lo)[e];
760 784
        }
761 785
      return _tol.negative(delta);
762 786
    }
763 787

	
764 788
    /// @}
765 789

	
766 790
  };
767 791

	
768 792
}
769 793

	
770 794
#endif
Ignore white space 6 line context
1 1
#cmakedefine HAVE_LONG_LONG 1
2 2
#cmakedefine HAVE_LP 1
3 3
#cmakedefine HAVE_MIP 1
4 4
#cmakedefine HAVE_GLPK 1
5
#cmakedefine HAVE_CPLEX 1
6
#cmakedefine HAVE_CLP 1
7
#cmakedefine HAVE_CBC 1
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-2009
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_SUURBALLE_H
20 20
#define LEMON_SUURBALLE_H
21 21

	
22 22
///\ingroup shortest_path
23 23
///\file
24 24
///\brief An algorithm for finding arc-disjoint paths between two
25 25
/// nodes having minimum total length.
26 26

	
27 27
#include <vector>
28
#include <limits>
28 29
#include <lemon/bin_heap.h>
29 30
#include <lemon/path.h>
30 31
#include <lemon/list_graph.h>
31 32
#include <lemon/maps.h>
32 33

	
33 34
namespace lemon {
34 35

	
35 36
  /// \addtogroup shortest_path
36 37
  /// @{
37 38

	
38 39
  /// \brief Algorithm for finding arc-disjoint paths between two nodes
39 40
  /// having minimum total length.
40 41
  ///
41 42
  /// \ref lemon::Suurballe "Suurballe" implements an algorithm for
42 43
  /// finding arc-disjoint paths having minimum total length (cost)
43 44
  /// from a given source node to a given target node in a digraph.
44 45
  ///
45
  /// In fact, this implementation is the specialization of the
46
  /// \ref CapacityScaling "successive shortest path" algorithm.
46
  /// Note that this problem is a special case of the \ref min_cost_flow
47
  /// "minimum cost flow problem". This implementation is actually an
48
  /// efficient specialized version of the \ref CapacityScaling
49
  /// "Successive Shortest Path" algorithm directly for this problem.
50
  /// Therefore this class provides query functions for flow values and
51
  /// node potentials (the dual solution) just like the minimum cost flow
52
  /// algorithms.
47 53
  ///
48 54
  /// \tparam GR The digraph type the algorithm runs on.
49
  /// The default value is \c ListDigraph.
50
  /// \tparam LEN The type of the length (cost) map.
51
  /// The default value is <tt>Digraph::ArcMap<int></tt>.
55
  /// \tparam LEN The type of the length map.
56
  /// The default value is <tt>GR::ArcMap<int></tt>.
52 57
  ///
53 58
  /// \warning Length values should be \e non-negative \e integers.
54 59
  ///
55 60
  /// \note For finding node-disjoint paths this algorithm can be used
56
  /// with \ref SplitNodes.
61
  /// along with the \ref SplitNodes adaptor.
57 62
#ifdef DOXYGEN
58 63
  template <typename GR, typename LEN>
59 64
#else
60
  template < typename GR = ListDigraph,
65
  template < typename GR,
61 66
             typename LEN = typename GR::template ArcMap<int> >
62 67
#endif
63 68
  class Suurballe
64 69
  {
65 70
    TEMPLATE_DIGRAPH_TYPEDEFS(GR);
66 71

	
67 72
    typedef ConstMap<Arc, int> ConstArcMap;
68 73
    typedef typename GR::template NodeMap<Arc> PredMap;
69 74

	
70 75
  public:
71 76

	
72 77
    /// The type of the digraph the algorithm runs on.
73 78
    typedef GR Digraph;
74 79
    /// The type of the length map.
75 80
    typedef LEN LengthMap;
76 81
    /// The type of the lengths.
77 82
    typedef typename LengthMap::Value Length;
83
#ifdef DOXYGEN
84
    /// The type of the flow map.
85
    typedef GR::ArcMap<int> FlowMap;
86
    /// The type of the potential map.
87
    typedef GR::NodeMap<Length> PotentialMap;
88
#else
78 89
    /// The type of the flow map.
79 90
    typedef typename Digraph::template ArcMap<int> FlowMap;
80 91
    /// The type of the potential map.
81 92
    typedef typename Digraph::template NodeMap<Length> PotentialMap;
93
#endif
94

	
82 95
    /// The type of the path structures.
83
    typedef SimplePath<Digraph> Path;
96
    typedef SimplePath<GR> Path;
84 97

	
85 98
  private:
86 99

	
87
    /// \brief Special implementation of the Dijkstra algorithm
88
    /// for finding shortest paths in the residual network.
89
    ///
90
    /// \ref ResidualDijkstra is a special implementation of the
91
    /// \ref Dijkstra algorithm for finding shortest paths in the
92
    /// residual network of the digraph with respect to the reduced arc
93
    /// lengths and modifying the node potentials according to the
94
    /// distance of the nodes.
100
    // ResidualDijkstra is a special implementation of the
101
    // Dijkstra algorithm for finding shortest paths in the
102
    // residual network with respect to the reduced arc lengths
103
    // and modifying the node potentials according to the
104
    // distance of the nodes.
95 105
    class ResidualDijkstra
96 106
    {
97 107
      typedef typename Digraph::template NodeMap<int> HeapCrossRef;
98 108
      typedef BinHeap<Length, HeapCrossRef> Heap;
99 109

	
100 110
    private:
101 111

	
102 112
      // The digraph the algorithm runs on
103 113
      const Digraph &_graph;
104 114

	
105 115
      // The main maps
106 116
      const FlowMap &_flow;
107 117
      const LengthMap &_length;
108 118
      PotentialMap &_potential;
109 119

	
110 120
      // The distance map
111 121
      PotentialMap _dist;
112 122
      // The pred arc map
113 123
      PredMap &_pred;
114 124
      // The processed (i.e. permanently labeled) nodes
115 125
      std::vector<Node> _proc_nodes;
116 126

	
117 127
      Node _s;
118 128
      Node _t;
119 129

	
120 130
    public:
121 131

	
122 132
      /// Constructor.
123
      ResidualDijkstra( const Digraph &digraph,
133
      ResidualDijkstra( const Digraph &graph,
124 134
                        const FlowMap &flow,
125 135
                        const LengthMap &length,
126 136
                        PotentialMap &potential,
127 137
                        PredMap &pred,
128 138
                        Node s, Node t ) :
129
        _graph(digraph), _flow(flow), _length(length), _potential(potential),
130
        _dist(digraph), _pred(pred), _s(s), _t(t) {}
139
        _graph(graph), _flow(flow), _length(length), _potential(potential),
140
        _dist(graph), _pred(pred), _s(s), _t(t) {}
131 141

	
132 142
      /// \brief Run the algorithm. It returns \c true if a path is found
133 143
      /// from the source node to the target node.
134 144
      bool run() {
135 145
        HeapCrossRef heap_cross_ref(_graph, Heap::PRE_HEAP);
136 146
        Heap heap(heap_cross_ref);
137 147
        heap.push(_s, 0);
138 148
        _pred[_s] = INVALID;
139 149
        _proc_nodes.clear();
140 150

	
141 151
        // Process nodes
142 152
        while (!heap.empty() && heap.top() != _t) {
143 153
          Node u = heap.top(), v;
144 154
          Length d = heap.prio() + _potential[u], nd;
145 155
          _dist[u] = heap.prio();
146 156
          heap.pop();
147 157
          _proc_nodes.push_back(u);
148 158

	
149 159
          // Traverse outgoing arcs
150 160
          for (OutArcIt e(_graph, u); e != INVALID; ++e) {
151 161
            if (_flow[e] == 0) {
152 162
              v = _graph.target(e);
153 163
              switch(heap.state(v)) {
154 164
              case Heap::PRE_HEAP:
155 165
                heap.push(v, d + _length[e] - _potential[v]);
156 166
                _pred[v] = e;
157 167
                break;
158 168
              case Heap::IN_HEAP:
159 169
                nd = d + _length[e] - _potential[v];
160 170
                if (nd < heap[v]) {
161 171
                  heap.decrease(v, nd);
162 172
                  _pred[v] = e;
163 173
                }
164 174
                break;
165 175
              case Heap::POST_HEAP:
166 176
                break;
167 177
              }
168 178
            }
169 179
          }
170 180

	
171 181
          // Traverse incoming arcs
172 182
          for (InArcIt e(_graph, u); e != INVALID; ++e) {
173 183
            if (_flow[e] == 1) {
174 184
              v = _graph.source(e);
175 185
              switch(heap.state(v)) {
176 186
              case Heap::PRE_HEAP:
177 187
                heap.push(v, d - _length[e] - _potential[v]);
178 188
                _pred[v] = e;
179 189
                break;
180 190
              case Heap::IN_HEAP:
181 191
                nd = d - _length[e] - _potential[v];
182 192
                if (nd < heap[v]) {
183 193
                  heap.decrease(v, nd);
184 194
                  _pred[v] = e;
185 195
                }
186 196
                break;
187 197
              case Heap::POST_HEAP:
188 198
                break;
189 199
              }
190 200
            }
191 201
          }
192 202
        }
193 203
        if (heap.empty()) return false;
194 204

	
195 205
        // Update potentials of processed nodes
196 206
        Length t_dist = heap.prio();
197 207
        for (int i = 0; i < int(_proc_nodes.size()); ++i)
198 208
          _potential[_proc_nodes[i]] += _dist[_proc_nodes[i]] - t_dist;
199 209
        return true;
200 210
      }
201 211

	
202 212
    }; //class ResidualDijkstra
203 213

	
204 214
  private:
205 215

	
206 216
    // The digraph the algorithm runs on
207 217
    const Digraph &_graph;
208 218
    // The length map
209 219
    const LengthMap &_length;
210 220

	
211 221
    // Arc map of the current flow
212 222
    FlowMap *_flow;
213 223
    bool _local_flow;
214 224
    // Node map of the current potentials
215 225
    PotentialMap *_potential;
216 226
    bool _local_potential;
217 227

	
218 228
    // The source node
219 229
    Node _source;
220 230
    // The target node
221 231
    Node _target;
222 232

	
223 233
    // Container to store the found paths
224 234
    std::vector< SimplePath<Digraph> > paths;
225 235
    int _path_num;
226 236

	
227 237
    // The pred arc map
228 238
    PredMap _pred;
229 239
    // Implementation of the Dijkstra algorithm for finding augmenting
230 240
    // shortest paths in the residual network
231 241
    ResidualDijkstra *_dijkstra;
232 242

	
233 243
  public:
234 244

	
235 245
    /// \brief Constructor.
236 246
    ///
237 247
    /// Constructor.
238 248
    ///
239
    /// \param digraph The digraph the algorithm runs on.
249
    /// \param graph The digraph the algorithm runs on.
240 250
    /// \param length The length (cost) values of the arcs.
241
    /// \param s The source node.
242
    /// \param t The target node.
243
    Suurballe( const Digraph &digraph,
244
               const LengthMap &length,
245
               Node s, Node t ) :
246
      _graph(digraph), _length(length), _flow(0), _local_flow(false),
247
      _potential(0), _local_potential(false), _source(s), _target(t),
248
      _pred(digraph) {}
251
    Suurballe( const Digraph &graph,
252
               const LengthMap &length ) :
253
      _graph(graph), _length(length), _flow(0), _local_flow(false),
254
      _potential(0), _local_potential(false), _pred(graph)
255
    {
256
      LEMON_ASSERT(std::numeric_limits<Length>::is_integer,
257
        "The length type of Suurballe must be integer");
258
    }
249 259

	
250 260
    /// Destructor.
251 261
    ~Suurballe() {
252 262
      if (_local_flow) delete _flow;
253 263
      if (_local_potential) delete _potential;
254 264
      delete _dijkstra;
255 265
    }
256 266

	
257 267
    /// \brief Set the flow map.
258 268
    ///
259 269
    /// This function sets the flow map.
270
    /// If it is not used before calling \ref run() or \ref init(),
271
    /// an instance will be allocated automatically. The destructor
272
    /// deallocates this automatically allocated map, of course.
260 273
    ///
261
    /// The found flow contains only 0 and 1 values. It is the union of
262
    /// the found arc-disjoint paths.
274
    /// The found flow contains only 0 and 1 values, since it is the
275
    /// union of the found arc-disjoint paths.
263 276
    ///
264 277
    /// \return <tt>(*this)</tt>
265 278
    Suurballe& flowMap(FlowMap &map) {
266 279
      if (_local_flow) {
267 280
        delete _flow;
268 281
        _local_flow = false;
269 282
      }
270 283
      _flow = &map;
271 284
      return *this;
272 285
    }
273 286

	
274 287
    /// \brief Set the potential map.
275 288
    ///
276 289
    /// This function sets the potential map.
290
    /// If it is not used before calling \ref run() or \ref init(),
291
    /// an instance will be allocated automatically. The destructor
292
    /// deallocates this automatically allocated map, of course.
277 293
    ///
278
    /// The potentials provide the dual solution of the underlying
279
    /// minimum cost flow problem.
294
    /// The node potentials provide the dual solution of the underlying
295
    /// \ref min_cost_flow "minimum cost flow problem".
280 296
    ///
281 297
    /// \return <tt>(*this)</tt>
282 298
    Suurballe& potentialMap(PotentialMap &map) {
283 299
      if (_local_potential) {
284 300
        delete _potential;
285 301
        _local_potential = false;
286 302
      }
287 303
      _potential = &map;
288 304
      return *this;
289 305
    }
290 306

	
291 307
    /// \name Execution Control
292 308
    /// The simplest way to execute the algorithm is to call the run()
293 309
    /// function.
294 310
    /// \n
295 311
    /// If you only need the flow that is the union of the found
296 312
    /// arc-disjoint paths, you may call init() and findFlow().
297 313

	
298 314
    /// @{
299 315

	
300 316
    /// \brief Run the algorithm.
301 317
    ///
302 318
    /// This function runs the algorithm.
303 319
    ///
320
    /// \param s The source node.
321
    /// \param t The target node.
304 322
    /// \param k The number of paths to be found.
305 323
    ///
306 324
    /// \return \c k if there are at least \c k arc-disjoint paths from
307 325
    /// \c s to \c t in the digraph. Otherwise it returns the number of
308 326
    /// arc-disjoint paths found.
309 327
    ///
310
    /// \note Apart from the return value, <tt>s.run(k)</tt> is just a
311
    /// shortcut of the following code.
328
    /// \note Apart from the return value, <tt>s.run(s, t, k)</tt> is
329
    /// just a shortcut of the following code.
312 330
    /// \code
313
    ///   s.init();
314
    ///   s.findFlow(k);
331
    ///   s.init(s);
332
    ///   s.findFlow(t, k);
315 333
    ///   s.findPaths();
316 334
    /// \endcode
317
    int run(int k = 2) {
318
      init();
319
      findFlow(k);
335
    int run(const Node& s, const Node& t, int k = 2) {
336
      init(s);
337
      findFlow(t, k);
320 338
      findPaths();
321 339
      return _path_num;
322 340
    }
323 341

	
324 342
    /// \brief Initialize the algorithm.
325 343
    ///
326 344
    /// This function initializes the algorithm.
327
    void init() {
345
    ///
346
    /// \param s The source node.
347
    void init(const Node& s) {
348
      _source = s;
349

	
328 350
      // Initialize maps
329 351
      if (!_flow) {
330 352
        _flow = new FlowMap(_graph);
331 353
        _local_flow = true;
332 354
      }
333 355
      if (!_potential) {
334 356
        _potential = new PotentialMap(_graph);
335 357
        _local_potential = true;
336 358
      }
337 359
      for (ArcIt e(_graph); e != INVALID; ++e) (*_flow)[e] = 0;
338 360
      for (NodeIt n(_graph); n != INVALID; ++n) (*_potential)[n] = 0;
339

	
340
      _dijkstra = new ResidualDijkstra( _graph, *_flow, _length,
341
                                        *_potential, _pred,
342
                                        _source, _target );
343 361
    }
344 362

	
345
    /// \brief Execute the successive shortest path algorithm to find
346
    /// an optimal flow.
363
    /// \brief Execute the algorithm to find an optimal flow.
347 364
    ///
348 365
    /// This function executes the successive shortest path algorithm to
349
    /// find a minimum cost flow, which is the union of \c k or less
366
    /// find a minimum cost flow, which is the union of \c k (or less)
350 367
    /// arc-disjoint paths.
351 368
    ///
369
    /// \param t The target node.
370
    /// \param k The number of paths to be found.
371
    ///
352 372
    /// \return \c k if there are at least \c k arc-disjoint paths from
353
    /// \c s to \c t in the digraph. Otherwise it returns the number of
354
    /// arc-disjoint paths found.
373
    /// the source node to the given node \c t in the digraph.
374
    /// Otherwise it returns the number of arc-disjoint paths found.
355 375
    ///
356 376
    /// \pre \ref init() must be called before using this function.
357
    int findFlow(int k = 2) {
377
    int findFlow(const Node& t, int k = 2) {
378
      _target = t;
379
      _dijkstra =
380
        new ResidualDijkstra( _graph, *_flow, _length, *_potential, _pred,
381
                              _source, _target );
382

	
358 383
      // Find shortest paths
359 384
      _path_num = 0;
360 385
      while (_path_num < k) {
361 386
        // Run Dijkstra
362 387
        if (!_dijkstra->run()) break;
363 388
        ++_path_num;
364 389

	
365 390
        // Set the flow along the found shortest path
366 391
        Node u = _target;
367 392
        Arc e;
368 393
        while ((e = _pred[u]) != INVALID) {
369 394
          if (u == _graph.target(e)) {
370 395
            (*_flow)[e] = 1;
371 396
            u = _graph.source(e);
372 397
          } else {
373 398
            (*_flow)[e] = 0;
374 399
            u = _graph.target(e);
375 400
          }
376 401
        }
377 402
      }
378 403
      return _path_num;
379 404
    }
380 405

	
381 406
    /// \brief Compute the paths from the flow.
382 407
    ///
383
    /// This function computes the paths from the flow.
408
    /// This function computes the paths from the found minimum cost flow,
409
    /// which is the union of some arc-disjoint paths.
384 410
    ///
385 411
    /// \pre \ref init() and \ref findFlow() must be called before using
386 412
    /// this function.
387 413
    void findPaths() {
388
      // Create the residual flow map (the union of the paths not found
389
      // so far)
390 414
      FlowMap res_flow(_graph);
391 415
      for(ArcIt a(_graph); a != INVALID; ++a) res_flow[a] = (*_flow)[a];
392 416

	
393 417
      paths.clear();
394 418
      paths.resize(_path_num);
395 419
      for (int i = 0; i < _path_num; ++i) {
396 420
        Node n = _source;
397 421
        while (n != _target) {
398 422
          OutArcIt e(_graph, n);
399 423
          for ( ; res_flow[e] == 0; ++e) ;
400 424
          n = _graph.target(e);
401 425
          paths[i].addBack(e);
402 426
          res_flow[e] = 0;
403 427
        }
404 428
      }
405 429
    }
406 430

	
407 431
    /// @}
408 432

	
409 433
    /// \name Query Functions
410 434
    /// The results of the algorithm can be obtained using these
411 435
    /// functions.
412 436
    /// \n The algorithm should be executed before using them.
413 437

	
414 438
    /// @{
415 439

	
416
    /// \brief Return a const reference to the arc map storing the
440
    /// \brief Return the total length of the found paths.
441
    ///
442
    /// This function returns the total length of the found paths, i.e.
443
    /// the total cost of the found flow.
444
    /// The complexity of the function is O(e).
445
    ///
446
    /// \pre \ref run() or \ref findFlow() must be called before using
447
    /// this function.
448
    Length totalLength() const {
449
      Length c = 0;
450
      for (ArcIt e(_graph); e != INVALID; ++e)
451
        c += (*_flow)[e] * _length[e];
452
      return c;
453
    }
454

	
455
    /// \brief Return the flow value on the given arc.
456
    ///
457
    /// This function returns the flow value on the given arc.
458
    /// It is \c 1 if the arc is involved in one of the found arc-disjoint
459
    /// paths, otherwise it is \c 0.
460
    ///
461
    /// \pre \ref run() or \ref findFlow() must be called before using
462
    /// this function.
463
    int flow(const Arc& arc) const {
464
      return (*_flow)[arc];
465
    }
466

	
467
    /// \brief Return a const reference to an arc map storing the
417 468
    /// found flow.
418 469
    ///
419
    /// This function returns a const reference to the arc map storing
470
    /// This function returns a const reference to an arc map storing
420 471
    /// the flow that is the union of the found arc-disjoint paths.
421 472
    ///
422 473
    /// \pre \ref run() or \ref findFlow() must be called before using
423 474
    /// this function.
424 475
    const FlowMap& flowMap() const {
425 476
      return *_flow;
426 477
    }
427 478

	
428
    /// \brief Return a const reference to the node map storing the
429
    /// found potentials (the dual solution).
430
    ///
431
    /// This function returns a const reference to the node map storing
432
    /// the found potentials that provide the dual solution of the
433
    /// underlying minimum cost flow problem.
434
    ///
435
    /// \pre \ref run() or \ref findFlow() must be called before using
436
    /// this function.
437
    const PotentialMap& potentialMap() const {
438
      return *_potential;
439
    }
440

	
441
    /// \brief Return the flow on the given arc.
442
    ///
443
    /// This function returns the flow on the given arc.
444
    /// It is \c 1 if the arc is involved in one of the found paths,
445
    /// otherwise it is \c 0.
446
    ///
447
    /// \pre \ref run() or \ref findFlow() must be called before using
448
    /// this function.
449
    int flow(const Arc& arc) const {
450
      return (*_flow)[arc];
451
    }
452

	
453 479
    /// \brief Return the potential of the given node.
454 480
    ///
455 481
    /// This function returns the potential of the given node.
482
    /// The node potentials provide the dual solution of the
483
    /// underlying \ref min_cost_flow "minimum cost flow problem".
456 484
    ///
457 485
    /// \pre \ref run() or \ref findFlow() must be called before using
458 486
    /// this function.
459 487
    Length potential(const Node& node) const {
460 488
      return (*_potential)[node];
461 489
    }
462 490

	
463
    /// \brief Return the total length (cost) of the found paths (flow).
491
    /// \brief Return a const reference to a node map storing the
492
    /// found potentials (the dual solution).
464 493
    ///
465
    /// This function returns the total length (cost) of the found paths
466
    /// (flow). The complexity of the function is O(e).
494
    /// This function returns a const reference to a node map storing
495
    /// the found potentials that provide the dual solution of the
496
    /// underlying \ref min_cost_flow "minimum cost flow problem".
467 497
    ///
468 498
    /// \pre \ref run() or \ref findFlow() must be called before using
469 499
    /// this function.
470
    Length totalLength() const {
471
      Length c = 0;
472
      for (ArcIt e(_graph); e != INVALID; ++e)
473
        c += (*_flow)[e] * _length[e];
474
      return c;
500
    const PotentialMap& potentialMap() const {
501
      return *_potential;
475 502
    }
476 503

	
477 504
    /// \brief Return the number of the found paths.
478 505
    ///
479 506
    /// This function returns the number of the found paths.
480 507
    ///
481 508
    /// \pre \ref run() or \ref findFlow() must be called before using
482 509
    /// this function.
483 510
    int pathNum() const {
484 511
      return _path_num;
485 512
    }
486 513

	
487 514
    /// \brief Return a const reference to the specified path.
488 515
    ///
489 516
    /// This function returns a const reference to the specified path.
490 517
    ///
491
    /// \param i The function returns the \c i-th path.
518
    /// \param i The function returns the <tt>i</tt>-th path.
492 519
    /// \c i must be between \c 0 and <tt>%pathNum()-1</tt>.
493 520
    ///
494 521
    /// \pre \ref run() or \ref findPaths() must be called before using
495 522
    /// this function.
496 523
    Path path(int i) const {
497 524
      return paths[i];
498 525
    }
499 526

	
500 527
    /// @}
501 528

	
502 529
  }; //class Suurballe
503 530

	
504 531
  ///@}
505 532

	
506 533
} //namespace lemon
507 534

	
508 535
#endif //LEMON_SUURBALLE_H
Ignore white space 6 line context
1 1
INCLUDE_DIRECTORIES(
2 2
  ${PROJECT_SOURCE_DIR}
3 3
  ${PROJECT_BINARY_DIR}
4 4
)
5 5

	
6
IF(HAVE_GLPK)
7
  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
8
ENDIF(HAVE_GLPK)
9

	
10 6
LINK_DIRECTORIES(${PROJECT_BINARY_DIR}/lemon)
11 7

	
12 8
SET(TESTS
13 9
  adaptors_test
14 10
  bfs_test
15 11
  circulation_test
16 12
  counter_test
17 13
  dfs_test
18 14
  digraph_test
19 15
  dijkstra_test
20 16
  dim_test
21 17
  edge_set_test
22 18
  error_test
23 19
  euler_test
24 20
  gomory_hu_test
25 21
  graph_copy_test
26 22
  graph_test
27 23
  graph_utils_test
28 24
  hao_orlin_test
29 25
  heap_test
30 26
  kruskal_test
31 27
  maps_test
32 28
  matching_test
33 29
  min_cost_arborescence_test
34 30
  min_cost_flow_test
35 31
  path_test
36 32
  preflow_test
37 33
  radix_sort_test
38 34
  random_test
39 35
  suurballe_test
40 36
  time_measure_test
41 37
  unionfind_test)
42 38

	
43 39
IF(HAVE_LP)
44 40
  ADD_EXECUTABLE(lp_test lp_test.cc)
41
  SET(LP_TEST_LIBS lemon)
45 42
  IF(HAVE_GLPK)
46
    TARGET_LINK_LIBRARIES(lp_test lemon ${GLPK_LIBRARIES})
43
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
47 44
  ENDIF(HAVE_GLPK)
45
  IF(HAVE_CPLEX)
46
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
47
  ENDIF(HAVE_CPLEX)
48
  IF(HAVE_CLP)
49
    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
50
  ENDIF(HAVE_CLP)
51
  TARGET_LINK_LIBRARIES(lp_test ${LP_TEST_LIBS})
48 52
  ADD_TEST(lp_test lp_test)
49 53

	
50 54
  IF(WIN32 AND HAVE_GLPK)
51 55
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
52 56
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
53 57
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
54 58
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
55 59
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
56 60
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
57 61
    )
58 62
  ENDIF(WIN32 AND HAVE_GLPK)
63
  IF(WIN32 AND HAVE_CPLEX)
64
    GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
65
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
66
    ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
67
      COMMAND cmake -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
68
    )
69
  ENDIF(WIN32 AND HAVE_CPLEX)
59 70
ENDIF(HAVE_LP)
60 71

	
61 72
IF(HAVE_MIP)
62 73
  ADD_EXECUTABLE(mip_test mip_test.cc)
74
  SET(MIP_TEST_LIBS lemon)
63 75
  IF(HAVE_GLPK)
64
    TARGET_LINK_LIBRARIES(mip_test lemon ${GLPK_LIBRARIES})
76
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
65 77
  ENDIF(HAVE_GLPK)
78
  IF(HAVE_CPLEX)
79
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
80
  ENDIF(HAVE_CPLEX)
81
  IF(HAVE_CBC)
82
    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
83
  ENDIF(HAVE_CBC)
84
  TARGET_LINK_LIBRARIES(mip_test ${MIP_TEST_LIBS})
66 85
  ADD_TEST(mip_test mip_test)
67 86

	
68 87
  IF(WIN32 AND HAVE_GLPK)
69 88
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
70 89
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
71 90
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
72 91
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/glpk.dll ${TARGET_PATH}
73 92
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/libltdl3.dll ${TARGET_PATH}
74 93
      COMMAND cmake -E copy ${GLPK_BIN_DIR}/zlib1.dll ${TARGET_PATH}
75 94
    )
76 95
  ENDIF(WIN32 AND HAVE_GLPK)
96
  IF(WIN32 AND HAVE_CPLEX)
97
    GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
98
    GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
99
    ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
100
      COMMAND cmake -E copy ${CPLEX_BIN_DIR}/cplex91.dll ${TARGET_PATH}
101
    )
102
  ENDIF(WIN32 AND HAVE_CPLEX)
77 103
ENDIF(HAVE_MIP)
78 104

	
79 105
FOREACH(TEST_NAME ${TESTS})
80 106
  ADD_EXECUTABLE(${TEST_NAME} ${TEST_NAME}.cc)
81 107
  TARGET_LINK_LIBRARIES(${TEST_NAME} lemon)
82 108
  ADD_TEST(${TEST_NAME} ${TEST_NAME})
83 109
ENDFOREACH(TEST_NAME)
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-2009
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 <lemon/list_graph.h>
22 22
#include <lemon/lgf_reader.h>
23 23
#include <lemon/path.h>
24 24
#include <lemon/suurballe.h>
25
#include <lemon/concepts/digraph.h>
25 26

	
26 27
#include "test_tools.h"
27 28

	
28 29
using namespace lemon;
29 30

	
30 31
char test_lgf[] =
31 32
  "@nodes\n"
32
  "label supply1 supply2 supply3\n"
33
  "1     0        20      27\n"
34
  "2     0       -4        0\n"
35
  "3     0        0        0\n"
36
  "4     0        0        0\n"
37
  "5     0        9        0\n"
38
  "6     0       -6        0\n"
39
  "7     0        0        0\n"
40
  "8     0        0        0\n"
41
  "9     0        3        0\n"
42
  "10    0       -2        0\n"
43
  "11    0        0        0\n"
44
  "12    0       -20     -27\n"
33
  "label\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
  "10\n"
44
  "11\n"
45
  "12\n"
45 46
  "@arcs\n"
46
  "      cost capacity lower1 lower2\n"
47
  " 1  2  70  11       0      8\n"
48
  " 1  3 150   3       0      1\n"
49
  " 1  4  80  15       0      2\n"
50
  " 2  8  80  12       0      0\n"
51
  " 3  5 140   5       0      3\n"
52
  " 4  6  60  10       0      1\n"
53
  " 4  7  80   2       0      0\n"
54
  " 4  8 110   3       0      0\n"
55
  " 5  7  60  14       0      0\n"
56
  " 5 11 120  12       0      0\n"
57
  " 6  3   0   3       0      0\n"
58
  " 6  9 140   4       0      0\n"
59
  " 6 10  90   8       0      0\n"
60
  " 7  1  30   5       0      0\n"
61
  " 8 12  60  16       0      4\n"
62
  " 9 12  50   6       0      0\n"
63
  "10 12  70  13       0      5\n"
64
  "10  2 100   7       0      0\n"
65
  "10  7  60  10       0      0\n"
66
  "11 10  20  14       0      6\n"
67
  "12 11  30  10       0      0\n"
47
  "      length\n"
48
  " 1  2  70\n"
49
  " 1  3 150\n"
50
  " 1  4  80\n"
51
  " 2  8  80\n"
52
  " 3  5 140\n"
53
  " 4  6  60\n"
54
  " 4  7  80\n"
55
  " 4  8 110\n"
56
  " 5  7  60\n"
57
  " 5 11 120\n"
58
  " 6  3   0\n"
59
  " 6  9 140\n"
60
  " 6 10  90\n"
61
  " 7  1  30\n"
62
  " 8 12  60\n"
63
  " 9 12  50\n"
64
  "10 12  70\n"
65
  "10  2 100\n"
66
  "10  7  60\n"
67
  "11 10  20\n"
68
  "12 11  30\n"
68 69
  "@attributes\n"
69 70
  "source  1\n"
70 71
  "target 12\n"
71 72
  "@end\n";
72 73

	
74
// Check the interface of Suurballe
75
void checkSuurballeCompile()
76
{
77
  typedef int VType;
78
  typedef concepts::Digraph Digraph;
79

	
80
  typedef Digraph::Node Node;
81
  typedef Digraph::Arc Arc;
82
  typedef concepts::ReadMap<Arc, VType> LengthMap;
83
  
84
  typedef Suurballe<Digraph, LengthMap> SuurballeType;
85

	
86
  Digraph g;
87
  Node n;
88
  Arc e;
89
  LengthMap len;
90
  SuurballeType::FlowMap flow(g);
91
  SuurballeType::PotentialMap pi(g);
92

	
93
  SuurballeType suurb_test(g, len);
94
  const SuurballeType& const_suurb_test = suurb_test;
95

	
96
  suurb_test
97
    .flowMap(flow)
98
    .potentialMap(pi);
99

	
100
  int k;
101
  k = suurb_test.run(n, n);
102
  k = suurb_test.run(n, n, k);
103
  suurb_test.init(n);
104
  k = suurb_test.findFlow(n);
105
  k = suurb_test.findFlow(n, k);
106
  suurb_test.findPaths();
107
  
108
  int f;
109
  VType c;
110
  c = const_suurb_test.totalLength();
111
  f = const_suurb_test.flow(e);
112
  const SuurballeType::FlowMap& fm =
113
    const_suurb_test.flowMap();
114
  c = const_suurb_test.potential(n);
115
  const SuurballeType::PotentialMap& pm =
116
    const_suurb_test.potentialMap();
117
  k = const_suurb_test.pathNum();
118
  Path<Digraph> p = const_suurb_test.path(k);
119
  
120
  ignore_unused_variable_warning(fm);
121
  ignore_unused_variable_warning(pm);
122
}
123

	
73 124
// Check the feasibility of the flow
74 125
template <typename Digraph, typename FlowMap>
75 126
bool checkFlow( const Digraph& gr, const FlowMap& flow,
76 127
                typename Digraph::Node s, typename Digraph::Node t,
77 128
                int value )
78 129
{
79 130
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
80 131
  for (ArcIt e(gr); e != INVALID; ++e)
81 132
    if (!(flow[e] == 0 || flow[e] == 1)) return false;
82 133

	
83 134
  for (NodeIt n(gr); n != INVALID; ++n) {
84 135
    int sum = 0;
85 136
    for (OutArcIt e(gr, n); e != INVALID; ++e)
86 137
      sum += flow[e];
87 138
    for (InArcIt e(gr, n); e != INVALID; ++e)
88 139
      sum -= flow[e];
89 140
    if (n == s && sum != value) return false;
90 141
    if (n == t && sum != -value) return false;
91 142
    if (n != s && n != t && sum != 0) return false;
92 143
  }
93 144

	
94 145
  return true;
95 146
}
96 147

	
97 148
// Check the optimalitiy of the flow
98 149
template < typename Digraph, typename CostMap,
99 150
           typename FlowMap, typename PotentialMap >
100 151
bool checkOptimality( const Digraph& gr, const CostMap& cost,
101 152
                      const FlowMap& flow, const PotentialMap& pi )
102 153
{
103 154
  // Check the "Complementary Slackness" optimality condition
104 155
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
105 156
  bool opt = true;
106 157
  for (ArcIt e(gr); e != INVALID; ++e) {
107 158
    typename CostMap::Value red_cost =
108 159
      cost[e] + pi[gr.source(e)] - pi[gr.target(e)];
109 160
    opt = (flow[e] == 0 && red_cost >= 0) ||
110 161
          (flow[e] == 1 && red_cost <= 0);
111 162
    if (!opt) break;
112 163
  }
113 164
  return opt;
114 165
}
115 166

	
116 167
// Check a path
117 168
template <typename Digraph, typename Path>
118 169
bool checkPath( const Digraph& gr, const Path& path,
119 170
                typename Digraph::Node s, typename Digraph::Node t)
120 171
{
121
  // Check the "Complementary Slackness" optimality condition
122 172
  TEMPLATE_DIGRAPH_TYPEDEFS(Digraph);
123 173
  Node n = s;
124 174
  for (int i = 0; i < path.length(); ++i) {
125 175
    if (gr.source(path.nth(i)) != n) return false;
126 176
    n = gr.target(path.nth(i));
127 177
  }
128 178
  return n == t;
129 179
}
130 180

	
131 181

	
132 182
int main()
133 183
{
134 184
  DIGRAPH_TYPEDEFS(ListDigraph);
135 185

	
136 186
  // Read the test digraph
137 187
  ListDigraph digraph;
138 188
  ListDigraph::ArcMap<int> length(digraph);
139
  Node source, target;
189
  Node s, t;
140 190

	
141 191
  std::istringstream input(test_lgf);
142 192
  DigraphReader<ListDigraph>(digraph, input).
143
    arcMap("cost", length).
144
    node("source", source).
145
    node("target", target).
193
    arcMap("length", length).
194
    node("source", s).
195
    node("target", t).
146 196
    run();
147 197

	
148 198
  // Find 2 paths
149 199
  {
150
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
151
    check(suurballe.run(2) == 2, "Wrong number of paths");
152
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 2),
200
    Suurballe<ListDigraph> suurballe(digraph, length);
201
    check(suurballe.run(s, t) == 2, "Wrong number of paths");
202
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 2),
153 203
          "The flow is not feasible");
154 204
    check(suurballe.totalLength() == 510, "The flow is not optimal");
155 205
    check(checkOptimality(digraph, length, suurballe.flowMap(),
156 206
                          suurballe.potentialMap()),
157 207
          "Wrong potentials");
158 208
    for (int i = 0; i < suurballe.pathNum(); ++i)
159
      check(checkPath(digraph, suurballe.path(i), source, target),
160
            "Wrong path");
209
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
161 210
  }
162 211

	
163 212
  // Find 3 paths
164 213
  {
165
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
166
    check(suurballe.run(3) == 3, "Wrong number of paths");
167
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
214
    Suurballe<ListDigraph> suurballe(digraph, length);
215
    check(suurballe.run(s, t, 3) == 3, "Wrong number of paths");
216
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
168 217
          "The flow is not feasible");
169 218
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
170 219
    check(checkOptimality(digraph, length, suurballe.flowMap(),
171 220
                          suurballe.potentialMap()),
172 221
          "Wrong potentials");
173 222
    for (int i = 0; i < suurballe.pathNum(); ++i)
174
      check(checkPath(digraph, suurballe.path(i), source, target),
175
            "Wrong path");
223
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
176 224
  }
177 225

	
178 226
  // Find 5 paths (only 3 can be found)
179 227
  {
180
    Suurballe<ListDigraph> suurballe(digraph, length, source, target);
181
    check(suurballe.run(5) == 3, "Wrong number of paths");
182
    check(checkFlow(digraph, suurballe.flowMap(), source, target, 3),
228
    Suurballe<ListDigraph> suurballe(digraph, length);
229
    check(suurballe.run(s, t, 5) == 3, "Wrong number of paths");
230
    check(checkFlow(digraph, suurballe.flowMap(), s, t, 3),
183 231
          "The flow is not feasible");
184 232
    check(suurballe.totalLength() == 1040, "The flow is not optimal");
185 233
    check(checkOptimality(digraph, length, suurballe.flowMap(),
186 234
                          suurballe.potentialMap()),
187 235
          "Wrong potentials");
188 236
    for (int i = 0; i < suurballe.pathNum(); ++i)
189
      check(checkPath(digraph, suurballe.path(i), source, target),
190
            "Wrong path");
237
      check(checkPath(digraph, suurballe.path(i), s, t), "Wrong path");
191 238
  }
192 239

	
193 240
  return 0;
194 241
}
Ignore white space 6 line context
... ...
@@ -355,290 +355,289 @@
355 355
      if (next != -1 &&
356 356
          circle_form(points[site], points[curr],points[next])) {
357 357
        double x = circle_point(points[site], points[curr], points[next]);
358 358
        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
359 359
        nit->second.it =
360 360
          beach.insert(std::make_pair(Part(site, curr, next), nit));
361 361
      } else {
362 362
        beach.insert(std::make_pair(Part(site, curr, next), nit));
363 363
      }
364 364

	
365 365
      ++siteindex;
366 366
    } else {
367 367
      sweep = spit->first;
368 368

	
369 369
      Beach::iterator bit = spit->second.it;
370 370

	
371 371
      int prev = bit->first.prev;
372 372
      int curr = bit->first.curr;
373 373
      int next = bit->first.next;
374 374

	
375 375
      {
376 376
        std::pair<int, int> arc;
377 377

	
378 378
        arc = prev < curr ?
379 379
          std::make_pair(prev, curr) : std::make_pair(curr, prev);
380 380

	
381 381
        if (arcs.find(arc) == arcs.end()) {
382 382
          arcs.insert(arc);
383 383
          g.addEdge(nodes[prev], nodes[curr]);
384 384
          ++cnt;
385 385
        }
386 386

	
387 387
        arc = curr < next ?
388 388
          std::make_pair(curr, next) : std::make_pair(next, curr);
389 389

	
390 390
        if (arcs.find(arc) == arcs.end()) {
391 391
          arcs.insert(arc);
392 392
          g.addEdge(nodes[curr], nodes[next]);
393 393
          ++cnt;
394 394
        }
395 395
      }
396 396

	
397 397
      Beach::iterator pbit = bit; --pbit;
398 398
      int ppv = pbit->first.prev;
399 399
      Beach::iterator nbit = bit; ++nbit;
400 400
      int nnt = nbit->first.next;
401 401

	
402 402
      if (bit->second != spikeheap.end()) spikeheap.erase(bit->second);
403 403
      if (pbit->second != spikeheap.end()) spikeheap.erase(pbit->second);
404 404
      if (nbit->second != spikeheap.end()) spikeheap.erase(nbit->second);
405 405

	
406 406
      beach.erase(nbit);
407 407
      beach.erase(bit);
408 408
      beach.erase(pbit);
409 409

	
410 410
      SpikeHeap::iterator pit = spikeheap.end();
411 411
      if (ppv != -1 && ppv != next &&
412 412
          circle_form(points[ppv], points[prev], points[next])) {
413 413
        double x = circle_point(points[ppv], points[prev], points[next]);
414 414
        if (x < sweep) x = sweep;
415 415
        pit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
416 416
        pit->second.it =
417 417
          beach.insert(std::make_pair(Part(ppv, prev, next), pit));
418 418
      } else {
419 419
        beach.insert(std::make_pair(Part(ppv, prev, next), pit));
420 420
      }
421 421

	
422 422
      SpikeHeap::iterator nit = spikeheap.end();
423 423
      if (nnt != -1 && prev != nnt &&
424 424
          circle_form(points[prev], points[next], points[nnt])) {
425 425
        double x = circle_point(points[prev], points[next], points[nnt]);
426 426
        if (x < sweep) x = sweep;
427 427
        nit = spikeheap.insert(std::make_pair(x, BeachIt(beach.end())));
428 428
        nit->second.it =
429 429
          beach.insert(std::make_pair(Part(prev, next, nnt), nit));
430 430
      } else {
431 431
        beach.insert(std::make_pair(Part(prev, next, nnt), nit));
432 432
      }
433 433

	
434 434
    }
435 435
  }
436 436

	
437 437
  for (Beach::iterator it = beach.begin(); it != beach.end(); ++it) {
438 438
    int curr = it->first.curr;
439 439
    int next = it->first.next;
440 440

	
441 441
    if (next == -1) continue;
442 442

	
443 443
    std::pair<int, int> arc;
444 444

	
445 445
    arc = curr < next ?
446 446
      std::make_pair(curr, next) : std::make_pair(next, curr);
447 447

	
448 448
    if (arcs.find(arc) == arcs.end()) {
449 449
      arcs.insert(arc);
450 450
      g.addEdge(nodes[curr], nodes[next]);
451 451
      ++cnt;
452 452
    }
453 453
  }
454 454
}
455 455

	
456 456
void sparse(int d)
457 457
{
458 458
  Counter cnt("Number of arcs removed: ");
459 459
  Bfs<ListGraph> bfs(g);
460 460
  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
461 461
      ei!=arcs.rend();++ei)
462 462
    {
463 463
      Node a=g.u(*ei);
464 464
      Node b=g.v(*ei);
465 465
      g.erase(*ei);
466 466
      bfs.run(a,b);
467 467
      if(bfs.predArc(b)==INVALID || bfs.dist(b)>d)
468 468
        g.addEdge(a,b);
469 469
      else cnt++;
470 470
    }
471 471
}
472 472

	
473 473
void sparse2(int d)
474 474
{
475 475
  Counter cnt("Number of arcs removed: ");
476 476
  for(std::vector<Edge>::reverse_iterator ei=arcs.rbegin();
477 477
      ei!=arcs.rend();++ei)
478 478
    {
479 479
      Node a=g.u(*ei);
480 480
      Node b=g.v(*ei);
481 481
      g.erase(*ei);
482 482
      ConstMap<Arc,int> cegy(1);
483
      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy,a,b);
484
      int k=sur.run(2);
483
      Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
484
      int k=sur.run(a,b,2);
485 485
      if(k<2 || sur.totalLength()>d)
486 486
        g.addEdge(a,b);
487 487
      else cnt++;
488 488
//       else std::cout << "Remove arc " << g.id(a) << "-" << g.id(b) << '\n';
489 489
    }
490 490
}
491 491

	
492 492
void sparseTriangle(int d)
493 493
{
494 494
  Counter cnt("Number of arcs added: ");
495 495
  std::vector<Parc> pedges;
496 496
  for(NodeIt n(g);n!=INVALID;++n)
497 497
    for(NodeIt m=++(NodeIt(n));m!=INVALID;++m)
498 498
      {
499 499
        Parc p;
500 500
        p.a=n;
501 501
        p.b=m;
502 502
        p.len=(coords[m]-coords[n]).normSquare();
503 503
        pedges.push_back(p);
504 504
      }
505 505
  std::sort(pedges.begin(),pedges.end(),pedgeLess);
506 506
  for(std::vector<Parc>::iterator pi=pedges.begin();pi!=pedges.end();++pi)
507 507
    {
508 508
      Line li(pi->a,pi->b);
509 509
      EdgeIt e(g);
510 510
      for(;e!=INVALID && !cross(e,li);++e) ;
511 511
      Edge ne;
512 512
      if(e==INVALID) {
513 513
        ConstMap<Arc,int> cegy(1);
514
        Suurballe<ListGraph,ConstMap<Arc,int> >
515
          sur(g,cegy,pi->a,pi->b);
516
        int k=sur.run(2);
514
        Suurballe<ListGraph,ConstMap<Arc,int> > sur(g,cegy);
515
        int k=sur.run(pi->a,pi->b,2);
517 516
        if(k<2 || sur.totalLength()>d)
518 517
          {
519 518
            ne=g.addEdge(pi->a,pi->b);
520 519
            arcs.push_back(ne);
521 520
            cnt++;
522 521
          }
523 522
      }
524 523
    }
525 524
}
526 525

	
527 526
template <typename Graph, typename CoordMap>
528 527
class LengthSquareMap {
529 528
public:
530 529
  typedef typename Graph::Edge Key;
531 530
  typedef typename CoordMap::Value::Value Value;
532 531

	
533 532
  LengthSquareMap(const Graph& graph, const CoordMap& coords)
534 533
    : _graph(graph), _coords(coords) {}
535 534

	
536 535
  Value operator[](const Key& key) const {
537 536
    return (_coords[_graph.v(key)] -
538 537
            _coords[_graph.u(key)]).normSquare();
539 538
  }
540 539

	
541 540
private:
542 541

	
543 542
  const Graph& _graph;
544 543
  const CoordMap& _coords;
545 544
};
546 545

	
547 546
void minTree() {
548 547
  std::vector<Parc> pedges;
549 548
  Timer T;
550 549
  std::cout << T.realTime() << "s: Creating delaunay triangulation...\n";
551 550
  delaunay();
552 551
  std::cout << T.realTime() << "s: Calculating spanning tree...\n";
553 552
  LengthSquareMap<ListGraph, ListGraph::NodeMap<Point> > ls(g, coords);
554 553
  ListGraph::EdgeMap<bool> tree(g);
555 554
  kruskal(g, ls, tree);
556 555
  std::cout << T.realTime() << "s: Removing non tree arcs...\n";
557 556
  std::vector<Edge> remove;
558 557
  for (EdgeIt e(g); e != INVALID; ++e) {
559 558
    if (!tree[e]) remove.push_back(e);
560 559
  }
561 560
  for(int i = 0; i < int(remove.size()); ++i) {
562 561
    g.erase(remove[i]);
563 562
  }
564 563
  std::cout << T.realTime() << "s: Done\n";
565 564
}
566 565

	
567 566
void tsp2()
568 567
{
569 568
  std::cout << "Find a tree..." << std::endl;
570 569

	
571 570
  minTree();
572 571

	
573 572
  std::cout << "Total arc length (tree) : " << totalLen() << std::endl;
574 573

	
575 574
  std::cout << "Make it Euler..." << std::endl;
576 575

	
577 576
  {
578 577
    std::vector<Node> leafs;
579 578
    for(NodeIt n(g);n!=INVALID;++n)
580 579
      if(countIncEdges(g,n)%2==1) leafs.push_back(n);
581 580

	
582 581
//    for(unsigned int i=0;i<leafs.size();i+=2)
583 582
//       g.addArc(leafs[i],leafs[i+1]);
584 583

	
585 584
    std::vector<Parc> pedges;
586 585
    for(unsigned int i=0;i<leafs.size()-1;i++)
587 586
      for(unsigned int j=i+1;j<leafs.size();j++)
588 587
        {
589 588
          Node n=leafs[i];
590 589
          Node m=leafs[j];
591 590
          Parc p;
592 591
          p.a=n;
593 592
          p.b=m;
594 593
          p.len=(coords[m]-coords[n]).normSquare();
595 594
          pedges.push_back(p);
596 595
        }
597 596
    std::sort(pedges.begin(),pedges.end(),pedgeLess);
598 597
    for(unsigned int i=0;i<pedges.size();i++)
599 598
      if(countIncEdges(g,pedges[i].a)%2 &&
600 599
         countIncEdges(g,pedges[i].b)%2)
601 600
        g.addEdge(pedges[i].a,pedges[i].b);
602 601
  }
603 602

	
604 603
  for(NodeIt n(g);n!=INVALID;++n)
605 604
    if(countIncEdges(g,n)%2 || countIncEdges(g,n)==0 )
606 605
      std::cout << "GEBASZ!!!" << std::endl;
607 606

	
608 607
  for(EdgeIt e(g);e!=INVALID;++e)
609 608
    if(g.u(e)==g.v(e))
610 609
      std::cout << "LOOP GEBASZ!!!" << std::endl;
611 610

	
612 611
  std::cout << "Number of arcs : " << countEdges(g) << std::endl;
613 612

	
614 613
  std::cout << "Total arc length (euler) : " << totalLen() << std::endl;
615 614

	
616 615
  ListGraph::EdgeMap<Arc> enext(g);
617 616
  {
618 617
    EulerIt<ListGraph> e(g);
619 618
    Arc eo=e;
620 619
    Arc ef=e;
621 620
//     std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
622 621
    for(++e;e!=INVALID;++e)
623 622
      {
624 623
//         std::cout << "Tour arc: " << g.id(Edge(e)) << std::endl;
625 624
        enext[eo]=e;
626 625
        eo=e;
627 626
      }
628 627
    enext[eo]=ef;
629 628
  }
630 629

	
631 630
  std::cout << "Creating a tour from that..." << std::endl;
632 631

	
633 632
  int nnum = countNodes(g);
634 633
  int ednum = countEdges(g);
635 634

	
636 635
  for(Arc p=enext[EdgeIt(g)];ednum>nnum;p=enext[p])
637 636
    {
638 637
//       std::cout << "Checking arc " << g.id(p) << std::endl;
639 638
      Arc e=enext[p];
640 639
      Arc f=enext[e];
641 640
      Node n2=g.source(f);
642 641
      Node n1=g.oppositeNode(n2,e);
643 642
      Node n3=g.oppositeNode(n2,f);
644 643
      if(countIncEdges(g,n2)>2)
0 comments (0 inline)