[Lemon-commits] Alpar Juttner: Merge

Lemon HG hg at lemon.cs.elte.hu
Sun Apr 26 17:41:05 CEST 2009


details:   http://lemon.cs.elte.hu/hg/lemon/rev/58357e986a08
changeset: 658:58357e986a08
user:      Alpar Juttner <alpar [at] cs.elte.hu>
date:      Sun Apr 26 16:36:23 2009 +0100
description:
	Merge

diffstat:

 CMakeLists.txt         |    8 +-
 cmake/FindCOIN.cmake   |   68 +++++++++++++++++
 cmake/FindCPLEX.cmake  |   27 ++++++
 cmake/FindGLPK.cmake   |    7 +
 lemon/CMakeLists.txt   |   17 ++++-
 lemon/circulation.h    |   40 ++++++++--
 lemon/config.h.cmake   |    3 +
 lemon/suurballe.h      |  205 +++++++++++++++++++++++++++++----------------------
 test/CMakeLists.txt    |   38 ++++++++-
 test/suurballe_test.cc |  157 +++++++++++++++++++++++++-------------
 tools/lgf-gen.cc       |    9 +-
 11 files changed, 409 insertions(+), 170 deletions(-)

diffs (truncated from 1013 to 300 lines):

diff --git a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -14,6 +14,8 @@
 INCLUDE(FindDoxygen)
 INCLUDE(FindGhostscript)
 FIND_PACKAGE(GLPK 4.33)
+FIND_PACKAGE(CPLEX)
+FIND_PACKAGE(COIN)
 
 ADD_DEFINITIONS(-DHAVE_CONFIG_H)
 
@@ -26,12 +28,6 @@
 # C4996: 'function': was declared deprecated
 ENDIF(MSVC)
 
-IF(GLPK_FOUND)
-  SET(HAVE_LP TRUE)
-  SET(HAVE_MIP TRUE)
-  SET(HAVE_GLPK TRUE)
-ENDIF(GLPK_FOUND)
-
 INCLUDE(CheckTypeSize)
 CHECK_TYPE_SIZE("long long" LONG_LONG)
 
diff --git a/cmake/FindCOIN.cmake b/cmake/FindCOIN.cmake
new file mode 100644
--- /dev/null
+++ b/cmake/FindCOIN.cmake
@@ -0,0 +1,68 @@
+SET(COIN_ROOT_DIR "" CACHE PATH "COIN root directory")
+
+FIND_PATH(COIN_INCLUDE_DIR coin/CoinUtilsConfig.h
+  PATHS ${COIN_ROOT_DIR}/include)
+
+FIND_LIBRARY(COIN_CBC_LIBRARY libCbc
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_CBC_SOLVER_LIBRARY libCbcSolver
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_CGL_LIBRARY libCgl
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_CLP_LIBRARY libClp
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_COIN_UTILS_LIBRARY libCoinUtils
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_OSI_LIBRARY libOsi
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_OSI_CBC_LIBRARY libOsiCbc
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_OSI_CLP_LIBRARY libOsiClp
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_OSI_VOL_LIBRARY libOsiVol
+  PATHS ${COIN_ROOT_DIR}/lib)
+FIND_LIBRARY(COIN_VOL_LIBRARY libVol
+  PATHS ${COIN_ROOT_DIR}/lib)
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(COIN DEFAULT_MSG
+  COIN_INCLUDE_DIR
+  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
+)
+
+IF(COIN_FOUND)
+  SET(COIN_INCLUDE_DIRS ${COIN_INCLUDE_DIR})
+  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}")
+  SET(COIN_CLP_LIBRARIES "${COIN_CLP_LIBRARY};${COIN_COIN_UTILS_LIBRARY}")
+  SET(COIN_CBC_LIBRARIES ${COIN_LIBRARIES})
+ENDIF(COIN_FOUND)
+
+MARK_AS_ADVANCED(
+  COIN_INCLUDE_DIR
+  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
+)
+
+IF(COIN_FOUND)
+  SET(HAVE_LP TRUE)
+  SET(HAVE_MIP TRUE)
+  SET(HAVE_CLP TRUE)
+  SET(HAVE_CBC TRUE)
+ENDIF(COIN_FOUND)
diff --git a/cmake/FindCPLEX.cmake b/cmake/FindCPLEX.cmake
new file mode 100644
--- /dev/null
+++ b/cmake/FindCPLEX.cmake
@@ -0,0 +1,27 @@
+FIND_PATH(CPLEX_INCLUDE_DIR
+  ilcplex/cplex.h
+  PATHS "C:/ILOG/CPLEX91/include")
+
+FIND_LIBRARY(CPLEX_LIBRARY
+  NAMES cplex91
+  PATHS "C:/ILOG/CPLEX91/lib/msvc7/stat_mda")
+
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
+
+FIND_PATH(CPLEX_BIN_DIR
+  cplex91.dll
+  PATHS "C:/ILOG/CPLEX91/bin/x86_win32")
+
+IF(CPLEX_FOUND)
+  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
+  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
+ENDIF(CPLEX_FOUND)
+
+MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
+
+IF(CPLEX_FOUND)
+  SET(HAVE_LP TRUE)
+  SET(HAVE_MIP TRUE)
+  SET(HAVE_CPLEX TRUE)
+ENDIF(CPLEX_FOUND)
diff --git a/cmake/FindGLPK.cmake b/cmake/FindGLPK.cmake
--- a/cmake/FindGLPK.cmake
+++ b/cmake/FindGLPK.cmake
@@ -13,8 +13,15 @@
 FIND_PACKAGE_HANDLE_STANDARD_ARGS(GLPK DEFAULT_MSG GLPK_LIBRARY GLPK_INCLUDE_DIR)
 
 IF(GLPK_FOUND)
