Bugfixes in CplexBase and ClpLp (#639)
authorAlpar Juttner <alpar@cs.elte.hu>
Wed, 20 Jan 2021 16:17:21 +0100
changeset 142757abff252556
parent 1423 8c567e298d7f
child 1428 86a5b114a066
Bugfixes in CplexBase and ClpLp (#639)
cmake/FindILOG.cmake
lemon/clp.cc
lemon/cplex.cc
test/lp_test.cc
test/mip_test.cc
     1.1 --- a/cmake/FindILOG.cmake	Sat Oct 27 13:00:48 2018 +0200
     1.2 +++ b/cmake/FindILOG.cmake	Wed Jan 20 16:17:21 2021 +0100
     1.3 @@ -96,7 +96,7 @@
     1.4    SET(ILOG_LIBRARIES ${ILOG_CPLEX_LIBRARY} ${ILOG_CONCERT_LIBRARY})
     1.5    IF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
     1.6      # SET(CPLEX_LIBRARIES "${CPLEX_LIBRARIES};m;pthread")
     1.7 -    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread")
     1.8 +    SET(ILOG_LIBRARIES ${ILOG_LIBRARIES} "m" "pthread" "dl")
     1.9    ENDIF(CMAKE_SYSTEM_NAME STREQUAL "Linux")
    1.10  ENDIF(ILOG_FOUND)
    1.11  
     2.1 --- a/lemon/clp.cc	Sat Oct 27 13:00:48 2018 +0200
     2.2 +++ b/lemon/clp.cc	Wed Jan 20 16:17:21 2021 +0100
     2.3 @@ -227,14 +227,14 @@
     2.4    }
     2.5  
     2.6    ClpLp::Value ClpLp::_getCoeff(int ix, int jx) const {
     2.7 -    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[ix];
     2.8 -    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[ix];
     2.9 +    CoinBigIndex begin = _prob->clpMatrix()->getVectorStarts()[jx];
    2.10 +    CoinBigIndex end = begin + _prob->clpMatrix()->getVectorLengths()[jx];
    2.11  
    2.12      const int* indices = _prob->clpMatrix()->getIndices();
    2.13      const double* elements = _prob->clpMatrix()->getElements();
    2.14  
    2.15 -    const int* it = std::lower_bound(indices + begin, indices + end, jx);
    2.16 -    if (it != indices + end && *it == jx) {
    2.17 +    const int* it = std::lower_bound(indices + begin, indices + end, ix);
    2.18 +    if (it != indices + end && *it == ix) {
    2.19        return elements[it - indices];
    2.20      } else {
    2.21        return 0.0;
     3.1 --- a/lemon/cplex.cc	Sat Oct 27 13:00:48 2018 +0200
     3.2 +++ b/lemon/cplex.cc	Wed Jan 20 16:17:21 2021 +0100
     3.3 @@ -158,7 +158,7 @@
     3.4      } else {
     3.5        const char s = 'R';
     3.6        double len = ub - lb;
     3.7 -      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &ub, &s,
     3.8 +      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &lb, &s,
     3.9                   &rmatbeg, &indices.front(), &values.front(), 0, 0);
    3.10        CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
    3.11      }
     4.1 --- a/test/lp_test.cc	Sat Oct 27 13:00:48 2018 +0200
     4.2 +++ b/test/lp_test.cc	Wed Jan 20 16:17:21 2021 +0100
     4.3 @@ -339,6 +339,7 @@
     4.4    check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
     4.5    check(lp.sense() == lp.MAX,"This is a maximization!");
     4.6    check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
     4.7 +  check(lp.coeff(upright,x2)==2,"The coefficient in question is 1!");
     4.8    check(lp.colLowerBound(x1)==0,
     4.9          "The lower bound for variable x1 should be 0.");
    4.10    check(lp.colUpperBound(x1)==LpSolver::INF,
    4.11 @@ -424,6 +425,34 @@
    4.12    delete lpclone;
    4.13  }
    4.14  
    4.15 +template<class LP>
    4.16 +void rangeConstraintTest()
    4.17 +{
    4.18 +  LP lp;
    4.19 +  // Add two columns (variables) to the problem
    4.20 +  typename LP::Col x1 = lp.addCol();
    4.21 +  typename LP::Col x2 = lp.addCol();
    4.22 +  // Add rows (constraints) to the problem
    4.23 +  lp.addRow(x1 - 5 <= x2);
    4.24 +    lp.addRow(0 <= 2 * x1 + x2 <= 25);
    4.25 +  
    4.26 +  // Set lower and upper bounds for the columns (variables)
    4.27 +  lp.colLowerBound(x1, 0);
    4.28 +  lp.colUpperBound(x2, 10);
    4.29 +  
    4.30 +  // Specify the objective function
    4.31 +  lp.max();
    4.32 +  lp.obj(5 * x1 + 3 * x2);
    4.33 +  
    4.34 +  // Solve the problem using the underlying LP solver
    4.35 +  lp.solve();
    4.36 +  // Print the results
    4.37 +  check(lp.primalType() == LP::OPTIMAL, "Optimal solution is not found");
    4.38 +  check(lp.primal() <= 67.501 && lp.primal() >= 67.499, "Wrong objective value");
    4.39 +  check(lp.primal(x1) <= 7.501 && lp.primal(x1) >= 7.499, "Wrong value for x1");
    4.40 +  check(lp.primal(x2) <= 10.001 && lp.primal(x2) >= 9.999, "Wrong value for x2");
    4.41 +}
    4.42 +
    4.43  int main()
    4.44  {
    4.45    LpSkeleton lp_skel;
    4.46 @@ -444,6 +473,7 @@
    4.47      lpTest(lp_glpk1);
    4.48      aTest(lp_glpk2);
    4.49      cloneTest<GlpkLp>();
    4.50 +    rangeConstraintTest<GlpkLp>();
    4.51    }
    4.52  #endif
    4.53  
    4.54 @@ -453,6 +483,7 @@
    4.55      lpTest(lp_cplex1);
    4.56      aTest(lp_cplex2);
    4.57      cloneTest<CplexLp>();
    4.58 +    rangeConstraintTest<CplexLp>();
    4.59    } catch (CplexEnv::LicenseError& error) {
    4.60      check(false, error.what());
    4.61    }
    4.62 @@ -464,6 +495,7 @@
    4.63      lpTest(lp_soplex1);
    4.64      aTest(lp_soplex2);
    4.65      cloneTest<SoplexLp>();
    4.66 +    rangeConstraintTest<Soplex>();
    4.67    }
    4.68  #endif
    4.69  
    4.70 @@ -473,6 +505,7 @@
    4.71      lpTest(lp_clp1);
    4.72      aTest(lp_clp2);
    4.73      cloneTest<ClpLp>();
    4.74 +    rangeConstraintTest<ClpLp>();
    4.75    }
    4.76  #endif
    4.77  
     5.1 --- a/test/mip_test.cc	Sat Oct 27 13:00:48 2018 +0200
     5.2 +++ b/test/mip_test.cc	Wed Jan 20 16:17:21 2021 +0100
     5.3 @@ -61,7 +61,7 @@
     5.4    }
     5.5  }
     5.6  
     5.7 -void aTest(MipSolver& mip)
     5.8 +void aTest(MipSolver& mip, bool solve_empty=true)
     5.9  {
    5.10    //The following example is very simple
    5.11  
    5.12 @@ -80,7 +80,8 @@
    5.13    mip.max();
    5.14  
    5.15    //Unconstrained optimization
    5.16 -  mip.solve();
    5.17 +  if(solve_empty)
    5.18 +    mip.solve();
    5.19    //Check it out!
    5.20  
    5.21    //Constraints
    5.22 @@ -135,7 +136,11 @@
    5.23  #ifdef LEMON_HAVE_MIP
    5.24    {
    5.25      Mip mip1;
    5.26 +#if LEMON_DEFAULT_MIP==LEMON_CBC_
    5.27 +    aTest(mip1, false);
    5.28 +#else
    5.29      aTest(mip1);
    5.30 +#endif
    5.31      cloneTest<Mip>();
    5.32    }
    5.33  #endif
    5.34 @@ -161,7 +166,7 @@
    5.35  #ifdef LEMON_HAVE_CBC
    5.36    {
    5.37      CbcMip mip1;
    5.38 -    aTest(mip1);
    5.39 +    aTest(mip1, false);
    5.40      cloneTest<CbcMip>();
    5.41    }
    5.42  #endif