# HG changeset patch # User athos # Date 1158849988 0 # Node ID 50f1a780a5ff10bafbadc99febf50966d3650b9d # Parent 4a10a45d55f6f9e3d75b32a8738db1fe58caa3dc Interface to the cplex MIP solver: it is little, a bit sour but it is ours. diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/Makefile.am --- a/lemon/Makefile.am Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/Makefile.am Thu Sep 21 14:46:28 2006 +0000 @@ -25,6 +25,7 @@ if HAVE_CPLEX lemon_libemon_la_SOURCES += lemon/lp_cplex.cc +lemon_libemon_la_SOURCES += lemon/mip_cplex.cc endif lemon_HEADERS += \ @@ -78,6 +79,7 @@ lemon/min_cost_flow.h \ lemon/min_cut.h \ lemon/mip_glpk.h \ + lemon/mip_cplex.h \ lemon/path.h \ lemon/polynomial.h \ lemon/preflow.h \ diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/lp.h --- a/lemon/lp.h Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/lp.h Thu Sep 21 14:46:28 2006 +0000 @@ -21,18 +21,20 @@ #include + #ifdef HAVE_GLPK #include #include #elif HAVE_CPLEX #include +#include #endif ///\file ///\brief Defines a default LP solver ///\ingroup gen_opt_group namespace lemon { - + #ifdef DOXYGEN ///The default LP solver identifier @@ -72,6 +74,7 @@ #elif HAVE_CPLEX #define DEFAULT_LP CPLEX typedef LpCplex Lp; + typedef MipCplex Mip; const char default_solver_name[]="CPLEX"; #endif #endif diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/lp_base.h --- a/lemon/lp_base.h Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/lp_base.h Thu Sep 21 14:46:28 2006 +0000 @@ -75,8 +75,10 @@ } return cross[n]; } - ///\todo Create an own exception type. - else throw LogicError(); //floatingId-s must form a continuous range; + else { + ///\todo Create an own exception type. + throw LogicError(); //floatingId-s must form a continuous range; + } } ///Remove a fix id. @@ -1169,7 +1171,10 @@ ///Continuous variable REAL = 0, ///Integer variable - INTEGER = 1 + + ///Unfortunately, cplex 7.5 somewhere writes something like + ///#define INTEGER 'I' + LEMON_INTEGER = 1 ///\todo No support for other types yet. }; @@ -1192,7 +1197,7 @@ ///Sets the type of the given Col to integer or remove that property. void integer(Col c, bool enable) { if (enable) - colType(c,INTEGER); + colType(c,LEMON_INTEGER); else colType(c,REAL); } @@ -1202,7 +1207,7 @@ ///Gives back the type of the column. ///\return true if the column has integer type and false if not. bool integer(Col c){ - return (colType(c)==INTEGER); + return (colType(c)==LEMON_INTEGER); } /// The status of the MIP problem diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/lp_cplex.cc --- a/lemon/lp_cplex.cc Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/lp_cplex.cc Thu Sep 21 14:46:28 2006 +0000 @@ -269,7 +269,7 @@ //CPX_PARAM_LPMETHOD status = CPXlpopt(env, lp); //status = CPXprimopt(env, lp); -#if CPX_VERSION >= 900 +#if CPX_VERSION >= 800 if (status) { return UNSOLVED; @@ -416,8 +416,23 @@ LpCplex::SolutionStatus LpCplex::_getPrimalStatus() { + //Unboundedness not treated well: the following is from cplex 9.0 doc + // About Unboundedness + + // The treatment of models that are unbounded involves a few + // subtleties. Specifically, a declaration of unboundedness means that + // ILOG CPLEX has determined that the model has an unbounded + // ray. Given any feasible solution x with objective z, a multiple of + // the unbounded ray can be added to x to give a feasible solution + // with objective z-1 (or z+1 for maximization models). Thus, if a + // feasible solution exists, then the optimal objective is + // unbounded. Note that ILOG CPLEX has not necessarily concluded that + // a feasible solution exists. Users can call the routine CPXsolninfo + // to determine whether ILOG CPLEX has also concluded that the model + // has a feasible solution. + int stat = CPXgetstat(env, lp); -#if CPX_VERSION >= 900 +#if CPX_VERSION >= 800 switch (stat) { case CPX_STAT_OPTIMAL: @@ -485,7 +500,7 @@ LpCplex::SolutionStatus LpCplex::_getDualStatus() { int stat = CPXgetstat(env, lp); -#if CPX_VERSION >= 900 +#if CPX_VERSION >= 800 switch (stat) { case CPX_STAT_OPTIMAL: @@ -514,7 +529,7 @@ LpCplex::ProblemTypes LpCplex::_getProblemType() { int stat = CPXgetstat(env, lp); -#if CPX_VERSION >= 900 +#if CPX_VERSION >= 800 switch (stat) { case CPX_STAT_OPTIMAL: diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/lp_cplex.h --- a/lemon/lp_cplex.h Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/lp_cplex.h Thu Sep 21 14:46:28 2006 +0000 @@ -34,7 +34,7 @@ /// \brief Interface for the CPLEX solver /// /// This class implements an interface for the CPLEX LP solver. - class LpCplex : public LpSolverBase { + class LpCplex :virtual public LpSolverBase { public: diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/mip_glpk.cc --- a/lemon/mip_glpk.cc Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/mip_glpk.cc Thu Sep 21 14:46:28 2006 +0000 @@ -16,11 +16,11 @@ * */ -#ifndef LEMON_ILP_GLPK_CC -#define LEMON_ILP_GLPK_CC +#ifndef LEMON_MIP_GLPK_CC +#define LEMON_MIP_GLPK_CC ///\file -///\brief Implementation of the LEMON-GLPK lp solver interface. +///\brief Implementation of the LEMON-GLPK mip solver interface. #include @@ -32,7 +32,7 @@ void MipGlpk::_colType(int i, MipGlpk::ColTypes col_type){ switch (col_type){ - case INTEGER: + case LEMON_INTEGER: lpx_set_col_kind(lp,i,LPX_IV); break; case REAL: @@ -46,7 +46,7 @@ MipGlpk::ColTypes MipGlpk::_colType(int i){ switch (lpx_get_col_kind(lp,i)){ case LPX_IV: - return INTEGER;//Or binary + return LEMON_INTEGER;//Or binary case LPX_CV: return REAL; default: @@ -110,6 +110,6 @@ MipGlpk::Value MipGlpk::_getPrimalValue(){ return lpx_mip_obj_val(lp); } -} //END OG NAMESPACE LEMON +} //END OF NAMESPACE LEMON -#endif +#endif //END OF MIP_GLPK_CC diff -r 4a10a45d55f6 -r 50f1a780a5ff lemon/mip_glpk.h --- a/lemon/mip_glpk.h Thu Sep 14 19:58:29 2006 +0000 +++ b/lemon/mip_glpk.h Thu Sep 21 14:46:28 2006 +0000 @@ -16,20 +16,20 @@ * */ -#ifndef LEMON_ILP_GLPK_H -#define LEMON_ILP_GLPK_H +#ifndef LEMON_MIP_GLPK_H +#define LEMON_MIP_GLPK_H ///\file -///\brief Header of the LEMON-GLPK lp solver interface. +///\brief Header of the LEMON-GLPK mip solver interface. ///\ingroup gen_opt_group #include namespace lemon { - /// \brief Interface for the GLPK ILP solver + /// \brief Interface for the GLPK MIP solver /// - /// This class implements an interface for the GLPK ILP solver. + /// This class implements an interface for the GLPK MIP solver. ///\ingroup gen_opt_group class MipGlpk : public MipSolverBase, public LpGlpk{ @@ -56,4 +56,4 @@ } //END OF NAMESPACE LEMON -#endif // END OF LEMON_ILP_GLPK_H +#endif // END OF LEMON_MIP_GLPK_H diff -r 4a10a45d55f6 -r 50f1a780a5ff test/mip_test.cc --- a/test/mip_test.cc Thu Sep 14 19:58:29 2006 +0000 +++ b/test/mip_test.cc Thu Sep 21 14:46:28 2006 +0000 @@ -1,20 +1,26 @@ -#include #include "test_tools.h" + +#include +#include +#include + using namespace lemon; -void solveAndCheck(Mip& lp, LpSolverBase::SolutionStatus stat, +void solveAndCheck(MipSolverBase& lp, MipSolverBase::SolutionStatus stat, double exp_opt) { using std::string; + lp.solve(); //int decimal,sign; std::ostringstream buf; buf << "Primalstatus should be: " << int(stat)<<" and it is "<