+  SET(GLPK_INCLUDE_DIRS ${GLPK_INCLUDE_DIR})
   SET(GLPK_LIBRARIES ${GLPK_LIBRARY})
   SET(GLPK_BIN_DIR ${GLPK_ROOT_PATH}/bin)
 ENDIF(GLPK_FOUND)
 
 MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
+
+IF(GLPK_FOUND)
+  SET(HAVE_LP TRUE)
+  SET(HAVE_MIP TRUE)
+  SET(HAVE_GLPK TRUE)
+ENDIF(GLPK_FOUND)
diff --git a/lemon/CMakeLists.txt b/lemon/CMakeLists.txt
--- a/lemon/CMakeLists.txt
+++ b/lemon/CMakeLists.txt
@@ -20,7 +20,7 @@
 
 IF(HAVE_GLPK)
   SET(LEMON_SOURCES ${LEMON_SOURCES} glpk.cc)
-  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIR})
+  INCLUDE_DIRECTORIES(${GLPK_INCLUDE_DIRS})
   IF(WIN32)
     INSTALL(FILES ${GLPK_BIN_DIR}/glpk.dll DESTINATION bin)
     INSTALL(FILES ${GLPK_BIN_DIR}/libltdl3.dll DESTINATION bin)
@@ -28,6 +28,21 @@
   ENDIF(WIN32)
 ENDIF(HAVE_GLPK)
 
