Merge #446, #457, #465
authorAlpar Juttner <alpar@cs.elte.hu>
Mon, 15 Jul 2013 08:33:08 +0200
changeset 1065490d89913a17
parent 1061 473c71baff72
parent 1064 fc3854d936f7
child 1066 b208de044477
Merge #446, #457, #465
INSTALL
cmake/FindCPLEX.cmake
test/CMakeLists.txt
     1.1 --- a/CMakeLists.txt	Thu Feb 28 23:45:39 2013 +0100
     1.2 +++ b/CMakeLists.txt	Mon Jul 15 08:33:08 2013 +0200
     1.3 @@ -61,9 +61,64 @@
     1.4  
     1.5  FIND_PACKAGE(Doxygen)
     1.6  FIND_PACKAGE(Ghostscript)
     1.7 -FIND_PACKAGE(GLPK 4.33)
     1.8 -FIND_PACKAGE(CPLEX)
     1.9 -FIND_PACKAGE(COIN)
    1.10 +
    1.11 +SET(LEMON_ENABLE_GLPK YES CACHE STRING "Enable GLPK solver backend.")
    1.12 +SET(LEMON_ENABLE_ILOG YES CACHE STRING "Enable ILOG (CPLEX) solver backend.")
    1.13 +SET(LEMON_ENABLE_COIN YES CACHE STRING "Enable COIN solver backend.")
    1.14 +
    1.15 +IF(LEMON_ENABLE_GLPK) 
    1.16 +  FIND_PACKAGE(GLPK 4.33)
    1.17 +ENDIF(LEMON_ENABLE_GLPK)
    1.18 +IF(LEMON_ENABLE_ILOG)
    1.19 +  FIND_PACKAGE(ILOG)
    1.20 +ENDIF(LEMON_ENABLE_ILOG)
    1.21 +IF(LEMON_ENABLE_COIN)
    1.22 +  FIND_PACKAGE(COIN)
    1.23 +ENDIF(LEMON_ENABLE_COIN)
    1.24 +
    1.25 +IF(GLPK_FOUND)
    1.26 +  SET(LEMON_HAVE_LP TRUE)
    1.27 +  SET(LEMON_HAVE_MIP TRUE)
    1.28 +  SET(LEMON_HAVE_GLPK TRUE)
    1.29 +ENDIF(GLPK_FOUND)
    1.30 +IF(ILOG_FOUND)
    1.31 +  SET(LEMON_HAVE_LP TRUE)
    1.32 +  SET(LEMON_HAVE_MIP TRUE)
    1.33 +  SET(LEMON_HAVE_ILOG TRUE)
    1.34 +ENDIF(ILOG_FOUND)
    1.35 +IF(COIN_FOUND)
    1.36 +  SET(LEMON_HAVE_LP TRUE)
    1.37 +  SET(LEMON_HAVE_MIP TRUE)
    1.38 +  SET(LEMON_HAVE_CLP TRUE)
    1.39 +  SET(LEMON_HAVE_CBC TRUE)
    1.40 +ENDIF(COIN_FOUND)
    1.41 +
    1.42 +IF(ILOG_FOUND)
    1.43 +  SET(DEFAULT_LP "CPLEX")
    1.44 +  SET(DEFAULT_MIP "CPLEX")
    1.45 +ELSEIF(COIN_FOUND)
    1.46 +  SET(DEFAULT_LP "CLP")
    1.47 +  SET(DEFAULT_MIP "CBC")
    1.48 +ELSEIF(GLPK_FOUND)
    1.49 +  SET(DEFAULT_LP "GLPK")
    1.50 +  SET(DEFAULT_MIP "GLPK")
    1.51 +ENDIF()
    1.52 +
    1.53 +IF(NOT LEMON_DEFAULT_LP OR
    1.54 +    (NOT ILOG_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CPLEX")) OR
    1.55 +    (NOT COIN_FOUND AND (LEMON_DEFAULT_LP STREQUAL "CLP")) OR
    1.56 +    (NOT GLPK_FOUND AND (LEMON_DEFAULT_LP STREQUAL "GLPK")))
    1.57 +  SET(LEMON_DEFAULT_LP ${DEFAULT_LP} CACHE STRING
    1.58 +    "Default LP solver backend (GLPK, CPLEX or CLP)" FORCE)
    1.59 +ENDIF()
    1.60 +IF(NOT LEMON_DEFAULT_MIP OR
    1.61 +    (NOT ILOG_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CPLEX")) OR
    1.62 +    (NOT COIN_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "CBC")) OR
    1.63 +    (NOT GLPK_FOUND AND (LEMON_DEFAULT_MIP STREQUAL "GLPK")))
    1.64 +  SET(LEMON_DEFAULT_MIP ${DEFAULT_MIP} CACHE STRING
    1.65 +    "Default MIP solver backend (GLPK, CPLEX or CBC)" FORCE)
    1.66 +ENDIF()
    1.67 +
    1.68  
    1.69  IF(DEFINED ENV{LEMON_CXX_WARNING})
    1.70    SET(CXX_WARNING $ENV{LEMON_CXX_WARNING})
     2.1 --- a/INSTALL	Thu Feb 28 23:45:39 2013 +0100
     2.2 +++ b/INSTALL	Mon Jul 15 08:33:08 2013 +0200
     2.3 @@ -134,11 +134,29 @@
     2.4    See http://docs.mathjax.org/en/latest/installation.html for more details.
     2.5  
     2.6    
     2.7 +-DLEMON_ENABLE_GLPK=NO
     2.8 +-DLEMON_ENABLE_COIN=NO
     2.9 +-DLEMON_ENABLE_ILOG=NO
    2.10 +
    2.11 +  Enable optional third party libraries. They are all enabled by default. 
    2.12 +
    2.13 +-DLEMON_DEFAULT_LP=GLPK
    2.14 +
    2.15 +  Sets the default LP solver backend. The supported values are
    2.16 +  CPLEX, CLP and GLPK. By default, it is set to the first one which
    2.17 +  is enabled and succesfully discovered.
    2.18 +
    2.19 +-DLEMON_DEFAULT_MIP=GLPK
    2.20 +
    2.21 +  Sets the default MIP solver backend. The supported values are
    2.22 +  CPLEX, CBC and GLPK. By default, it is set to the first one which
    2.23 +  is enabled and succesfully discovered.
    2.24 +
    2.25  -DGLPK_ROOT_DIR=DIRECTORY
    2.26  -DCOIN_ROOT_DIR=DIRECTORY
    2.27 --DCPLEX_ROOT_DIR=DIRECTORY
    2.28 +-DILOG_ROOT_DIR=DIRECTORY
    2.29  
    2.30 -  Install root directory prefixes of optional third party libraries.
    2.31 +  Root directory prefixes of optional third party libraries.
    2.32  
    2.33  Makefile Variables
    2.34  ==================
     3.1 --- a/cmake/FindCOIN.cmake	Thu Feb 28 23:45:39 2013 +0100
     3.2 +++ b/cmake/FindCOIN.cmake	Mon Jul 15 08:33:08 2013 +0200
     3.3 @@ -108,10 +108,3 @@
     3.4    COIN_ZLIB_LIBRARY
     3.5    COIN_BZ2_LIBRARY
     3.6  )
     3.7 -
     3.8 -IF(COIN_FOUND)
     3.9 -  SET(LEMON_HAVE_LP TRUE)
    3.10 -  SET(LEMON_HAVE_MIP TRUE)
    3.11 -  SET(LEMON_HAVE_CLP TRUE)
    3.12 -  SET(LEMON_HAVE_CBC TRUE)
    3.13 -ENDIF(COIN_FOUND)
     4.1 --- a/cmake/FindCPLEX.cmake	Thu Feb 28 23:45:39 2013 +0100
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,40 +0,0 @@
     4.4 -SET(CPLEX_ROOT_DIR "" CACHE PATH "CPLEX root directory")
     4.5 -
     4.6 -FIND_PATH(CPLEX_INCLUDE_DIR
     4.7 -  ilcplex/cplex.h
     4.8 -  PATHS "C:/ILOG/CPLEX/include"
     4.9 -  PATHS "/opt/ilog/cplex/include"
    4.10 -  HINTS ${CPLEX_ROOT_DIR}/include
    4.11 -)
    4.12 -FIND_LIBRARY(CPLEX_LIBRARY
    4.13 -  cplex
    4.14 -  PATHS "C:/ILOG/CPLEX/lib/msvc7/stat_mda"
    4.15 -  PATHS "/opt/ilog/cplex/bin"
    4.16 -  HINTS ${CPLEX_ROOT_DIR}/bin
    4.17 -  HINTS ${CPLEX_ROOT_DIR}/lib
    4.18 -)
    4.19 -
    4.20 -INCLUDE(FindPackageHandleStandardArgs)
    4.21 -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPLEX DEFAULT_MSG CPLEX_LIBRARY CPLEX_INCLUDE_DIR)
    4.22 -
    4.23 -FIND_PATH(CPLEX_BIN_DIR
    4.24 -  cplex.dll
    4.25 -  PATHS "C:/ILOG/CPLEX/bin/x86_win32"
    4.26 -  HINTS ${CPLEX_ROOT_DIR}/bin
    4.27 -)
    4.28 -
    4.29 -IF(CPLEX_FOUND)
    4.30 -  SET(CPLEX_INCLUDE_DIRS ${CPLEX_INCLUDE_DIR})
    4.31 -  SET(CPLEX_LIBRARIES ${CPLEX_LIBRARY})
    4.32 -  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    4.33 -    SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
    4.34 -  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    4.35 -ENDIF(CPLEX_FOUND)
    4.36 -
    4.37 -MARK_AS_ADVANCED(CPLEX_LIBRARY CPLEX_INCLUDE_DIR CPLEX_BIN_DIR)
    4.38 -
    4.39 -IF(CPLEX_FOUND)
    4.40 -  SET(LEMON_HAVE_LP TRUE)
    4.41 -  SET(LEMON_HAVE_MIP TRUE)
    4.42 -  SET(LEMON_HAVE_CPLEX TRUE)
    4.43 -ENDIF(CPLEX_FOUND)
     5.1 --- a/cmake/FindGLPK.cmake	Thu Feb 28 23:45:39 2013 +0100
     5.2 +++ b/cmake/FindGLPK.cmake	Mon Jul 15 08:33:08 2013 +0200
     5.3 @@ -53,9 +53,3 @@
     5.4  ENDIF(GLPK_FOUND)
     5.5  
     5.6  MARK_AS_ADVANCED(GLPK_LIBRARY GLPK_INCLUDE_DIR GLPK_BIN_DIR)
     5.7 -
     5.8 -IF(GLPK_FOUND)
     5.9 -  SET(LEMON_HAVE_LP TRUE)
    5.10 -  SET(LEMON_HAVE_MIP TRUE)
    5.11 -  SET(LEMON_HAVE_GLPK TRUE)
    5.12 -ENDIF(GLPK_FOUND)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/cmake/FindILOG.cmake	Mon Jul 15 08:33:08 2013 +0200
     6.3 @@ -0,0 +1,102 @@
     6.4 +FIND_PATH(ILOG_ROOT_DIR
     6.5 +  NAMES cplex
     6.6 +  DOC "CPLEX STUDIO root directory"
     6.7 +  PATHS /opt/ibm/ILOG /usr/local/ibm/ILOG /usr/local/ILOG /usr/local/ilog
     6.8 +  PATHS "$ENV{HOME}/ILOG" "$ENV{HOME}/.local/ILOG"
     6.9 +  PATHS "$ENV{HOME}/ibm/ILOG" "$ENV{HOME}/.local/ibm/ILOG"
    6.10 +  PATHS "C:/Program Files/IBM/ILOG" 
    6.11 +  PATH_SUFFIXES "CPLEX_Studio126" "CPLEX_Studio125"
    6.12 +  "CPLEX_Studio124" "CPLEX_Studio123" "CPLEX_Studio122"
    6.13 +  NO_DEFAULT_PATH
    6.14 +)
    6.15 +
    6.16 +IF(WIN32)
    6.17 +  IF(MSVC_VERSION STREQUAL "1400")
    6.18 +    SET(ILOG_WIN_COMPILER "windows_vs2005")
    6.19 +  ELSEIF(MSVC_VERSION STREQUAL "1500")
    6.20 +    SET(ILOG_WIN_COMPILER "windows_vs2008")
    6.21 +  ELSEIF(MSVC_VERSION STREQUAL "1600")
    6.22 +    SET(ILOG_WIN_COMPILER "windows_vs2010")
    6.23 +  ELSE()
    6.24 +    SET(ILOG_WIN_COMPILER "windows_vs2008")
    6.25 +  ENDIF()
    6.26 +  IF(CMAKE_CL_64)
    6.27 +    SET(ILOG_WIN_COMPILER "x64_${ILOG_WIN_COMPILER}")
    6.28 +    SET(ILOG_WIN_PLATFORM "x64_win32")
    6.29 +  ELSE()
    6.30 +    SET(ILOG_WIN_COMPILER "x86_${ILOG_WIN_COMPILER}")
    6.31 +    SET(ILOG_WIN_PLATFORM "x86_win32")
    6.32 +  ENDIF()
    6.33 +ENDIF()
    6.34 +
    6.35 +FIND_PATH(ILOG_CPLEX_ROOT_DIR
    6.36 +  NAMES include/ilcplex
    6.37 +  HINTS ${ILOG_ROOT_DIR}/cplex ${ILOG_ROOT_DIR}/cplex121
    6.38 +  ${ILOG_ROOT_DIR}/cplex122 ${ILOG_ROOT_DIR}/cplex123
    6.39 +  DOC "CPLEX root directory"
    6.40 +  NO_DEFAULT_PATH
    6.41 +)
    6.42 +
    6.43 +FIND_PATH(ILOG_CONCERT_ROOT_DIR
    6.44 +  NAMES include/ilconcert
    6.45 +  HINTS ${ILOG_ROOT_DIR}/concert ${ILOG_ROOT_DIR}/concert29
    6.46 +  DOC "CONCERT root directory"
    6.47 +  NO_DEFAULT_PATH
    6.48 +)
    6.49 +
    6.50 +FIND_PATH(ILOG_CPLEX_INCLUDE_DIR
    6.51 +  ilcplex/cplex.h
    6.52 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/include
    6.53 +  NO_DEFAULT_PATH
    6.54 +)
    6.55 +
    6.56 +FIND_PATH(ILOG_CONCERT_INCLUDE_DIR
    6.57 +  ilconcert/ilobasic.h
    6.58 +  HINTS ${ILOG_CONCERT_ROOT_DIR}/include
    6.59 +  NO_DEFAULT_PATH
    6.60 +)
    6.61 +
    6.62 +FIND_LIBRARY(ILOG_CPLEX_LIBRARY
    6.63 +  cplex cplex121 cplex122 cplex123 cplex124
    6.64 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
    6.65 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
    6.66 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
    6.67 +  ${ILOG_CPLEX_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
    6.68 +  ${ILOG_CPLEX_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
    6.69 +  NO_DEFAULT_PATH
    6.70 +  )
    6.71 +
    6.72 +FIND_LIBRARY(ILOG_CONCERT_LIBRARY
    6.73 +  concert
    6.74 +  HINTS ${ILOG_CONCERT_ROOT_DIR}/lib/x86_sles10_4.1/static_pic
    6.75 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_sles10_4.1/static_pic
    6.76 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86_debian4.0_4.1/static_pic
    6.77 +  ${ILOG_CONCERT_ROOT_DIR}/lib/x86-64_debian4.0_4.1/static_pic
    6.78 +  ${ILOG_CONCERT_ROOT_DIR}/lib/${ILOG_WIN_COMPILER}/stat_mda
    6.79 +  NO_DEFAULT_PATH
    6.80 +  )
    6.81 +
    6.82 +FIND_FILE(ILOG_CPLEX_DLL
    6.83 +  cplex121.dll cplex122.dll cplex123.dll cplex124.dll
    6.84 +  HINTS ${ILOG_CPLEX_ROOT_DIR}/bin/${ILOG_WIN_PLATFORM}
    6.85 +  NO_DEFAULT_PATH
    6.86 +  )
    6.87 +
    6.88 +INCLUDE(FindPackageHandleStandardArgs)
    6.89 +FIND_PACKAGE_HANDLE_STANDARD_ARGS(ILOG
    6.90 +  DEFAULT_MSG ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR
    6.91 +  )
    6.92 +
    6.93 +IF(ILOG_FOUND)
    6.94 +  SET(ILOG_INCLUDE_DIRS ${ILOG_CPLEX_INCLUDE_DIR} ${ILOG_CONCERT_INCLUDE_DIR})
    6.95 +  SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
    6.96 +  IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    6.97 +    # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
    6.98 +    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
    6.99 +  ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
   6.100 +ENDIF(ILOG_FOUND)
   6.101 +
   6.102 +MARK_AS_ADVANCED(
   6.103 +  ILOG_CPLEX_LIBRARY ILOG_CPLEX_INCLUDE_DIR ILOG_CPLEX_DLL
   6.104 +  ILOG_CONCERT_LIBRARY ILOG_CONCERT_INCLUDE_DIR ILOG_CONCERT_DLL
   6.105 +  )
     7.1 --- a/lemon/CMakeLists.txt	Thu Feb 28 23:45:39 2013 +0100
     7.2 +++ b/lemon/CMakeLists.txt	Mon Jul 15 08:33:08 2013 +0200
     7.3 @@ -36,7 +36,7 @@
     7.4  
     7.5  IF(LEMON_HAVE_CPLEX)
     7.6    SET(LEMON_SOURCES ${LEMON_SOURCES} cplex.cc)
     7.7 -  INCLUDE_DIRECTORIES(${CPLEX_INCLUDE_DIRS})
     7.8 +  INCLUDE_DIRECTORIES(${ILOG_INCLUDE_DIRS})
     7.9  ENDIF()
    7.10  
    7.11  IF(LEMON_HAVE_CLP)
     8.1 --- a/lemon/cbc.h	Thu Feb 28 23:45:39 2013 +0100
     8.2 +++ b/lemon/cbc.h	Mon Jul 15 08:33:08 2013 +0200
     8.3 @@ -16,7 +16,6 @@
     8.4   *
     8.5   */
     8.6  
     8.7 -// -*- C++ -*-
     8.8  #ifndef LEMON_CBC_H
     8.9  #define LEMON_CBC_H
    8.10  
     9.1 --- a/lemon/config.h.in	Thu Feb 28 23:45:39 2013 +0100
     9.2 +++ b/lemon/config.h.in	Mon Jul 15 08:33:08 2013 +0200
     9.3 @@ -6,5 +6,7 @@
     9.4  #cmakedefine LEMON_HAVE_CPLEX 1
     9.5  #cmakedefine LEMON_HAVE_CLP 1
     9.6  #cmakedefine LEMON_HAVE_CBC 1
     9.7 +#cmakedefine LEMON_DEFAULT_LP @LEMON_DEFAULT_LP@
     9.8 +#cmakedefine LEMON_DEFAULT_MIP @LEMON_DEFAULT_MIP@
     9.9  #cmakedefine LEMON_USE_PTHREAD 1
    9.10  #cmakedefine LEMON_USE_WIN32_THREADS 1
    10.1 --- a/lemon/cplex.cc	Thu Feb 28 23:45:39 2013 +0100
    10.2 +++ b/lemon/cplex.cc	Mon Jul 15 08:33:08 2013 +0200
    10.3 @@ -492,6 +492,17 @@
    10.4                     _message_enabled ? CPX_ON : CPX_OFF);
    10.5    }
    10.6  
    10.7 +  void CplexBase::_write(std::string file, std::string format) const
    10.8 +  {
    10.9 +    if(format == "MPS" || format == "LP")
   10.10 +      CPXwriteprob(cplexEnv(), cplexLp(), file.c_str(), format.c_str());
   10.11 +    else if(format == "SOL")
   10.12 +      CPXsolwrite(cplexEnv(), cplexLp(), file.c_str());
   10.13 +    else throw UnsupportedFormatError(format);
   10.14 +  }
   10.15 +
   10.16 +
   10.17 +
   10.18    // CplexLp members
   10.19  
   10.20    CplexLp::CplexLp()
    11.1 --- a/lemon/cplex.h	Thu Feb 28 23:45:39 2013 +0100
    11.2 +++ b/lemon/cplex.h	Mon Jul 15 08:33:08 2013 +0200
    11.3 @@ -150,6 +150,8 @@
    11.4  
    11.5      bool _message_enabled;
    11.6  
    11.7 +    void _write(std::string file, std::string format) const;
    11.8 +
    11.9    public:
   11.10  
   11.11      /// Returns the used \c CplexEnv instance
   11.12 @@ -170,6 +172,19 @@
   11.13      /// Returns the cplex problem object
   11.14      const cpxlp* cplexLp() const { return _prob; }
   11.15  
   11.16 +#ifdef DOXYGEN
   11.17 +    /// Write the problem or the solution to a file in the given format
   11.18 +
   11.19 +    /// This function writes the problem or the solution
   11.20 +    /// to a file in the given format.
   11.21 +    /// Trying to write in an unsupported format will trigger
   11.22 +    /// \ref UnsupportedFormatError.
   11.23 +    /// \param file The file path
   11.24 +    /// \param format The output file format.
   11.25 +    /// Supportted formats are "MPS", "LP" and "SOL".
   11.26 +    void write(std::string file, std::string format = "MPS") const {}
   11.27 +#endif
   11.28 +
   11.29    };
   11.30  
   11.31    /// \brief Interface for the CPLEX LP solver
    12.1 --- a/lemon/glpk.cc	Thu Feb 28 23:45:39 2013 +0100
    12.2 +++ b/lemon/glpk.cc	Mon Jul 15 08:33:08 2013 +0200
    12.3 @@ -582,6 +582,15 @@
    12.4      }
    12.5    }
    12.6  
    12.7 +  void GlpkBase::_write(std::string file, std::string format) const
    12.8 +  {
    12.9 +    if(format == "MPS")
   12.10 +      glp_write_mps(lp, GLP_MPS_FILE, 0, file.c_str());
   12.11 +    else if(format == "LP")
   12.12 +      glp_write_lp(lp, 0, file.c_str());
   12.13 +    else throw UnsupportedFormatError(format);
   12.14 +  }
   12.15 +
   12.16    GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
   12.17  
   12.18    // GlpkLp members
   12.19 @@ -998,4 +1007,6 @@
   12.20  
   12.21    const char* GlpkMip::_solverName() const { return "GlpkMip"; }
   12.22  
   12.23 +
   12.24 +
   12.25  } //END OF NAMESPACE LEMON
    13.1 --- a/lemon/glpk.h	Thu Feb 28 23:45:39 2013 +0100
    13.2 +++ b/lemon/glpk.h	Mon Jul 15 08:33:08 2013 +0200
    13.3 @@ -115,6 +115,8 @@
    13.4  
    13.5      virtual void _messageLevel(MessageLevel level);
    13.6  
    13.7 +    virtual void _write(std::string file, std::string format) const;
    13.8 +
    13.9    private:
   13.10  
   13.11      static void freeEnv();
   13.12 @@ -144,6 +146,19 @@
   13.13      ///Returns the variable identifier understood by GLPK.
   13.14      int lpxCol(Col c) const { return cols(id(c)); }
   13.15  
   13.16 +#ifdef DOXYGEN
   13.17 +    /// Write the problem or the solution to a file in the given format
   13.18 +    
   13.19 +    /// This function writes the problem or the solution
   13.20 +    /// to a file in the given format.
   13.21 +    /// Trying to write in an unsupported format will trigger
   13.22 +    /// \ref UnsupportedFormatError.
   13.23 +    /// \param file The file path
   13.24 +    /// \param format The output file format.
   13.25 +    /// Supportted formats are "MPS" and "LP".
   13.26 +    void write(std::string file, std::string format = "MPS") const {}
   13.27 +#endif
   13.28 +
   13.29    };
   13.30  
   13.31    /// \brief Interface for the GLPK LP solver
    14.1 --- a/lemon/lp.h	Thu Feb 28 23:45:39 2013 +0100
    14.2 +++ b/lemon/lp.h	Mon Jul 15 08:33:08 2013 +0200
    14.3 @@ -59,32 +59,31 @@
    14.4    ///The default MIP solver identifier.
    14.5    ///\ingroup lp_group
    14.6    ///
    14.7 -  ///Currently, the possible values are \c GLPK or \c CPLEX
    14.8 +  ///Currently, the possible values are \c GLPK, \c CPLEX or \c CBC
    14.9  #define LEMON_DEFAULT_MIP SOLVER
   14.10    ///The default MIP solver.
   14.11  
   14.12    ///The default MIP solver.
   14.13    ///\ingroup lp_group
   14.14    ///
   14.15 -  ///Currently, it is either \c GlpkMip or \c CplexMip
   14.16 +  ///Currently, it is either \c GlpkMip, \c CplexMip , \c CbcMip
   14.17    typedef GlpkMip Mip;
   14.18  #else
   14.19 -#ifdef LEMON_HAVE_GLPK
   14.20 -# define LEMON_DEFAULT_LP GLPK
   14.21 +#if LEMON_DEFAULT_LP == GLPK
   14.22    typedef GlpkLp Lp;
   14.23 -# define LEMON_DEFAULT_MIP GLPK
   14.24 -  typedef GlpkMip Mip;
   14.25 -#elif LEMON_HAVE_CPLEX
   14.26 -# define LEMON_DEFAULT_LP CPLEX
   14.27 +#elif LEMON_DEFAULT_LP == CPLEX
   14.28    typedef CplexLp Lp;
   14.29 -# define LEMON_DEFAULT_MIP CPLEX
   14.30 +#elif LEMON_DEFAULT_LP == SOPLEX
   14.31 +  typedef SoplexLp Lp;
   14.32 +#elif LEMON_DEFAULT_LP == CLP
   14.33 +  typedef ClpLp Lp;
   14.34 +#endif
   14.35 +#if LEMON_DEFAULT_MIP == GLPK
   14.36 +  typedef GlpkLp Mip;
   14.37 +#elif LEMON_DEFAULT_MIP == CPLEX
   14.38    typedef CplexMip Mip;
   14.39 -#elif LEMON_HAVE_SOPLEX
   14.40 -# define DEFAULT_LP SOPLEX
   14.41 -  typedef SoplexLp Lp;
   14.42 -#elif LEMON_HAVE_CLP
   14.43 -# define DEFAULT_LP CLP
   14.44 -  typedef ClpLp Lp;
   14.45 +#elif LEMON_DEFAULT_MIP == CBC
   14.46 +  typedef CbcMip Mip;
   14.47  #endif
   14.48  #endif
   14.49  
    15.1 --- a/lemon/lp_base.h	Thu Feb 28 23:45:39 2013 +0100
    15.2 +++ b/lemon/lp_base.h	Mon Jul 15 08:33:08 2013 +0200
    15.3 @@ -1007,6 +1007,36 @@
    15.4  
    15.5    public:
    15.6  
    15.7 +    ///\e
    15.8 +    class UnsupportedFormatError : public Exception
    15.9 +    {
   15.10 +      std::string _format;
   15.11 +      mutable std::string _what;
   15.12 +    public:
   15.13 +      explicit UnsupportedFormatError(std::string format) throw()
   15.14 +        : _format(format) { }
   15.15 +      virtual ~UnsupportedFormatError() throw() {}
   15.16 +      virtual const char* what() const throw() {
   15.17 +        try {
   15.18 +          _what.clear();
   15.19 +          std::ostringstream oss;
   15.20 +          oss << "lemon::UnsupportedFormatError: " << _format;
   15.21 +          _what = oss.str();
   15.22 +        }
   15.23 +        catch (...) {}
   15.24 +        if (!_what.empty()) return _what.c_str();
   15.25 +        else return "lemon::UnsupportedFormatError";
   15.26 +      }
   15.27 +    };
   15.28 +    
   15.29 +  protected:
   15.30 +    virtual void _write(std::string, std::string format) const
   15.31 +    {
   15.32 +      throw UnsupportedFormatError(format);
   15.33 +    }
   15.34 +    
   15.35 +  public:
   15.36 +
   15.37      /// Virtual destructor
   15.38      virtual ~LpBase() {}
   15.39  
   15.40 @@ -1555,12 +1585,27 @@
   15.41      ///Set the sense to maximization
   15.42      void min() { _setSense(MIN); }
   15.43  
   15.44 -    ///Clears the problem
   15.45 +    ///Clear the problem
   15.46      void clear() { _clear(); rows.clear(); cols.clear(); }
   15.47  
   15.48 -    /// Sets the message level of the solver
   15.49 +    /// Set the message level of the solver
   15.50      void messageLevel(MessageLevel level) { _messageLevel(level); }
   15.51  
   15.52 +    /// Write the problem to a file in the given format
   15.53 +
   15.54 +    /// This function writes the problem to a file in the given format.
   15.55 +    /// Different solver backends may support different formats.
   15.56 +    /// Trying to write in an unsupported format will trigger
   15.57 +    /// \ref UnsupportedFormatError. For the supported formats,
   15.58 +    /// visit the documentation of the base class of the related backends
   15.59 +    /// (\ref CplexBase, \ref GlpkBase etc.)
   15.60 +    /// \param file The file path
   15.61 +    /// \param format The output file format.
   15.62 +    void write(std::string file, std::string format = "MPS") const
   15.63 +    {
   15.64 +      _write(file.c_str(),format.c_str());
   15.65 +    }
   15.66 +
   15.67      ///@}
   15.68  
   15.69    };
    16.1 --- a/lemon/lp_skeleton.cc	Thu Feb 28 23:45:39 2013 +0100
    16.2 +++ b/lemon/lp_skeleton.cc	Mon Jul 15 08:33:08 2013 +0200
    16.3 @@ -91,6 +91,8 @@
    16.4  
    16.5    void SkeletonSolverBase::_messageLevel(MessageLevel) {}
    16.6  
    16.7 +  void SkeletonSolverBase::_write(std::string, std::string) const {}
    16.8 +
    16.9    LpSkeleton::SolveExitStatus LpSkeleton::_solve() { return SOLVED; }
   16.10  
   16.11    LpSkeleton::Value LpSkeleton::_getPrimal(int) const { return 0; }
    17.1 --- a/lemon/lp_skeleton.h	Thu Feb 28 23:45:39 2013 +0100
    17.2 +++ b/lemon/lp_skeleton.h	Mon Jul 15 08:33:08 2013 +0200
    17.3 @@ -144,6 +144,10 @@
    17.4  
    17.5      ///\e
    17.6      virtual void _messageLevel(MessageLevel);
    17.7 +
    17.8 +    ///\e
    17.9 +    virtual void _write(std::string file, std::string format) const;
   17.10 +
   17.11    };
   17.12  
   17.13    /// \brief Skeleton class for an LP solver interface
   17.14 @@ -222,6 +226,7 @@
   17.15  
   17.16      ///\e
   17.17      virtual const char* _solverName() const;
   17.18 +
   17.19    };
   17.20  
   17.21  } //namespace lemon
    18.1 --- a/test/CMakeLists.txt	Thu Feb 28 23:45:39 2013 +0100
    18.2 +++ b/test/CMakeLists.txt	Mon Jul 15 08:33:08 2013 +0200
    18.3 @@ -69,7 +69,7 @@
    18.4      SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${GLPK_LIBRARIES})
    18.5    ENDIF()
    18.6    IF(LEMON_HAVE_CPLEX)
    18.7 -    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${CPLEX_LIBRARIES})
    18.8 +    SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${ILOG_LIBRARIES})
    18.9    ENDIF()
   18.10    IF(LEMON_HAVE_CLP)
   18.11      SET(LP_TEST_LIBS ${LP_TEST_LIBS} ${COIN_CLP_LIBRARIES})
   18.12 @@ -93,7 +93,7 @@
   18.13      GET_TARGET_PROPERTY(TARGET_LOC lp_test LOCATION)
   18.14      GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
   18.15      ADD_CUSTOM_COMMAND(TARGET lp_test POST_BUILD
   18.16 -      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
   18.17 +      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
   18.18      )
   18.19    ENDIF()
   18.20  ENDIF()
   18.21 @@ -111,7 +111,7 @@
   18.22      SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${GLPK_LIBRARIES})
   18.23    ENDIF()
   18.24    IF(LEMON_HAVE_CPLEX)
   18.25 -    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${CPLEX_LIBRARIES})
   18.26 +    SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${ILOG_LIBRARIES})
   18.27    ENDIF()
   18.28    IF(LEMON_HAVE_CBC)
   18.29      SET(MIP_TEST_LIBS ${MIP_TEST_LIBS} ${COIN_CBC_LIBRARIES})
   18.30 @@ -135,7 +135,7 @@
   18.31      GET_TARGET_PROPERTY(TARGET_LOC mip_test LOCATION)
   18.32      GET_FILENAME_COMPONENT(TARGET_PATH ${TARGET_LOC} PATH)
   18.33      ADD_CUSTOM_COMMAND(TARGET mip_test POST_BUILD
   18.34 -      COMMAND ${CMAKE_COMMAND} -E copy ${CPLEX_BIN_DIR}/cplex.dll ${TARGET_PATH}
   18.35 +      COMMAND ${CMAKE_COMMAND} -E copy ${ILOG_CPLEX_DLL} ${TARGET_PATH}
   18.36      )
   18.37    ENDIF()
   18.38  ENDIF()
    19.1 --- a/test/lp_test.cc	Thu Feb 28 23:45:39 2013 +0100
    19.2 +++ b/test/lp_test.cc	Mon Jul 15 08:33:08 2013 +0200
    19.3 @@ -240,8 +240,7 @@
    19.4  
    19.5    {
    19.6      LP::DualExpr e,f,g;
    19.7 -    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
    19.8 -      p4 = INVALID, p5 = INVALID;
    19.9 +    LP::Row p1 = INVALID, p2 = INVALID;
   19.10  
   19.11      e[p1]=2;
   19.12      e[p1]+=2;