# HG changeset patch # User Alpar Juttner # Date 1611251917 -3600 # Node ID eba5aa390aca48b621b6c9689f90c4a53b70ce5b # Parent 736a341e604b983e4ae9f4f47120fad0bef131c7# Parent 86a5b114a0662ff7857949add3f38c1053b2c02a Merge #640 diff -r 736a341e604b -r eba5aa390aca cmake/FindILOG.cmake --- a/cmake/FindILOG.cmake Thu Jan 21 08:36:53 2021 +0100 +++ b/cmake/FindILOG.cmake Thu Jan 21 18:58:37 2021 +0100 @@ -96,7 +96,7 @@ SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY}) IF(CMAKE_SYSTEM_NAME STREQUAL "Linux") # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread") - SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread") + SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread" "dl") ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux") ENDIF(ILOG_FOUND) diff -r 736a341e604b -r eba5aa390aca lemon/clp.cc --- a/lemon/clp.cc Thu Jan 21 08:36:53 2021 +0100 +++ b/lemon/clp.cc Thu Jan 21 18:58:37 2021 +0100 @@ -227,14 +227,14 @@ } ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const { - CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix]; - CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix]; + CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[jx]; + CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[jx]; const int* indices = _prob->clpMatrix()->getIndices(); const double* elements = _prob->clpMatrix()->getElements(); - const int* it = std::lower_bound(indices + begin, indices + end, jx); - if (it != indices + end && *it == jx) { + const int* it = std::lower_bound(indices + begin, indices + end, ix); + if (it != indices + end && *it == ix) { return elements[it - indices]; } else { return 0.0; @@ -461,4 +461,14 @@ } } + void ClpLp::_write(std::string file, std::string format) const + { + if(format == "LP") + _prob->writeLp(file.c_str(), "", 1e-5, 10, 5, + sense()==ClpLp::MIN?1:-1, + true + ); + else throw UnsupportedFormatError(format); + } + } //END OF NAMESPACE LEMON diff -r 736a341e604b -r eba5aa390aca lemon/clp.h --- a/lemon/clp.h Thu Jan 21 08:36:53 2021 +0100 +++ b/lemon/clp.h Thu Jan 21 18:58:37 2021 +0100 @@ -139,6 +139,8 @@ virtual void _messageLevel(MessageLevel); + void _write(std::string file, std::string format) const; + public: ///Solves LP with primal simplex method. diff -r 736a341e604b -r eba5aa390aca lemon/cplex.cc --- a/lemon/cplex.cc Thu Jan 21 08:36:53 2021 +0100 +++ b/lemon/cplex.cc Thu Jan 21 18:58:37 2021 +0100 @@ -158,7 +158,7 @@ } else { const char s = 'R'; double len = ub - lb; - CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &ub, &s, + CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &lb, &s, &rmatbeg, &indices.front(), &values.front(), 0, 0); CPXchgrngval(cplexEnv(), _prob, 1, &i, &len); } diff -r 736a341e604b -r eba5aa390aca test/lp_test.cc --- a/test/lp_test.cc Thu Jan 21 08:36:53 2021 +0100 +++ b/test/lp_test.cc Thu Jan 21 18:58:37 2021 +0100 @@ -339,6 +339,7 @@ check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!"); check(lp.sense() == lp.MAX,"This is a maximization!"); check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!"); + check(lp.coeff(upright,x2)==2,"The coefficient in question is 1!"); check(lp.colLowerBound(x1)==0, "The lower bound for variable x1 should be 0."); check(lp.colUpperBound(x1)==LpSolver::INF, @@ -424,6 +425,34 @@ delete lpclone; } +template +void rangeConstraintTest() +{ + LP lp; + // Add two columns (variables) to the problem + typename LP::Col x1 = lp.addCol(); + typename LP::Col x2 = lp.addCol(); + // Add rows (constraints) to the problem + lp.addRow(x1 - 5 <= x2); + lp.addRow(0 <= 2 * x1 + x2 <= 25); + + // Set lower and upper bounds for the columns (variables) + lp.colLowerBound(x1, 0); + lp.colUpperBound(x2, 10); + + // Specify the objective function + lp.max(); + lp.obj(5 * x1 + 3 * x2); + + // Solve the problem using the underlying LP solver + lp.solve(); + // Print the results + check(lp.primalType() == LP::OPTIMAL, "Optimal solution is not found"); + check(lp.primal() <= 67.501 && lp.primal() >= 67.499, "Wrong objective value"); + check(lp.primal(x1) <= 7.501 && lp.primal(x1) >= 7.499, "Wrong value for x1"); + check(lp.primal(x2) <= 10.001 && lp.primal(x2) >= 9.999, "Wrong value for x2"); +} + int main() { LpSkeleton lp_skel; @@ -444,6 +473,7 @@ lpTest(lp_glpk1); aTest(lp_glpk2); cloneTest(); + rangeConstraintTest(); } #endif @@ -453,6 +483,7 @@ lpTest(lp_cplex1); aTest(lp_cplex2); cloneTest(); + rangeConstraintTest(); } catch (CplexEnv::LicenseError& error) { check(false, error.what()); } @@ -464,6 +495,7 @@ lpTest(lp_soplex1); aTest(lp_soplex2); cloneTest(); + rangeConstraintTest(); } #endif @@ -473,6 +505,7 @@ lpTest(lp_clp1); aTest(lp_clp2); cloneTest(); + rangeConstraintTest(); } #endif diff -r 736a341e604b -r eba5aa390aca test/mip_test.cc --- a/test/mip_test.cc Thu Jan 21 08:36:53 2021 +0100 +++ b/test/mip_test.cc Thu Jan 21 18:58:37 2021 +0100 @@ -61,7 +61,7 @@ } } -void aTest(MipSolver& mip) +void aTest(MipSolver& mip, bool solve_empty=true) { //The following example is very simple @@ -80,7 +80,8 @@ mip.max(); //Unconstrained optimization - mip.solve(); + if(solve_empty) + mip.solve(); //Check it out! //Constraints @@ -135,7 +136,11 @@ #ifdef LEMON_HAVE_MIP { Mip mip1; +#if LEMON_DEFAULT_MIP==LEMON_CBC_ + aTest(mip1, false); +#else aTest(mip1); +#endif cloneTest(); } #endif @@ -161,7 +166,7 @@ #ifdef LEMON_HAVE_CBC { CbcMip mip1; - aTest(mip1); + aTest(mip1, false); cloneTest(); } #endif