+IF(HAVE_CPLEX)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
+  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
+ENDIF(HAVE_CPLEX)
+
+IF(HAVE_CLP)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} clp.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF(HAVE_CLP)
+
+IF(HAVE_CBC)
+  SET(LEMON_SOURCES ${LEMON_SOURCES} cbc.cc)
+  INCLUDE_DIRECTORIES(${COIN_INCLUDE_DIRS})
+ENDIF(HAVE_CBC)
+
 ADD_LIBRARY(lemon ${LEMON_SOURCES})
 
 INSTALL(
diff --git a/lemon/circulation.h b/lemon/circulation.h
--- a/lemon/circulation.h
+++ b/lemon/circulation.h
@@ -21,6 +21,7 @@
 
 #include <lemon/tolerance.h>
 #include <lemon/elevator.h>
+#include <limits>
 
 ///\ingroup max_flow
 ///\file
@@ -119,15 +120,15 @@
      at the nodes.
 
      The exact formulation of this problem is the following.
-     Let \f$G=(V,A)\f$ be a digraph,
-     \f$lower, upper: A\rightarrow\mathbf{R}^+_0\f$ denote the lower and
-     upper bounds on the arcs, for which \f$0 \leq lower(uv) \leq upper(uv)\f$
+     Let \f$G=(V,A)\f$ be a digraph, \f$lower: A\rightarrow\mathbf{R}\f$
+     \f$upper: A\rightarrow\mathbf{R}\cup\{\infty\}\f$ denote the lower and
+     upper bounds on the arcs, for which \f$lower(uv) \leq upper(uv)\f$
      holds for all \f$uv\in A\f$, and \f$sup: V\rightarrow\mathbf{R}\f$
      denotes the signed supply values of the nodes.
      If \f$sup(u)>0\f$, then \f$u\f$ is a supply node with \f$sup(u)\f$
      supply, if \f$sup(u)<0\f$, then \f$u\f$ is a demand node with
      \f$-sup(u)\f$ demand.
-     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}^+_0\f$
+     A feasible circulation is an \f$f: A\rightarrow\mathbf{R}\f$
      solution of the following problem.
 
      \f[ \sum_{uv\in A} f(uv) - \sum_{vu\in A} f(vu)
@@ -151,6 +152,10 @@
      the direction of the arcs and taking the negative of the supply values
      (e.g. using \ref ReverseDigraph and \ref NegMap adaptors).
 
+     This algorithm either calculates a feasible circulation, or provides
+     a \ref barrier() "barrier", which prooves that a feasible soultion
+     cannot exist.
+
      Note that this algorithm also provides a feasible solution for the
      \ref min_cost_flow "minimum cost flow problem".
 
@@ -337,6 +342,13 @@
 
   private:
 
+    bool checkBoundMaps() {
+      for (ArcIt e(_g);e!=INVALID;++e) {
+        if (_tol.less((*_up)[e], (*_lo)[e])) return false;
+      }
+      return true;
+    }
+
     void createStructures() {
       _node_num = _el = countNodes(_g);
 
@@ -380,7 +392,7 @@
 
     /// Sets the upper bound (capacity) map.
     /// \return <tt>(*this)</tt>
-    Circulation& upperMap(const LowerMap& map) {
+    Circulation& upperMap(const UpperMap& map) {
       _up = ↦
       return *this;
     }
@@ -467,6 +479,9 @@
     /// to the lower bound.
     void init()
     {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
       createStructures();
 
       for(NodeIt n(_g);n!=INVALID;++n) {
@@ -496,6 +511,9 @@
     /// to construct the initial solution.
     void greedyInit()
     {
+      LEMON_DEBUG(checkBoundMaps(),
+        "Upper bounds must be greater or equal to the lower bounds");
+
       createStructures();
 
       for(NodeIt n(_g);n!=INVALID;++n) {
@@ -503,11 +521,11 @@
       }
 
       for (ArcIt e(_g);e!=INVALID;++e) {
-        if (!_tol.positive((*_excess)[_g.target(e)] + (*_up)[e])) {
+        if (!_tol.less(-(*_excess)[_g.target(e)], (*_up)[e])) {
           _flow->set(e, (*_up)[e]);
           (*_excess)[_g.target(e)] += (*_up)[e];
           (*_excess)[_g.source(e)] -= (*_up)[e];
-        } else if (_tol.positive((*_excess)[_g.target(e)] + (*_lo)[e])) {
+        } else if (_tol.less(-(*_excess)[_g.target(e)], (*_lo)[e])) {
           _flow->set(e, (*_lo)[e]);
           (*_excess)[_g.target(e)] += (*_lo)[e];
           (*_excess)[_g.source(e)] -= (*_lo)[e];
@@ -748,6 +766,9 @@
     bool checkBarrier() const
     {
       Flow delta=0;
+      Flow inf_cap = std::numeric_limits<Flow>::has_infinity ?
+        std::numeric_limits<Flow>::infinity() :
+        std::numeric_limits<Flow>::max();
       for(NodeIt n(_g);n!=INVALID;++n)
         if(barrier(n))
           delta-=(*_supply)[n];
@@ -755,7 +776,10 @@
         {
           Node s=_g.source(e);
           Node t=_g.target(e);
-          if(barrier(s)&&!barrier(t)) delta+=(*_up)[e];
+          if(barrier(s)&&!barrier(t)) {
+            if (_tol.less(inf_cap - (*_up)[e], delta)) return false;
+            delta+=(*_up)[e];



More information about the Lemon-commits mailing list