diff -r e4ec01f1a4cd -r 852361980706 lemon/lp_cplex.cc --- a/lemon/lp_cplex.cc Tue Apr 08 15:16:16 2008 +0000 +++ b/lemon/lp_cplex.cc Tue Apr 08 16:01:28 2008 +0000 @@ -17,47 +17,47 @@ */ #include +#include #include ///\file ///\brief Implementation of the LEMON-CPLEX lp solver interface. namespace lemon { - LpCplex::LpCplex() : LpSolverBase() { + LpCplex::LpCplex() { // env = CPXopenCPLEXdevelop(&status); env = CPXopenCPLEX(&status); lp = CPXcreateprob(env, &status, "LP problem"); } + + LpCplex::LpCplex(const LpCplex& cplex) : LpSolverBase() { + env = CPXopenCPLEX(&status); + lp = CPXcloneprob(env, cplex.lp, &status); + rows = cplex.rows; + cols = cplex.cols; + } LpCplex::~LpCplex() { - CPXfreeprob(env,&lp); - CPXcloseCPLEX(&env); + CPXfreeprob(env,&lp); + CPXcloseCPLEX(&env); } - LpSolverBase &LpCplex::_newLp() + LpSolverBase* LpCplex::_newLp() { //The first approach opens a new environment - LpCplex* newlp=new LpCplex(); - return *newlp; + return new LpCplex(); } - LpSolverBase &LpCplex::_copyLp() { - ///\bug FixID data is not copied! - //The first approach opens a new environment - LpCplex* newlp=new LpCplex(); - //The routine CPXcloneprob can be used to create a new CPLEX problem - //object and copy all the problem data from an existing problem - //object to it. Solution and starting information is not copied. - newlp->lp = CPXcloneprob(env, lp, &status); - return *newlp; + LpSolverBase* LpCplex::_copyLp() { + return new LpCplex(*this); } int LpCplex::_addCol() { int i = CPXgetnumcols(env, lp); Value lb[1],ub[1]; - lb[0]=-INF;//-CPX_INFBOUND; - ub[0]=INF;//CPX_INFBOUND; + lb[0]=-INF; + ub[0]=INF; status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL); return i; } @@ -89,7 +89,11 @@ ///\bug Untested int storespace; CPXgetcolname(env, lp, 0, 0, 0, &storespace, col, col); - + if (storespace == 0) { + name.clear(); + return; + } + storespace *= -1; std::vector buf(storespace); char *names[1]; @@ -136,6 +140,21 @@ } void LpCplex::_getRowCoeffs(int i, RowIterator b) const { + int tmp1, tmp2, tmp3, length; + CPXgetrows(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i); + + length = -length; + std::vector indices(length); + std::vector values(length); + + CPXgetrows(env, lp, &tmp1, &tmp2, &indices[0], &values[0], + length, &tmp3, i, i); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + /// \todo implement } @@ -156,7 +175,22 @@ } void LpCplex::_getColCoeffs(int i, ColIterator b) const { - /// \todo implement + + int tmp1, tmp2, tmp3, length; + CPXgetcols(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i); + + length = -length; + std::vector indices(length); + std::vector values(length); + + CPXgetcols(env, lp, &tmp1, &tmp2, &indices[0], &values[0], + length, &tmp3, i, i); + + for (int i = 0; i < length; ++i) { + *b = std::make_pair(indices[i], values[i]); + ++b; + } + } void LpCplex::_setCoeff(int row, int col, Value value) @@ -187,6 +221,7 @@ { LpCplex::Value x; CPXgetlb (env, lp, &x, i, i); + if (x <= -CPX_INFBOUND) x = -INF; return x; } @@ -205,6 +240,7 @@ { LpCplex::Value x; CPXgetub (env, lp, &x, i, i); + if (x >= CPX_INFBOUND) x = INF; return x; } @@ -469,8 +505,8 @@ // Default: 0 // Description: Method for linear optimization. // Determines which algorithm is used when CPXlpopt() (or "optimize" in the Interactive Optimizer) is called. Currently the behavior of the "Automatic" setting is that CPLEX simply invokes the dual simplex method, but this capability may be expanded in the future so that CPLEX chooses the method based on problem characteristics +#if CPX_VERSION < 900 void statusSwitch(CPXENVptr env,int& stat){ -#if CPX_VERSION < 900 int lpmethod; CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod); if (lpmethod==2){ @@ -482,8 +518,10 @@ stat=CPX_UNBOUNDED; } } + } +#else + void statusSwitch(CPXENVptr,int&){} #endif - } LpCplex::SolutionStatus LpCplex::_getPrimalStatus() const {