Merge #640
authorAlpar Juttner <alpar@cs.elte.hu>
Thu, 21 Jan 2021 18:58:37 +0100
changeset 1429eba5aa390aca
parent 1426 736a341e604b
parent 1428 86a5b114a066
child 1431 4a170261cc54
Merge #640
     1.1 --- a/cmake/FindILOG.cmake	Thu Jan 21 08:36:53 2021 +0100
     1.2 +++ b/cmake/FindILOG.cmake	Thu Jan 21 18:58:37 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	Thu Jan 21 08:36:53 2021 +0100
     2.2 +++ b/lemon/clp.cc	Thu Jan 21 18:58:37 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;
    2.22 @@ -461,4 +461,14 @@
    2.23      }
    2.24    }
    2.25  
    2.26 +   void ClpLp::_write(std::string file, std::string format) const
    2.27 +  {
    2.28 +    if(format == "LP")
    2.29 +      _prob->writeLp(file.c_str(), "", 1e-5, 10, 5,
    2.30 +                     sense()==ClpLp::MIN?1:-1,
    2.31 +                     true
    2.32 +                     );
    2.33 +    else throw UnsupportedFormatError(format);
    2.34 +  }
    2.35 + 
    2.36  } //END OF NAMESPACE LEMON
     3.1 --- a/lemon/clp.h	Thu Jan 21 08:36:53 2021 +0100
     3.2 +++ b/lemon/clp.h	Thu Jan 21 18:58:37 2021 +0100
     3.3 @@ -139,6 +139,8 @@
     3.4  
     3.5      virtual void _messageLevel(MessageLevel);
     3.6  
     3.7 +    void _write(std::string file, std::string format) const;
     3.8 +
     3.9    public:
    3.10  
    3.11      ///Solves LP with primal simplex method.
     4.1 --- a/lemon/cplex.cc	Thu Jan 21 08:36:53 2021 +0100
     4.2 +++ b/lemon/cplex.cc	Thu Jan 21 18:58:37 2021 +0100
     4.3 @@ -158,7 +158,7 @@
     4.4      } else {
     4.5        const char s = 'R';
     4.6        double len = ub - lb;
     4.7 -      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &ub, &s,
     4.8 +      CPXaddrows(cplexEnv(), _prob, 0, 1, values.size(), &lb, &s,
     4.9                   &rmatbeg, &indices.front(), &values.front(), 0, 0);
    4.10        CPXchgrngval(cplexEnv(), _prob, 1, &i, &len);
    4.11      }
     5.1 --- a/test/lp_test.cc	Thu Jan 21 08:36:53 2021 +0100
     5.2 +++ b/test/lp_test.cc	Thu Jan 21 18:58:37 2021 +0100
     5.3 @@ -339,6 +339,7 @@
     5.4    check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
     5.5    check(lp.sense() == lp.MAX,"This is a maximization!");
     5.6    check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
     5.7 +  check(lp.coeff(upright,x2)==2,"The coefficient in question is 1!");
     5.8    check(lp.colLowerBound(x1)==0,
     5.9          "The lower bound for variable x1 should be 0.");
    5.10    check(lp.colUpperBound(x1)==LpSolver::INF,
    5.11 @@ -424,6 +425,34 @@
    5.12    delete lpclone;
    5.13  }
    5.14  
    5.15 +template<class LP>
    5.16 +void rangeConstraintTest()
    5.17 +{
    5.18 +  LP lp;
    5.19 +  // Add two columns (variables) to the problem
    5.20 +  typename LP::Col x1 = lp.addCol();
    5.21 +  typename LP::Col x2 = lp.addCol();
    5.22 +  // Add rows (constraints) to the problem
    5.23 +  lp.addRow(x1 - 5 <= x2);
    5.24 +    lp.addRow(0 <= 2 * x1 + x2 <= 25);
    5.25 +  
    5.26 +  // Set lower and upper bounds for the columns (variables)
    5.27 +  lp.colLowerBound(x1, 0);
    5.28 +  lp.colUpperBound(x2, 10);
    5.29 +  
    5.30 +  // Specify the objective function
    5.31 +  lp.max();
    5.32 +  lp.obj(5 * x1 + 3 * x2);
    5.33 +  
    5.34 +  // Solve the problem using the underlying LP solver
    5.35 +  lp.solve();
    5.36 +  // Print the results
    5.37 +  check(lp.primalType() == LP::OPTIMAL, "Optimal solution is not found");
    5.38 +  check(lp.primal() <= 67.501 && lp.primal() >= 67.499, "Wrong objective value");
    5.39 +  check(lp.primal(x1) <= 7.501 && lp.primal(x1) >= 7.499, "Wrong value for x1");
    5.40 +  check(lp.primal(x2) <= 10.001 && lp.primal(x2) >= 9.999, "Wrong value for x2");
    5.41 +}
    5.42 +
    5.43  int main()
    5.44  {
    5.45    LpSkeleton lp_skel;
    5.46 @@ -444,6 +473,7 @@
    5.47      lpTest(lp_glpk1);
    5.48      aTest(lp_glpk2);
    5.49      cloneTest<GlpkLp>();
    5.50 +    rangeConstraintTest<GlpkLp>();
    5.51    }
    5.52  #endif
    5.53  
    5.54 @@ -453,6 +483,7 @@
    5.55      lpTest(lp_cplex1);
    5.56      aTest(lp_cplex2);
    5.57      cloneTest<CplexLp>();
    5.58 +    rangeConstraintTest<CplexLp>();
    5.59    } catch (CplexEnv::LicenseError& error) {
    5.60      check(false, error.what());
    5.61    }
    5.62 @@ -464,6 +495,7 @@
    5.63      lpTest(lp_soplex1);
    5.64      aTest(lp_soplex2);
    5.65      cloneTest<SoplexLp>();
    5.66 +    rangeConstraintTest<Soplex>();
    5.67    }
    5.68  #endif
    5.69  
    5.70 @@ -473,6 +505,7 @@
    5.71      lpTest(lp_clp1);
    5.72      aTest(lp_clp2);
    5.73      cloneTest<ClpLp>();
    5.74 +    rangeConstraintTest<ClpLp>();
    5.75    }
    5.76  #endif
    5.77  
     6.1 --- a/test/mip_test.cc	Thu Jan 21 08:36:53 2021 +0100
     6.2 +++ b/test/mip_test.cc	Thu Jan 21 18:58:37 2021 +0100
     6.3 @@ -61,7 +61,7 @@
     6.4    }
     6.5  }
     6.6  
     6.7 -void aTest(MipSolver& mip)
     6.8 +void aTest(MipSolver& mip, bool solve_empty=true)
     6.9  {
    6.10    //The following example is very simple
    6.11  
    6.12 @@ -80,7 +80,8 @@
    6.13    mip.max();
    6.14  
    6.15    //Unconstrained optimization
    6.16 -  mip.solve();
    6.17 +  if(solve_empty)
    6.18 +    mip.solve();
    6.19    //Check it out!
    6.20  
    6.21    //Constraints
    6.22 @@ -135,7 +136,11 @@
    6.23  #ifdef LEMON_HAVE_MIP
    6.24    {
    6.25      Mip mip1;
    6.26 +#if LEMON_DEFAULT_MIP==LEMON_CBC_
    6.27 +    aTest(mip1, false);
    6.28 +#else
    6.29      aTest(mip1);
    6.30 +#endif
    6.31      cloneTest<Mip>();
    6.32    }
    6.33  #endif
    6.34 @@ -161,7 +166,7 @@
    6.35  #ifdef LEMON_HAVE_CBC
    6.36    {
    6.37      CbcMip mip1;
    6.38 -    aTest(mip1);
    6.39 +    aTest(mip1, false);
    6.40      cloneTest<CbcMip>();
    6.41    }
    6.42  #endif