# HG changeset patch # User deba # Date 1164821421 0 # Node ID d9daf826e28a833e28c5b185c7ec6bdc9687ec92 # Parent 07e46cbb7d8584f74a4673a6a2765add19dc35b4 Preliminary soplex support diff -r 07e46cbb7d85 -r d9daf826e28a lemon/Makefile.am --- a/lemon/Makefile.am Wed Nov 29 15:01:13 2006 +0000 +++ b/lemon/Makefile.am Wed Nov 29 17:30:21 2006 +0000 @@ -15,8 +15,8 @@ lemon/bits/mingw32_time.cc \ lemon/random.cc -lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) -lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) +lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CFLAGS) +lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_CFLAGS) if HAVE_GLPK lemon_libemon_la_SOURCES += lemon/lp_glpk.cc @@ -28,6 +28,10 @@ lemon_libemon_la_SOURCES += lemon/mip_cplex.cc endif +if HAVE_SOPLEX +lemon_libemon_la_SOURCES += lemon/lp_soplex.cc +endif + lemon_HEADERS += \ lemon/bellman_ford.h \ lemon/bfs.h \ @@ -71,6 +75,7 @@ lemon/lp_cplex.h \ lemon/lp_glpk.h \ lemon/lp_skeleton.h \ + lemon/lp_soplex.h \ lemon/map_iterator.h \ lemon/maps.h \ lemon/matrix_maps.h \ diff -r 07e46cbb7d85 -r d9daf826e28a lemon/lp_soplex.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/lp_soplex.cc Wed Nov 29 17:30:21 2006 +0000 @@ -0,0 +1,208 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#include +#include + +#include + + +///\file +///\brief Implementation of the LEMON-SOPLEX lp solver interface. +namespace lemon { + + LpSoplex::LpSoplex() : LpSolverBase() { + soplex = new soplex::SoPlex; + } + + LpSoplex::~LpSoplex() { + delete soplex; + } + + LpSolverBase &LpSoplex::_newLp() { + LpSoplex* newlp = new LpSoplex(); + return *newlp; + } + + LpSolverBase &LpSoplex::_copyLp() { + LpSoplex* newlp = new LpSoplex(); + ((soplex::SPxLP&)*(newlp->soplex)) = *soplex; + return *newlp; + } + + int LpSoplex::_addCol() { + soplex::LPCol col; + soplex->addCol(col); + + colNames.push_back(std::string()); + primal.push_back(0.0); + + return soplex->nCols() - 1; + } + + int LpSoplex::_addRow() { + soplex::LPRow row; + soplex->addRow(row); + + dual.push_back(0.0); + + return soplex->nRows() - 1; + } + + + void LpSoplex::_eraseCol(int i) { + soplex->removeCol(i); + primal[i] = primal.back(); + primal.pop_back(); + } + + void LpSoplex::_eraseRow(int i) { + soplex->removeRow(i); + dual[i] = dual.back(); + dual.pop_back(); + } + + void LpSoplex::_getColName(int col, std::string &name) { + name = colNames[col]; + } + + void LpSoplex::_setColName(int col, const std::string &name) { + colNames[col] = name; + } + + + void LpSoplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) { + for (int j = 0; j < soplex->nCols(); ++j) { + soplex->changeElement(i, j, 0.0); + } + for(LpRowIterator it = b; it != e; ++it) { + soplex->changeElement(i, it->first, it->second); + } + } + + void LpSoplex::_setColCoeffs(int j, LpColIterator b, LpColIterator e) { + for (int i = 0; i < soplex->nRows(); ++i) { + soplex->changeElement(i, j, 0.0); + } + for(LpColIterator it = b; it != e; ++it) { + soplex->changeElement(it->first, j, it->second); + } + } + + void LpSoplex::_setCoeff(int row, int col, Value value) { + soplex->changeElement(row, col, value); + } + + void LpSoplex::_setColLowerBound(int i, Value value) { + soplex->changeLower(i, value); + } + + void LpSoplex::_setColUpperBound(int i, Value value) { + soplex->changeUpper(i, value); + } + + void LpSoplex::_setRowBounds(int i, Value lb, Value ub) { + soplex->changeRange(i, lb, ub); + } + + void LpSoplex::_setObjCoeff(int i, Value obj_coef) { + soplex->changeObj(i, obj_coef); + } + + void LpSoplex::_clearObj() { + for (int i = 0; i < soplex->nCols(); ++i) { + soplex->changeObj(i, 0.0); + } + } + + LpSoplex::SolveExitStatus LpSoplex::_solve() { + soplex::SPxSolver::Status status = soplex->solve(); + + soplex::Vector pv(primal.size(), &primal[0]); + soplex->getPrimal(pv); + + soplex::Vector dv(dual.size(), &dual[0]); + soplex->getDual(dv); + + switch (status) { + case soplex::SPxSolver::OPTIMAL: + case soplex::SPxSolver::INFEASIBLE: + case soplex::SPxSolver::UNBOUNDED: + return SOLVED; + default: + return UNSOLVED; + } + } + + LpSoplex::Value LpSoplex::_getPrimal(int i) { + return primal[i]; + } + + LpSoplex::Value LpSoplex::_getDual(int i) { + return dual[i]; + } + + LpSoplex::Value LpSoplex::_getPrimalValue() { + return soplex->objValue(); + } + + bool LpSoplex::_isBasicCol(int i) { + return soplex->getBasisColStatus(i) == soplex::SPxSolver::BASIC; + } + + LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() { + switch (soplex->status()) { + case soplex::SPxSolver::OPTIMAL: + return OPTIMAL; + case soplex::SPxSolver::UNBOUNDED: + return INFINITE; + case soplex::SPxSolver::INFEASIBLE: + return INFEASIBLE; + default: + return UNDEFINED; + } + } + + LpSoplex::SolutionStatus LpSoplex::_getDualStatus() { + switch (0) { + case 0: + return UNDEFINED; + return OPTIMAL; + return INFEASIBLE; + return UNDEFINED; + } + } + + LpSoplex::ProblemTypes LpSoplex::_getProblemType() { + switch (0) { + case 0: + return PRIMAL_DUAL_FEASIBLE; + return PRIMAL_FEASIBLE_DUAL_INFEASIBLE; + return UNKNOWN; + } + } + + void LpSoplex::_setMax() { + soplex->changeSense(soplex::SPxSolver::MAXIMIZE); + } + void LpSoplex::_setMin() { + soplex->changeSense(soplex::SPxSolver::MINIMIZE); + } + +} //namespace lemon + diff -r 07e46cbb7d85 -r d9daf826e28a lemon/lp_soplex.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/lp_soplex.h Wed Nov 29 17:30:21 2006 +0000 @@ -0,0 +1,99 @@ +/* -*- C++ -*- + * + * This file is a part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2003-2006 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_LP_SOPLEX_H +#define LEMON_LP_SOPLEX_H + +///\file +///\brief Header of the LEMON-SOPLEX lp solver interface. + +#include +#include + +#include + +// Forward declaration +namespace soplex { + class SoPlex; +} + +namespace lemon { + + /// \brief Interface for the SOPLEX solver + /// + /// This class implements an interface for the SOPLEX LP solver. + class LpSoplex :virtual public LpSolverBase { + protected: + + soplex::SoPlex* soplex; + + std::vector colNames; + + std::vector primal; + std::vector dual; + + + public: + + typedef LpSolverBase Parent; + + + /// \e + LpSoplex(); + /// \e + ~LpSoplex(); + + protected: + + virtual LpSolverBase &_newLp(); + virtual LpSolverBase &_copyLp(); + + virtual int _addCol(); + virtual int _addRow(); + virtual void _eraseCol(int i); + virtual void _eraseRow(int i); + virtual void _getColName(int col, std::string & name); + virtual void _setColName(int col, const std::string & name); + virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e); + virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e); + virtual void _setCoeff(int row, int col, Value value); + virtual void _setColLowerBound(int i, Value value); + virtual void _setColUpperBound(int i, Value value); + virtual void _setRowBounds(int i, Value lower, Value upper); + virtual void _setObjCoeff(int i, Value obj_coef); + virtual void _clearObj(); + + virtual SolveExitStatus _solve(); + virtual Value _getPrimal(int i); + virtual Value _getDual(int i); + virtual Value _getPrimalValue(); + virtual bool _isBasicCol(int i); + + virtual SolutionStatus _getPrimalStatus(); + virtual SolutionStatus _getDualStatus(); + virtual ProblemTypes _getProblemType(); + + + virtual void _setMax(); + virtual void _setMin(); + + }; +} //END OF NAMESPACE LEMON + +#endif //LEMON_LP_SOPLEX_H + diff -r 07e46cbb7d85 -r d9daf826e28a m4/lx_check_soplex.m4 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/m4/lx_check_soplex.m4 Wed Nov 29 17:30:21 2006 +0000 @@ -0,0 +1,71 @@ +AC_DEFUN([LX_CHECK_SOPLEX], +[ + AC_ARG_WITH([soplex], +AS_HELP_STRING([--with-soplex@<:@=PREFIX@:>@], [search for SOPLEX under PREFIX or under the default search paths if PREFIX is not given @<:@default@:>@]) +AS_HELP_STRING([--without-soplex], [disable checking for SOPLEX]), + [], [with_soplex=yes]) + + AC_ARG_WITH([soplex-includedir], +AS_HELP_STRING([--with-soplex-includedir=DIR], [search for SOPLEX headers in DIR]), + [], [with_soplex_includedir=no]) + + AC_ARG_WITH([soplex-libdir], +AS_HELP_STRING([--with-soplex-libdir=DIR], [search for SOPLEX libraries in DIR]), + [], [with_soplex_libdir=no]) + + lx_soplex_found=no + if test x"$with_soplex" != x"no"; then + AC_MSG_CHECKING([for SOPLEX]) + + if test x"$with_soplex_includedir" != x"no"; then + SOPLEX_CFLAGS="-I$with_soplex_includedir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_CFLAGS="-I$with_soplex/include" + fi + + if test x"$with_soplex_libdir" != x"no"; then + SOPLEX_LDFLAGS="-L$with_soplex_libdir" + elif test x"$with_soplex" != x"yes"; then + SOPLEX_LDFLAGS="-L$with_soplex/lib" + fi + SOPLEX_LIBS="-lsoplex -lz" + + lx_save_cxxflags="$CXXFLAGS" + lx_save_ldflags="$LDFLAGS" + lx_save_libs="$LIBS" + CXXFLAGS="$SOPLEX_CFLAGS" + LDFLAGS="$SOPLEX_LDFLAGS" + LIBS="$SOPLEX_LIBS" + + lx_soplex_test_prog=' + #include + + int main(int argc, char* argv[]) + { + soplex::SoPlex soplex; + return 0; + }' + + AC_LANG_PUSH(C++) + AC_LINK_IFELSE([$lx_soplex_test_prog], [lx_soplex_found=yes], [lx_soplex_found=no]) + AC_LANG_POP(C++) + + CXXFLAGS="$lx_save_cxxflags" + LDFLAGS="$lx_save_ldflags" + LIBS="$lx_save_libs" + + if test x"$lx_soplex_found" = x"yes"; then + AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.]) + AC_MSG_RESULT([yes]) + else + SOPLEX_CFLAGS="" + SOPLEX_LDFLAGS="" + SOPLEX_LIBS="" + AC_MSG_RESULT([no]) + fi + fi + SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS" + AC_SUBST(SOPLEX_CFLAGS) + AC_SUBST(SOPLEX_LIBS) + AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"]) +])