1.1 --- a/lemon/Makefile.am Thu Feb 15 13:06:23 2007 +0000
1.2 +++ b/lemon/Makefile.am Thu Feb 15 14:22:08 2007 +0000
1.3 @@ -15,8 +15,8 @@
1.4 lemon/bits/mingw32_time.cc \
1.5 lemon/random.cc
1.6
1.7 -lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CFLAGS)
1.8 -lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_CFLAGS)
1.9 +lemon_libemon_la_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
1.10 +lemon_libemon_la_LDFLAGS = $(GLPK_LIBS) $(CPLEX_LIBS) $(SOPLEX_LIBS)
1.11
1.12 if HAVE_GLPK
1.13 lemon_libemon_la_SOURCES += lemon/lp_glpk.cc
1.14 @@ -123,6 +123,7 @@
1.15 lemon/bits/invalid.h \
1.16 lemon/bits/item_reader.h \
1.17 lemon/bits/item_writer.h \
1.18 + lemon/bits/lp_id.h \
1.19 lemon/bits/map_extender.h \
1.20 lemon/bits/mingw32_time.h \
1.21 lemon/bits/path_dump.h \
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/lemon/bits/lp_id.h Thu Feb 15 14:22:08 2007 +0000
2.3 @@ -0,0 +1,146 @@
2.4 +/* -*- C++ -*-
2.5 + *
2.6 + * This file is a part of LEMON, a generic C++ optimization library
2.7 + *
2.8 + * Copyright (C) 2003-2006
2.9 + * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
2.10 + * (Egervary Research Group on Combinatorial Optimization, EGRES).
2.11 + *
2.12 + * Permission to use, modify and distribute this software is granted
2.13 + * provided that this copyright notice appears in all copies. For
2.14 + * precise terms see the accompanying LICENSE file.
2.15 + *
2.16 + * This software is provided "AS IS" with no warranty of any kind,
2.17 + * express or implied, and with no claim as to its suitability for any
2.18 + * purpose.
2.19 + *
2.20 + */
2.21 +
2.22 +#ifndef LEMON_BITS_LP_SOLVER_ID_H
2.23 +#define LEMON_BITS_LP_SOLVER_ID_H
2.24 +
2.25 +namespace lemon {
2.26 +
2.27 + namespace _lp_bits {
2.28 +
2.29 + struct LpIdImpl {
2.30 + std::vector<int> index;
2.31 + std::vector<int> cross;
2.32 + int first_index;
2.33 + int first_free;
2.34 + };
2.35 +
2.36 + class LpId {
2.37 + public:
2.38 +
2.39 + class IdHandler {
2.40 + public:
2.41 + virtual ~IdHandler() {}
2.42 + virtual int addId(LpIdImpl&) = 0;
2.43 + virtual void eraseId(LpIdImpl&, int xn) = 0;
2.44 + };
2.45 +
2.46 + LpId(int min_index = 0) {
2.47 + id_handler = 0;
2.48 + impl.first_free = -1;
2.49 + impl.first_index = min_index;
2.50 + impl.cross.resize(impl.first_index);
2.51 + }
2.52 +
2.53 + void setIdHandler(IdHandler& ih) {
2.54 + id_handler = &ih;
2.55 + }
2.56 +
2.57 + int fixId(int fn) const {return impl.cross[fn];}
2.58 + int floatingId(int xn) const {return impl.index[xn];}
2.59 +
2.60 + int addId() {
2.61 + if (id_handler == 0) {
2.62 + int xn, fn = impl.cross.size();
2.63 + if (impl.first_free == -1) {
2.64 + xn = impl.index.size();
2.65 + impl.index.push_back(fn);
2.66 + } else {
2.67 + xn = impl.first_free;
2.68 + impl.first_free = impl.index[impl.first_free];
2.69 + impl.index[xn] = fn;
2.70 + }
2.71 + impl.cross.push_back(xn);
2.72 + return xn;
2.73 + } else {
2.74 + return id_handler->addId(impl);
2.75 + }
2.76 + }
2.77 +
2.78 + void eraseId(int xn) {
2.79 + if (id_handler == 0) {
2.80 + int fn = impl.index[xn];
2.81 + impl.index[xn] = impl.first_free;
2.82 + impl.first_free = xn;
2.83 + for(int i = fn + 1; i < (int)impl.cross.size(); ++i) {
2.84 + impl.cross[i - 1] = impl.cross[i];
2.85 + impl.index[impl.cross[i]]--;
2.86 + }
2.87 + impl.cross.pop_back();
2.88 + } else {
2.89 + id_handler->eraseId(impl, xn);
2.90 + }
2.91 + }
2.92 +
2.93 + void firstFloating(int& fn) const {
2.94 + fn = impl.first_index;
2.95 + if (fn == (int)impl.cross.size()) fn = -1;
2.96 + }
2.97 +
2.98 + void nextFloating(int& fn) const {
2.99 + ++fn;
2.100 + if (fn == (int)impl.cross.size()) fn = -1;
2.101 + }
2.102 +
2.103 + void firstFix(int& xn) const {
2.104 + int fn;
2.105 + firstFloating(fn);
2.106 + xn = fn != -1 ? fixId(fn) : -1;
2.107 + }
2.108 +
2.109 + void nextFix(int& xn) const {
2.110 + int fn = floatingId(xn);
2.111 + nextFloating(fn);
2.112 + xn = fn != -1 ? fixId(fn) : -1;
2.113 + }
2.114 +
2.115 + protected:
2.116 + LpIdImpl impl;
2.117 + IdHandler *id_handler;
2.118 + };
2.119 +
2.120 + class RelocateIdHandler : public LpId::IdHandler {
2.121 + public:
2.122 +
2.123 + virtual int addId(LpIdImpl& impl) {
2.124 + int xn, fn = impl.cross.size();
2.125 + if (impl.first_free == -1) {
2.126 + xn = impl.index.size();
2.127 + impl.index.push_back(fn);
2.128 + } else {
2.129 + xn = impl.first_free;
2.130 + impl.first_free = impl.index[impl.first_free];
2.131 + impl.index[xn] = fn;
2.132 + }
2.133 + impl.cross.push_back(xn);
2.134 + return xn;
2.135 + }
2.136 +
2.137 + virtual void eraseId(LpIdImpl& impl, int xn) {
2.138 + int fn = impl.index[xn];
2.139 + impl.index[xn] = impl.first_free;
2.140 + impl.first_free = xn;
2.141 + impl.cross[fn] = impl.cross.back();
2.142 + impl.index[impl.cross.back()] = fn;
2.143 + impl.cross.pop_back();
2.144 + }
2.145 + };
2.146 + }
2.147 +}
2.148 +
2.149 +#endif
3.1 --- a/lemon/lp_base.h Thu Feb 15 13:06:23 2007 +0000
3.2 +++ b/lemon/lp_base.h Thu Feb 15 14:22:08 2007 +0000
3.3 @@ -27,93 +27,16 @@
3.4 #include<limits>
3.5 #include<cmath>
3.6
3.7 -#include<lemon/bits/utility.h>
3.8 #include<lemon/error.h>
3.9 #include<lemon/bits/invalid.h>
3.10 +#include<lemon/bits/utility.h>
3.11 +#include<lemon/bits/lp_id.h>
3.12
3.13 ///\file
3.14 ///\brief The interface of the LP solver interface.
3.15 ///\ingroup gen_opt_group
3.16 namespace lemon {
3.17
3.18 -
3.19 - ///Internal data structure to convert floating id's to fix one's
3.20 -
3.21 - ///\todo This might be implemented to be also usable in other places.
3.22 - class _FixId
3.23 - {
3.24 - protected:
3.25 - int _first_index;
3.26 - int first_free;
3.27 - public:
3.28 - std::vector<int> index;
3.29 - std::vector<int> cross;
3.30 - _FixId() : _first_index(-1), first_free(-1) {};
3.31 - ///Convert a floating id to a fix one
3.32 -
3.33 - ///\param n is a floating id
3.34 - ///\return the corresponding fix id
3.35 - int fixId(int n) const {return cross[n];}
3.36 - ///Convert a fix id to a floating one
3.37 -
3.38 - ///\param n is a fix id
3.39 - ///\return the corresponding floating id
3.40 - int floatingId(int n) const { return index[n];}
3.41 - ///Add a new floating id.
3.42 -
3.43 - ///\param n is a floating id
3.44 - ///\return the fix id of the new value
3.45 - ///\todo Multiple additions should also be handled.
3.46 - int insert(int n)
3.47 - {
3.48 - if(cross.empty()) _first_index=n;
3.49 - if(n>=int(cross.size())) {
3.50 - cross.resize(n+1);
3.51 - if(first_free==-1) {
3.52 - cross[n]=index.size();
3.53 - index.push_back(n);
3.54 - }
3.55 - else {
3.56 - cross[n]=first_free;
3.57 - int next=index[first_free];
3.58 - index[first_free]=n;
3.59 - first_free=next;
3.60 - }
3.61 - return cross[n];
3.62 - }
3.63 - else {
3.64 - ///\todo Create an own exception type.
3.65 - throw LogicError(); //floatingId-s must form a continuous range;
3.66 - }
3.67 - }
3.68 - ///Remove a fix id.
3.69 -
3.70 - ///\param n is a fix id
3.71 - ///
3.72 - void erase(int n)
3.73 - {
3.74 - int fl=index[n];
3.75 - index[n]=first_free;
3.76 - first_free=n;
3.77 - for(int i=fl+1;i<int(cross.size());++i) {
3.78 - cross[i-1]=cross[i];
3.79 - index[cross[i]]--;
3.80 - }
3.81 - cross.pop_back();
3.82 - }
3.83 - ///An upper bound on the largest fix id.
3.84 -
3.85 - ///\todo Do we need this?
3.86 - ///
3.87 - std::size_t maxFixId() { return cross.size()-1; }
3.88 -
3.89 - ///Returns the first (smallest) inserted index
3.90 -
3.91 - ///Returns the first (smallest) inserted index
3.92 - ///or -1 if no index has been inserted before.
3.93 - int firstIndex() {return _first_index;}
3.94 - };
3.95 -
3.96 ///Common base class for LP solvers
3.97
3.98 ///\todo Much more docs
3.99 @@ -121,9 +44,10 @@
3.100 class LpSolverBase {
3.101
3.102 protected:
3.103 - _FixId rows;
3.104 - _FixId cols;
3.105
3.106 + _lp_bits::LpId rows;
3.107 + _lp_bits::LpId cols;
3.108 +
3.109 public:
3.110
3.111 ///Possible outcomes of an LP solving procedure
3.112 @@ -215,14 +139,12 @@
3.113 ColIt() {}
3.114 ColIt(LpSolverBase &lp) : _lp(&lp)
3.115 {
3.116 - id = _lp->cols.cross.empty()?-1:
3.117 - _lp->cols.fixId(_lp->cols.firstIndex());
3.118 + _lp->cols.firstFix(id);
3.119 }
3.120 ColIt(const Invalid&) : Col(INVALID) {}
3.121 ColIt &operator++()
3.122 {
3.123 - int fid = _lp->cols.floatingId(id)+1;
3.124 - id = unsigned(fid)<_lp->cols.cross.size() ? _lp->cols.fixId(fid) : -1;
3.125 + _lp->cols.nextFix(id);
3.126 return *this;
3.127 }
3.128 };
3.129 @@ -746,8 +668,6 @@
3.130 virtual Value _getColLowerBound(int i) = 0;
3.131 virtual void _setColUpperBound(int i, Value value) = 0;
3.132 virtual Value _getColUpperBound(int i) = 0;
3.133 -// virtual void _setRowLowerBound(int i, Value value) = 0;
3.134 -// virtual void _setRowUpperBound(int i, Value value) = 0;
3.135 virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
3.136 virtual void _getRowBounds(int i, Value &lower, Value &upper)=0;
3.137
3.138 @@ -795,7 +715,7 @@
3.139 ///@{
3.140
3.141 ///Add a new empty column (i.e a new variable) to the LP
3.142 - Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
3.143 + Col addCol() { Col c; _addCol(); c.id = cols.addId(); return c;}
3.144
3.145 ///\brief Adds several new columns
3.146 ///(i.e a variables) at once
3.147 @@ -887,7 +807,7 @@
3.148
3.149 ///This function adds a new empty row (i.e a new constraint) to the LP.
3.150 ///\return The created row
3.151 - Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
3.152 + Row addRow() { Row r; _addRow(); r.id = rows.addId(); return r;}
3.153
3.154 ///\brief Add several new rows
3.155 ///(i.e a constraints) at once
3.156 @@ -965,8 +885,6 @@
3.157 e.simplify();
3.158 _setRowCoeffs(_lpId(r), LpRowIterator(e.begin(), *this),
3.159 LpRowIterator(e.end(), *this));
3.160 -// _setRowLowerBound(_lpId(r),l-e.constComp());
3.161 -// _setRowUpperBound(_lpId(r),u-e.constComp());
3.162 _setRowBounds(_lpId(r),l-e.constComp(),u-e.constComp());
3.163 }
3.164
3.165 @@ -1008,7 +926,7 @@
3.166 ///\todo Please check this
3.167 void eraseCol(Col c) {
3.168 _eraseCol(_lpId(c));
3.169 - cols.erase(c.id);
3.170 + cols.eraseId(c.id);
3.171 }
3.172 ///Erase a row (i.e a constraint) from the LP
3.173
3.174 @@ -1016,7 +934,7 @@
3.175 ///\todo Please check this
3.176 void eraseRow(Row r) {
3.177 _eraseRow(_lpId(r));
3.178 - rows.erase(r.id);
3.179 + rows.eraseId(r.id);
3.180 }
3.181
3.182 /// Get the name of a column
3.183 @@ -1216,31 +1134,14 @@
3.184 }
3.185 #endif
3.186
3.187 -// /// Set the lower bound of a row (i.e a constraint)
3.188 -
3.189 -// /// The lower bound of a linear expression (row) has to be given by an
3.190 -// /// extended number of type Value, i.e. a finite number of type
3.191 -// /// Value or -\ref INF.
3.192 -// void rowLowerBound(Row r, Value value) {
3.193 -// _setRowLowerBound(_lpId(r),value);
3.194 -// };
3.195 -// /// Set the upper bound of a row (i.e a constraint)
3.196 -
3.197 -// /// The upper bound of a linear expression (row) has to be given by an
3.198 -// /// extended number of type Value, i.e. a finite number of type
3.199 -// /// Value or \ref INF.
3.200 -// void rowUpperBound(Row r, Value value) {
3.201 -// _setRowUpperBound(_lpId(r),value);
3.202 -// };
3.203
3.204 /// Set the lower and the upper bounds of a row (i.e a constraint)
3.205
3.206 - /// The lower and the upper bound of
3.207 - /// a constraint (row) have to be given by an
3.208 - /// extended number of type Value, i.e. a finite number of type
3.209 - /// Value, -\ref INF or \ref INF. There is no separate function for the
3.210 - /// lower and the upper bound because that would have been hard to implement
3.211 - /// for CPLEX.
3.212 + /// The lower and the upper bound of a constraint (row) have to be
3.213 + /// given by an extended number of type Value, i.e. a finite
3.214 + /// number of type Value, -\ref INF or \ref INF. There is no
3.215 + /// separate function for the lower and the upper bound because
3.216 + /// that would have been hard to implement for CPLEX.
3.217 void rowBounds(Row c, Value lower, Value upper) {
3.218 _setRowBounds(_lpId(c),lower, upper);
3.219 }
4.1 --- a/lemon/lp_cplex.cc Thu Feb 15 13:06:23 2007 +0000
4.2 +++ b/lemon/lp_cplex.cc Thu Feb 15 14:22:08 2007 +0000
4.3 @@ -24,7 +24,6 @@
4.4 namespace lemon {
4.5
4.6 LpCplex::LpCplex() : LpSolverBase() {
4.7 -
4.8 // env = CPXopenCPLEXdevelop(&status);
4.9 env = CPXopenCPLEX(&status);
4.10 lp = CPXcreateprob(env, &status, "LP problem");
5.1 --- a/lemon/lp_glpk.cc Thu Feb 15 13:06:23 2007 +0000
5.2 +++ b/lemon/lp_glpk.cc Thu Feb 15 14:22:08 2007 +0000
5.3 @@ -24,16 +24,20 @@
5.4 namespace lemon {
5.5
5.6
5.7 - LpGlpk::LpGlpk() : Parent(),
5.8 - lp(lpx_create_prob()) {
5.9 - ///\todo constrol function for this:
5.10 + LpGlpk::LpGlpk() : Parent() {
5.11 + rows = _lp_bits::LpId(1);
5.12 + cols = _lp_bits::LpId(1);
5.13 + lp = lpx_create_prob();
5.14 + ///\todo control function for this:
5.15 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
5.16 messageLevel(0);
5.17 }
5.18
5.19 - LpGlpk::LpGlpk(const LpGlpk &glp) : Parent(glp),
5.20 - lp(lpx_create_prob()) {
5.21 - ///\todo constrol function for this:
5.22 + LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
5.23 + rows = _lp_bits::LpId(1);
5.24 + cols = _lp_bits::LpId(1);
5.25 + lp = lpx_create_prob();
5.26 + ///\todo control function for this:
5.27 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
5.28 messageLevel(0);
5.29 //Coefficient matrix, row bounds
5.30 @@ -349,92 +353,6 @@
5.31 }
5.32 }
5.33
5.34 -// void LpGlpk::_setRowLowerBound(int i, Value lo)
5.35 -// {
5.36 -// if (lo==INF) {
5.37 -// //FIXME error
5.38 -// }
5.39 -// int b=lpx_get_row_type(lp, i);
5.40 -// double up=lpx_get_row_ub(lp, i);
5.41 -// if (lo==-INF) {
5.42 -// switch (b) {
5.43 -// case LPX_FR:
5.44 -// case LPX_LO:
5.45 -// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
5.46 -// break;
5.47 -// case LPX_UP:
5.48 -// break;
5.49 -// case LPX_DB:
5.50 -// case LPX_FX:
5.51 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
5.52 -// break;
5.53 -// default: ;
5.54 -// //FIXME error
5.55 -// }
5.56 -// } else {
5.57 -// switch (b) {
5.58 -// case LPX_FR:
5.59 -// case LPX_LO:
5.60 -// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
5.61 -// break;
5.62 -// case LPX_UP:
5.63 -// case LPX_DB:
5.64 -// case LPX_FX:
5.65 -// if (lo==up)
5.66 -// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
5.67 -// else
5.68 -// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
5.69 -// break;
5.70 -// default: ;
5.71 -// //FIXME error
5.72 -// }
5.73 -// }
5.74 -// }
5.75 -
5.76 -// void LpGlpk::_setRowUpperBound(int i, Value up)
5.77 -// {
5.78 -// if (up==-INF) {
5.79 -// //FIXME error
5.80 -// }
5.81 -// int b=lpx_get_row_type(lp, i);
5.82 -// double lo=lpx_get_row_lb(lp, i);
5.83 -// if (up==INF) {
5.84 -// switch (b) {
5.85 -// case LPX_FR:
5.86 -// case LPX_LO:
5.87 -// break;
5.88 -// case LPX_UP:
5.89 -// lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
5.90 -// break;
5.91 -// case LPX_DB:
5.92 -// case LPX_FX:
5.93 -// lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
5.94 -// break;
5.95 -// default: ;
5.96 -// //FIXME error
5.97 -// }
5.98 -// } else {
5.99 -// switch (b) {
5.100 -// case LPX_FR:
5.101 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
5.102 -// break;
5.103 -// case LPX_UP:
5.104 -// lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
5.105 -// break;
5.106 -// case LPX_LO:
5.107 -// case LPX_DB:
5.108 -// case LPX_FX:
5.109 -// if (lo==up)
5.110 -// lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
5.111 -// else
5.112 -// lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
5.113 -// break;
5.114 -// default: ;
5.115 -// //FIXME error
5.116 -// }
5.117 -// }
5.118 -// }
5.119 -
5.120 void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
5.121 {
5.122 //Bad parameter
5.123 @@ -508,29 +426,15 @@
5.124 lpx_set_obj_coef(lp, i, 0);
5.125 }
5.126 }
5.127 -// void LpGlpk::_setObj(int length,
5.128 -// int const * indices,
5.129 -// Value const * values )
5.130 -// {
5.131 -// Value new_values[1+lpx_num_cols()];
5.132 -// for (i=0;i<=lpx_num_cols();++i){
5.133 -// new_values[i]=0;
5.134 -// }
5.135 -// for (i=1;i<=length;++i){
5.136 -// new_values[indices[i]]=values[i];
5.137 -// }
5.138 -
5.139 -// for (i=0;i<=lpx_num_cols();++i){
5.140 -// lpx_set_obj_coef(lp, i, new_values[i]);
5.141 -// }
5.142 -// }
5.143
5.144 LpGlpk::SolveExitStatus LpGlpk::_solve()
5.145 {
5.146 // A way to check the problem to be solved
5.147 //lpx_write_cpxlp(lp,"naittvan.cpx");
5.148
5.149 + lpx_std_basis(lp);
5.150 int i = lpx_simplex(lp);
5.151 +
5.152 switch (i) {
5.153 case LPX_E_OK:
5.154 return SOLVED;
6.1 --- a/lemon/lp_skeleton.h Thu Feb 15 13:06:23 2007 +0000
6.2 +++ b/lemon/lp_skeleton.h Thu Feb 15 14:22:08 2007 +0000
6.3 @@ -30,6 +30,7 @@
6.4 int col_num,row_num;
6.5
6.6 protected:
6.7 +
6.8 ///\e
6.9 virtual LpSolverBase &_newLp();
6.10 ///\e
7.1 --- a/lemon/lp_soplex.cc Thu Feb 15 13:06:23 2007 +0000
7.2 +++ b/lemon/lp_soplex.cc Thu Feb 15 14:22:08 2007 +0000
7.3 @@ -27,7 +27,10 @@
7.4 namespace lemon {
7.5
7.6 LpSoplex::LpSoplex() : LpSolverBase() {
7.7 + rows.setIdHandler(relocateIdHandler);
7.8 + cols.setIdHandler(relocateIdHandler);
7.9 soplex = new soplex::SoPlex;
7.10 + solved = false;
7.11 }
7.12
7.13 LpSoplex::~LpSoplex() {
7.14 @@ -47,19 +50,25 @@
7.15
7.16 int LpSoplex::_addCol() {
7.17 soplex::LPCol col;
7.18 + col.setLower(-soplex::infinity);
7.19 + col.setUpper(soplex::infinity);
7.20 soplex->addCol(col);
7.21
7.22 colNames.push_back(std::string());
7.23 - primal.push_back(0.0);
7.24 + primal_value.push_back(0.0);
7.25 + solved = false;
7.26
7.27 return soplex->nCols() - 1;
7.28 }
7.29
7.30 int LpSoplex::_addRow() {
7.31 soplex::LPRow row;
7.32 + row.setLhs(-soplex::infinity);
7.33 + row.setRhs(soplex::infinity);
7.34 soplex->addRow(row);
7.35
7.36 - dual.push_back(0.0);
7.37 + dual_value.push_back(0.0);
7.38 + solved = false;
7.39
7.40 return soplex->nRows() - 1;
7.41 }
7.42 @@ -67,14 +76,18 @@
7.43
7.44 void LpSoplex::_eraseCol(int i) {
7.45 soplex->removeCol(i);
7.46 - primal[i] = primal.back();
7.47 - primal.pop_back();
7.48 + colNames[i] = colNames.back();
7.49 + colNames.pop_back();
7.50 + primal_value[i] = primal_value.back();
7.51 + primal_value.pop_back();
7.52 + solved = false;
7.53 }
7.54
7.55 void LpSoplex::_eraseRow(int i) {
7.56 soplex->removeRow(i);
7.57 - dual[i] = dual.back();
7.58 - dual.pop_back();
7.59 + dual_value[i] = dual_value.back();
7.60 + dual_value.pop_back();
7.61 + solved = false;
7.62 }
7.63
7.64 void LpSoplex::_getColName(int col, std::string &name) {
7.65 @@ -93,6 +106,7 @@
7.66 for(LpRowIterator it = b; it != e; ++it) {
7.67 soplex->changeElement(i, it->first, it->second);
7.68 }
7.69 + solved = false;
7.70 }
7.71
7.72 void LpSoplex::_setColCoeffs(int j, LpColIterator b, LpColIterator e) {
7.73 @@ -102,47 +116,80 @@
7.74 for(LpColIterator it = b; it != e; ++it) {
7.75 soplex->changeElement(it->first, j, it->second);
7.76 }
7.77 + solved = false;
7.78 }
7.79
7.80 - void LpSoplex::_setCoeff(int row, int col, Value value) {
7.81 - soplex->changeElement(row, col, value);
7.82 + void LpSoplex::_setCoeff(int i, int j, Value value) {
7.83 + soplex->changeElement(i, j, value);
7.84 + solved = false;
7.85 + }
7.86 +
7.87 + LpSoplex::Value LpSoplex::_getCoeff(int i, int j) {
7.88 + return soplex->rowVector(i)[j];
7.89 }
7.90
7.91 void LpSoplex::_setColLowerBound(int i, Value value) {
7.92 - soplex->changeLower(i, value);
7.93 + soplex->changeLower(i, value != -INF ? value : -soplex::infinity);
7.94 + solved = false;
7.95 }
7.96
7.97 + LpSoplex::Value LpSoplex::_getColLowerBound(int i) {
7.98 + double value = soplex->lower(i);
7.99 + return value != -soplex::infinity ? value : -INF;
7.100 + }
7.101 +
7.102 void LpSoplex::_setColUpperBound(int i, Value value) {
7.103 - soplex->changeUpper(i, value);
7.104 + soplex->changeUpper(i, value != INF ? value : soplex::infinity);
7.105 + solved = false;
7.106 + }
7.107 +
7.108 + LpSoplex::Value LpSoplex::_getColUpperBound(int i) {
7.109 + double value = soplex->upper(i);
7.110 + return value != soplex::infinity ? value : INF;
7.111 }
7.112
7.113 void LpSoplex::_setRowBounds(int i, Value lb, Value ub) {
7.114 - soplex->changeRange(i, lb, ub);
7.115 + soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity,
7.116 + ub != INF ? ub : soplex::infinity);
7.117 + solved = false;
7.118 + }
7.119 + void LpSoplex::_getRowBounds(int i, Value &lower, Value &upper) {
7.120 + lower = soplex->lhs(i);
7.121 + if (lower == -soplex::infinity) lower = -INF;
7.122 + upper = soplex->rhs(i);
7.123 + if (upper == -soplex::infinity) upper = INF;
7.124 }
7.125
7.126 void LpSoplex::_setObjCoeff(int i, Value obj_coef) {
7.127 soplex->changeObj(i, obj_coef);
7.128 + solved = false;
7.129 + }
7.130 +
7.131 + LpSoplex::Value LpSoplex::_getObjCoeff(int i) {
7.132 + return soplex->obj(i);
7.133 }
7.134
7.135 void LpSoplex::_clearObj() {
7.136 for (int i = 0; i < soplex->nCols(); ++i) {
7.137 soplex->changeObj(i, 0.0);
7.138 }
7.139 + solved = false;
7.140 }
7.141
7.142 LpSoplex::SolveExitStatus LpSoplex::_solve() {
7.143 soplex::SPxSolver::Status status = soplex->solve();
7.144
7.145 - soplex::Vector pv(primal.size(), &primal[0]);
7.146 + soplex::Vector pv(primal_value.size(), &primal_value[0]);
7.147 soplex->getPrimal(pv);
7.148
7.149 - soplex::Vector dv(dual.size(), &dual[0]);
7.150 + soplex::Vector dv(dual_value.size(), &dual_value[0]);
7.151 soplex->getDual(dv);
7.152
7.153 switch (status) {
7.154 case soplex::SPxSolver::OPTIMAL:
7.155 case soplex::SPxSolver::INFEASIBLE:
7.156 case soplex::SPxSolver::UNBOUNDED:
7.157 + solved = true;
7.158 return SOLVED;
7.159 default:
7.160 return UNSOLVED;
7.161 @@ -150,11 +197,11 @@
7.162 }
7.163
7.164 LpSoplex::Value LpSoplex::_getPrimal(int i) {
7.165 - return primal[i];
7.166 + return primal_value[i];
7.167 }
7.168
7.169 LpSoplex::Value LpSoplex::_getDual(int i) {
7.170 - return dual[i];
7.171 + return dual_value[i];
7.172 }
7.173
7.174 LpSoplex::Value LpSoplex::_getPrimalValue() {
7.175 @@ -166,6 +213,7 @@
7.176 }
7.177
7.178 LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() {
7.179 + if (!solved) return UNDEFINED;
7.180 switch (soplex->status()) {
7.181 case soplex::SPxSolver::OPTIMAL:
7.182 return OPTIMAL;
7.183 @@ -179,30 +227,41 @@
7.184 }
7.185
7.186 LpSoplex::SolutionStatus LpSoplex::_getDualStatus() {
7.187 - switch (0) {
7.188 - case 0:
7.189 - return UNDEFINED;
7.190 + if (!solved) return UNDEFINED;
7.191 + switch (soplex->status()) {
7.192 + case soplex::SPxSolver::OPTIMAL:
7.193 return OPTIMAL;
7.194 + case soplex::SPxSolver::UNBOUNDED:
7.195 return INFEASIBLE;
7.196 + default:
7.197 return UNDEFINED;
7.198 }
7.199 }
7.200
7.201 LpSoplex::ProblemTypes LpSoplex::_getProblemType() {
7.202 - switch (0) {
7.203 - case 0:
7.204 + if (!solved) return UNKNOWN;
7.205 + switch (soplex->status()) {
7.206 + case soplex::SPxSolver::OPTIMAL:
7.207 return PRIMAL_DUAL_FEASIBLE;
7.208 + case soplex::SPxSolver::UNBOUNDED:
7.209 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
7.210 + default:
7.211 return UNKNOWN;
7.212 }
7.213 }
7.214
7.215 void LpSoplex::_setMax() {
7.216 soplex->changeSense(soplex::SPxSolver::MAXIMIZE);
7.217 + solved = false;
7.218 }
7.219 void LpSoplex::_setMin() {
7.220 soplex->changeSense(soplex::SPxSolver::MINIMIZE);
7.221 + solved = false;
7.222 }
7.223 + bool LpSoplex::_isMax() {
7.224 + return soplex->spxSense() == soplex::SPxSolver::MAXIMIZE;
7.225 + }
7.226 +
7.227
7.228 } //namespace lemon
7.229
8.1 --- a/lemon/lp_soplex.h Thu Feb 15 13:06:23 2007 +0000
8.2 +++ b/lemon/lp_soplex.h Thu Feb 15 14:22:08 2007 +0000
8.3 @@ -40,12 +40,15 @@
8.4 class LpSoplex :virtual public LpSolverBase {
8.5 protected:
8.6
8.7 + _lp_bits::RelocateIdHandler relocateIdHandler;
8.8 +
8.9 soplex::SoPlex* soplex;
8.10 + bool solved;
8.11
8.12 std::vector<std::string> colNames;
8.13
8.14 - std::vector<Value> primal;
8.15 - std::vector<Value> dual;
8.16 + std::vector<Value> primal_value;
8.17 + std::vector<Value> dual_value;
8.18
8.19
8.20 public:
8.21 @@ -67,15 +70,20 @@
8.22 virtual int _addRow();
8.23 virtual void _eraseCol(int i);
8.24 virtual void _eraseRow(int i);
8.25 - virtual void _getColName(int col, std::string & name);
8.26 + virtual void _getColName(int col, std::string & name);
8.27 virtual void _setColName(int col, const std::string & name);
8.28 virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
8.29 virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
8.30 virtual void _setCoeff(int row, int col, Value value);
8.31 + virtual Value _getCoeff(int row, int col);
8.32 virtual void _setColLowerBound(int i, Value value);
8.33 + virtual Value _getColLowerBound(int i);
8.34 virtual void _setColUpperBound(int i, Value value);
8.35 + virtual Value _getColUpperBound(int i);
8.36 virtual void _setRowBounds(int i, Value lower, Value upper);
8.37 + virtual void _getRowBounds(int i, Value &lower, Value &upper);
8.38 virtual void _setObjCoeff(int i, Value obj_coef);
8.39 + virtual Value _getObjCoeff(int i);
8.40 virtual void _clearObj();
8.41
8.42 virtual SolveExitStatus _solve();
8.43 @@ -91,6 +99,7 @@
8.44
8.45 virtual void _setMax();
8.46 virtual void _setMin();
8.47 + virtual bool _isMax();
8.48
8.49 };
8.50 } //END OF NAMESPACE LEMON
9.1 --- a/lemon/lp_utils.h Thu Feb 15 13:06:23 2007 +0000
9.2 +++ b/lemon/lp_utils.h Thu Feb 15 14:22:08 2007 +0000
9.3 @@ -22,6 +22,7 @@
9.4 #include <lemon/lp_base.h>
9.5
9.6 #include <lemon/lemon_reader.h>
9.7 +#include <lemon/lemon_writer.h>
9.8
9.9 namespace lemon {
9.10
9.11 @@ -319,7 +320,6 @@
9.12 /// It reads the content of the section.
9.13 virtual void read(std::istream& is) {
9.14 std::string line;
9.15 - std::map<std::string, LpSolverBase::Col> vars;
9.16 while (getline(is, line)) {
9.17 std::istringstream ls(line);
9.18 std::string sense;
9.19 @@ -359,6 +359,336 @@
9.20 ColMap cols;
9.21 };
9.22
9.23 +
9.24 +// class LpWriter : public LemonWriter::SectionWriter {
9.25 +// typedef LemonWriter::SectionWriter Parent;
9.26 +// public:
9.27 +
9.28 +
9.29 +// /// \brief Constructor.
9.30 +// ///
9.31 +// /// Constructor for LpWriter. It creates the LpWriter and attach
9.32 +// /// it into the given LemonWriter. The lp writer will add
9.33 +// /// variables, constraints and objective function to the
9.34 +// /// given lp solver.
9.35 +// LpWriter(LemonWriter& _writer, LpSolverBase& _lp,
9.36 +// const std::string& _name = std::string())
9.37 +// : Parent(_writer), lp(_lp), name(_name) {}
9.38 +
9.39 +
9.40 +// /// \brief Destructor.
9.41 +// ///
9.42 +// /// Destructor for NodeSetWriter.
9.43 +// virtual ~LpWriter() {}
9.44 +
9.45 +// private:
9.46 +// LpWriter(const LpWriter&);
9.47 +// void operator=(const LpWriter&);
9.48 +
9.49 +// protected:
9.50 +
9.51 +// /// \brief Gives back true when the SectionWriter can process
9.52 +// /// the section with the given header line.
9.53 +// ///
9.54 +// /// It gives back the header line of the \c \@lp section.
9.55 +// virtual std::string header() {
9.56 +// std::ostringstream ls(line);
9.57 +// ls << "@lp " << name;
9.58 +// return ls.str();
9.59 +// }
9.60 +
9.61 +// private:
9.62 +
9.63 +// std::ostream& writeConstraint(std::ostream& is, LpSolverBase::Constr& c) {
9.64 +// char x;
9.65 +
9.66 +
9.67 +// LpSolverBase::Expr e1, e2;
9.68 +// Relation op1;
9.69 +// is >> std::ws;
9.70 +// writexpression(is, e1);
9.71 +// is >> std::ws;
9.72 +// writeRelation(is, op1);
9.73 +// is >> std::ws;
9.74 +// writexpression(is, e2);
9.75 +// if (!is.get(x)) {
9.76 +// if (op1 == LE) {
9.77 +// c = e1 <= e2;
9.78 +// } else if (op1 == GE) {
9.79 +// c = e1 >= e2;
9.80 +// } else {
9.81 +// c = e1 == e2;
9.82 +// }
9.83 +// } else {
9.84 +// is.putback(x);
9.85 +// LpSolverBase::Expr e3;
9.86 +// Relation op2;
9.87 +// writeRelation(is, op2);
9.88 +// is >> std::ws;
9.89 +// writexpression(is, e3);
9.90 +// if (!e1.empty() || !e3.empty()) {
9.91 +// throw DataFormatError("Wrong range format");
9.92 +// }
9.93 +// if (op2 != op1 || op1 == EQ) {
9.94 +// throw DataFormatError("Wrong range format");
9.95 +// }
9.96 +// if (op1 == LE) {
9.97 +// c = e1.constComp() <= e2 <= e3.constComp();
9.98 +// } else {
9.99 +// c = e1.constComp() >= e2 >= e3.constComp();
9.100 +// }
9.101 +// }
9.102 +// }
9.103 +
9.104 +// std::ostream& writexpression(std::ostream& is, LpSolverBase::Expr& e) {
9.105 +// LpSolverBase::Col c;
9.106 +// double d;
9.107 +// char x;
9.108 +// writelement(is, c, d);
9.109 +// if (c != INVALID) {
9.110 +// e += d * c;
9.111 +// } else {
9.112 +// e += d;
9.113 +// }
9.114 +// is >> std::ws;
9.115 +// while (is.get(x) && (x == '+' || x == '-')) {
9.116 +// is >> std::ws;
9.117 +// writelement(is, c, d);
9.118 +// if (c != INVALID) {
9.119 +// e += (x == '+' ? d : -d) * c;
9.120 +// } else {
9.121 +// e += (x == '+' ? d : -d);
9.122 +// }
9.123 +// is >> std::ws;
9.124 +// }
9.125 +// if (!is) {
9.126 +// is.clear();
9.127 +// } else {
9.128 +// is.putback(x);
9.129 +// }
9.130 +// return is;
9.131 +// }
9.132 +
9.133 +// std::ostream& writelement(std::ostream& is,
9.134 +// LpSolverBase::Col& c, double& d) {
9.135 +// d = 1.0;
9.136 +// c = INVALID;
9.137 +// char x, y;
9.138 +// if (!is.get(x)) throw DataFormatError("Cannot find lp element");
9.139 +// if (x == '+' || x == '-') {
9.140 +// is >> std::ws;
9.141 +// d *= x == '-' ? -1 : 1;
9.142 +// while (is.get(x) && (x == '+' || x == '-')) {
9.143 +// d *= x == '-' ? -1 : 1;
9.144 +// is >> std::ws;
9.145 +// }
9.146 +// if (!is) throw DataFormatError("Cannot find lp element");
9.147 +// }
9.148 +// if (numFirstChar(x)) {
9.149 +// is.putback(x);
9.150 +// double e;
9.151 +// writeNum(is, e);
9.152 +// d *= e;
9.153 +// } else if (varFirstChar(x)) {
9.154 +// is.putback(x);
9.155 +// LpSolverBase::Col f;
9.156 +// writeCol(is, f);
9.157 +// c = f;
9.158 +// } else {
9.159 +// throw DataFormatError("Invalid expression format");
9.160 +// }
9.161 +// is >> std::ws;
9.162 +// while (is.get(y) && (y == '*' || y == '/')) {
9.163 +// is >> std::ws;
9.164 +// if (!is.get(x)) throw DataFormatError("Cannot find lp element");
9.165 +// if (x == '+' || x == '-') {
9.166 +// is >> std::ws;
9.167 +// d *= x == '-' ? -1 : 1;
9.168 +// while (is.get(x) && (x == '+' || x == '-')) {
9.169 +// d *= x == '-' ? -1 : 1;
9.170 +// is >> std::ws;
9.171 +// }
9.172 +// if (!is) throw DataFormatError("Cannot find lp element");
9.173 +// }
9.174 +// if (numFirstChar(x)) {
9.175 +// is.putback(x);
9.176 +// double e;
9.177 +// writeNum(is, e);
9.178 +// if (y == '*') {
9.179 +// d *= e;
9.180 +// } else {
9.181 +// d /= e;
9.182 +// }
9.183 +// } else if (varFirstChar(x)) {
9.184 +// is.putback(x);
9.185 +// LpSolverBase::Col f;
9.186 +// writeCol(is, f);
9.187 +// if (y == '*') {
9.188 +// if (c == INVALID) {
9.189 +// c = f;
9.190 +// } else {
9.191 +// throw DataFormatError("Quadratic element in expression");
9.192 +// }
9.193 +// } else {
9.194 +// throw DataFormatError("Division by variable");
9.195 +// }
9.196 +// } else {
9.197 +// throw DataFormatError("Invalid expression format");
9.198 +// }
9.199 +// is >> std::ws;
9.200 +// }
9.201 +// if (!is) {
9.202 +// is.clear();
9.203 +// } else {
9.204 +// is.putback(y);
9.205 +// }
9.206 +// return is;
9.207 +// }
9.208 +
9.209 +// std::ostream& writeCol(std::ostream& is, LpSolverBase::Col& c) {
9.210 +// char x;
9.211 +// std::string var;
9.212 +// while (is.get(x) && varChar(x)) {
9.213 +// var += x;
9.214 +// }
9.215 +// if (!is) {
9.216 +// is.clear();
9.217 +// } else {
9.218 +// is.putback(x);
9.219 +// }
9.220 +// ColMap::const_iterator it = cols.find(var);
9.221 +// if (cols.find(var) != cols.end()) {
9.222 +// c = it->second;
9.223 +// } else {
9.224 +// c = lp.addCol();
9.225 +// cols.insert(std::make_pair(var, c));
9.226 +// lp.colName(c, var);
9.227 +// }
9.228 +// return is;
9.229 +// }
9.230 +
9.231 +// std::ostream& writeNum(std::ostream& is, double& d) {
9.232 +// is >> d;
9.233 +// if (!is) throw DataFormatError("Wrong number format");
9.234 +// return is;
9.235 +// }
9.236 +
9.237 +// std::ostream& writeRelation(std::ostream& is, Relation& op) {
9.238 +// char x, y;
9.239 +// if (!is.get(x) || !(x == '<' || x == '=' || x == '>')) {
9.240 +// throw DataFormatError("Wrong relation operator");
9.241 +// }
9.242 +// if (!is.get(y) || y != '=') {
9.243 +// throw DataFormatError("Wrong relation operator");
9.244 +// }
9.245 +// switch (x) {
9.246 +// case '<': op = LE;
9.247 +// break;
9.248 +// case '=': op = EQ;
9.249 +// break;
9.250 +// case '>': op = GE;
9.251 +// break;
9.252 +// }
9.253 +// return is;
9.254 +// }
9.255 +
9.256 +// static bool relationFirstChar(char c) {
9.257 +// return c == '<' || c == '=' || c == '>';
9.258 +// }
9.259 +
9.260 +// static bool varFirstChar(char c) {
9.261 +// return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
9.262 +// }
9.263 +
9.264 +// static bool numFirstChar(char c) {
9.265 +// return (c >= '0' && c <= '9') || c == '.';
9.266 +// }
9.267 +
9.268 +// static bool varChar(char c) {
9.269 +// return (c >= '0' && c <= '9') ||
9.270 +// (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
9.271 +// }
9.272 +
9.273 +
9.274 +// void addConstraint(const LpSolverBase::Constr& constr) {
9.275 +// if (constr.expr().size() != 1) {
9.276 +// lp.addRow(constr);
9.277 +// } else {
9.278 +// Lp::Expr e = constr.expr();
9.279 +// LpSolverBase::Col col = e.begin()->first;
9.280 +// double coeff = e.begin()->second;
9.281 +// double lb = LpSolverBase::NaN;
9.282 +// double ub = LpSolverBase::NaN;
9.283 +// if (coeff > 0) {
9.284 +// if (constr.upperBounded()) {
9.285 +// lb = (constr.lowerBound() - e.constComp()) / coeff;
9.286 +// }
9.287 +// if (constr.lowerBounded()) {
9.288 +// ub = (constr.upperBound() - e.constComp()) / coeff;
9.289 +// }
9.290 +// } else if (coeff < 0) {
9.291 +// if (constr.upperBounded()) {
9.292 +// lb = (constr.upperBound() - e.constComp()) / coeff;
9.293 +// }
9.294 +// if (constr.lowerBounded()) {
9.295 +// ub = (constr.lowerBound() - e.constComp()) / coeff;
9.296 +// }
9.297 +// } else {
9.298 +// lb = -LpSolverBase::INF;
9.299 +// ub = LpSolverBase::INF;
9.300 +// }
9.301 +// lp.colLowerBound(col, lb);
9.302 +// lp.colUpperBound(col, ub);
9.303 +// }
9.304 +// }
9.305 +
9.306 +// protected:
9.307 +
9.308 +// /// \brief Writer function of the section.
9.309 +// ///
9.310 +// /// It writes the content of the section.
9.311 +// virtual void write(std::ostream& is) {
9.312 +// std::string line;
9.313 +// std::map<std::string, LpSolverBase::Col> vars;
9.314 +// while (getline(is, line)) {
9.315 +// std::istringstream ls(line);
9.316 +// std::string sense;
9.317 +// ls >> sense;
9.318 +// if (sense == "min" || sense == "max") {
9.319 +// LpSolverBase::Expr expr;
9.320 +// ls >> std::ws;
9.321 +// writeExpression(ls, expr);
9.322 +// lp.setObj(expr);
9.323 +// if (sense == "min") {
9.324 +// lp.min();
9.325 +// } else {
9.326 +// lp.max();
9.327 +// }
9.328 +// } else {
9.329 +// ls.str(line);
9.330 +// LpSolverBase::Constr constr;
9.331 +// ls >> std::ws;
9.332 +// writeConstraint(ls, constr);
9.333 +// addConstraint(constr);
9.334 +// }
9.335 +// }
9.336 +// }
9.337 +
9.338 +// virtual void missing() {
9.339 +// ErrorMessage msg;
9.340 +// msg << "Lp section not found in file: @lp " << name;
9.341 +// throw IoParameterError(msg.message());
9.342 +// }
9.343 +
9.344 +// private:
9.345 +
9.346 +// typedef std::map<std::string, LpSolverBase::Col> ColMap;
9.347 +
9.348 +// LpSolverBase& lp;
9.349 +// std::string name;
9.350 +// ColMap cols;
9.351 +// };
9.352 +
9.353 }
9.354
9.355 #endif
10.1 --- a/m4/lx_check_soplex.m4 Thu Feb 15 13:06:23 2007 +0000
10.2 +++ b/m4/lx_check_soplex.m4 Thu Feb 15 14:22:08 2007 +0000
10.3 @@ -18,9 +18,9 @@
10.4 AC_MSG_CHECKING([for SOPLEX])
10.5
10.6 if test x"$with_soplex_includedir" != x"no"; then
10.7 - SOPLEX_CFLAGS="-I$with_soplex_includedir"
10.8 + SOPLEX_CXXFLAGS="-I$with_soplex_includedir"
10.9 elif test x"$with_soplex" != x"yes"; then
10.10 - SOPLEX_CFLAGS="-I$with_soplex/include"
10.11 + SOPLEX_CXXFLAGS="-I$with_soplex/include"
10.12 fi
10.13
10.14 if test x"$with_soplex_libdir" != x"no"; then
10.15 @@ -33,7 +33,7 @@
10.16 lx_save_cxxflags="$CXXFLAGS"
10.17 lx_save_ldflags="$LDFLAGS"
10.18 lx_save_libs="$LIBS"
10.19 - CXXFLAGS="$SOPLEX_CFLAGS"
10.20 + CXXFLAGS="$SOPLEX_CXXFLAGS"
10.21 LDFLAGS="$SOPLEX_LDFLAGS"
10.22 LIBS="$SOPLEX_LIBS"
10.23
10.24 @@ -58,14 +58,14 @@
10.25 AC_DEFINE([HAVE_SOPLEX], [1], [Define to 1 if you have SOPLEX.])
10.26 AC_MSG_RESULT([yes])
10.27 else
10.28 - SOPLEX_CFLAGS=""
10.29 + SOPLEX_CXXFLAGS=""
10.30 SOPLEX_LDFLAGS=""
10.31 SOPLEX_LIBS=""
10.32 AC_MSG_RESULT([no])
10.33 fi
10.34 fi
10.35 SOPLEX_LIBS="$SOPLEX_LDFLAGS $SOPLEX_LIBS"
10.36 - AC_SUBST(SOPLEX_CFLAGS)
10.37 + AC_SUBST(SOPLEX_CXXFLAGS)
10.38 AC_SUBST(SOPLEX_LIBS)
10.39 AM_CONDITIONAL([HAVE_SOPLEX], [test x"$lx_soplex_found" = x"yes"])
10.40 ])
11.1 --- a/test/Makefile.am Thu Feb 15 13:06:23 2007 +0000
11.2 +++ b/test/Makefile.am Thu Feb 15 14:22:08 2007 +0000
11.3 @@ -49,7 +49,11 @@
11.4 else !HAVE_GLPK
11.5 if HAVE_CPLEX
11.6 check_PROGRAMS += test/lp_test test/mip_test
11.7 -endif HAVE_CPLEX
11.8 +else !HAVE_CPLEX
11.9 +if HAVE_SOPLEX
11.10 +check_PROGRAMS += test/lp_test
11.11 +endif HAVE_SOPLEX
11.12 +endif !HAVE_CPLEX
11.13 endif !HAVE_GLPK
11.14
11.15 TESTS += $(check_PROGRAMS)
11.16 @@ -89,6 +93,6 @@
11.17 test_unionfind_test_SOURCES = test/unionfind_test.cc
11.18
11.19 test_lp_test_SOURCES = test/lp_test.cc
11.20 -test_lp_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
11.21 +test_lp_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
11.22 test_mip_test_SOURCES = test/mip_test.cc
11.23 -test_mip_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS)
11.24 \ No newline at end of file
11.25 +test_mip_test_CXXFLAGS = $(GLPK_CFLAGS) $(CPLEX_CFLAGS) $(SOPLEX_CXXFLAGS)
11.26 \ No newline at end of file
12.1 --- a/test/lp_test.cc Thu Feb 15 13:06:23 2007 +0000
12.2 +++ b/test/lp_test.cc Thu Feb 15 14:22:08 2007 +0000
12.3 @@ -33,9 +33,9 @@
12.4 #include <lemon/lp_cplex.h>
12.5 #endif
12.6
12.7 -// #ifdef HAVE_SOPLEX
12.8 -// #include <lemon/lp_soplex.h>
12.9 -// #endif
12.10 +#ifdef HAVE_SOPLEX
12.11 +#include <lemon/lp_soplex.h>
12.12 +#endif
12.13
12.14 using namespace lemon;
12.15
12.16 @@ -374,11 +374,11 @@
12.17 aTest(lp_cplex2);
12.18 #endif
12.19
12.20 -// #ifdef HAVE_SOPLEX
12.21 -// LpSoplex lp_soplex1,lp_soplex2;
12.22 -// lpTest(lp_soplex1);
12.23 -// aTest(lp_soplex2);
12.24 -// #endif
12.25 +#ifdef HAVE_SOPLEX
12.26 + LpSoplex lp_soplex1,lp_soplex2;
12.27 + lpTest(lp_soplex1);
12.28 + aTest(lp_soplex2);
12.29 +#endif
12.30
12.31 return 0;
12.32 }