1.1 --- a/lemon/lp.h Tue Nov 28 17:25:22 2006 +0000
1.2 +++ b/lemon/lp.h Wed Nov 29 15:01:13 2006 +0000
1.3 @@ -28,6 +28,8 @@
1.4 #elif HAVE_CPLEX
1.5 #include <lemon/lp_cplex.h>
1.6 #include <lemon/mip_cplex.h>
1.7 +#elif HAVE_SOPLEX
1.8 +#include <lemon/lp_soplex.h>
1.9 #endif
1.10
1.11 ///\file
1.12 @@ -76,6 +78,10 @@
1.13 typedef LpCplex Lp;
1.14 typedef MipCplex Mip;
1.15 const char default_solver_name[]="CPLEX";
1.16 +#elif HAVE_SOPLEX
1.17 +#define DEFAULT_LP SOPLEX
1.18 + typedef LpSoplex Lp;
1.19 + const char default_solver_name[]="SOPLEX";
1.20 #endif
1.21 #endif
1.22
2.1 --- a/lemon/lp_base.h Tue Nov 28 17:25:22 2006 +0000
2.2 +++ b/lemon/lp_base.h Wed Nov 29 15:01:13 2006 +0000
2.3 @@ -32,7 +32,8 @@
2.4 ///\brief The interface of the LP solver interface.
2.5 ///\ingroup gen_opt_group
2.6 namespace lemon {
2.7 -
2.8 +
2.9 +
2.10 ///Internal data structure to convert floating id's to fix one's
2.11
2.12 ///\todo This might be implemented to be also usable in other places.
2.13 @@ -109,7 +110,7 @@
2.14 ///or -1 if no index has been inserted before.
2.15 int firstIndex() {return _first_index;}
2.16 };
2.17 -
2.18 +
2.19 ///Common base class for LP solvers
2.20
2.21 ///\todo Much more docs
2.22 @@ -128,7 +129,8 @@
2.23 ///an optimal solution has been found or infeasibility/unboundedness
2.24 ///has been proved.
2.25 SOLVED = 0,
2.26 - ///Any other case (including the case when some user specified limit has been exceeded)
2.27 + ///Any other case (including the case when some user specified
2.28 + ///limit has been exceeded)
2.29 UNSOLVED = 1
2.30 };
2.31
2.32 @@ -221,6 +223,9 @@
2.33 return *this;
2.34 }
2.35 };
2.36 +
2.37 + static int id(const Col& col) { return col.id; }
2.38 +
2.39
2.40 ///Refer to a row of the LP.
2.41
2.42 @@ -245,7 +250,22 @@
2.43 bool operator> (Row c) const {return id> c.id;}
2.44 bool operator==(Row c) const {return id==c.id;}
2.45 bool operator!=(Row c) const {return id!=c.id;}
2.46 - };
2.47 + };
2.48 +
2.49 + static int id(const Row& row) { return row.id; }
2.50 +
2.51 + protected:
2.52 +
2.53 + int _lpId(const Col& col) const {
2.54 + return cols.floatingId(id(col));
2.55 + }
2.56 +
2.57 + int _lpId(const Row& row) const {
2.58 + return rows.floatingId(id(row));
2.59 + }
2.60 +
2.61 +
2.62 + public:
2.63
2.64 ///Linear expression of variables and a constant component
2.65
2.66 @@ -336,6 +356,10 @@
2.67 }
2.68 }
2.69
2.70 + void simplify() const {
2.71 + const_cast<Expr*>(this)->simplify();
2.72 + }
2.73 +
2.74 ///Removes the coefficients closer to zero than \c tolerance.
2.75 void simplify(double &tolerance) {
2.76 for (Base::iterator i=Base::begin(); i!=Base::end();) {
2.77 @@ -415,9 +439,6 @@
2.78 typedef Expr::Key Key;
2.79 typedef Expr::Value Value;
2.80
2.81 -// static const Value INF;
2.82 -// static const Value NaN;
2.83 -
2.84 protected:
2.85 Expr _expr;
2.86 Value _lb,_ub;
2.87 @@ -553,6 +574,10 @@
2.88 }
2.89 }
2.90
2.91 + void simplify() const {
2.92 + const_cast<DualExpr*>(this)->simplify();
2.93 + }
2.94 +
2.95 ///Removes the coefficients closer to zero than \c tolerance.
2.96 void simplify(double &tolerance) {
2.97 for (Base::iterator i=Base::begin(); i!=Base::end();) {
2.98 @@ -563,7 +588,6 @@
2.99 }
2.100 }
2.101
2.102 -
2.103 ///Sets all coefficients to 0.
2.104 void clear() {
2.105 Base::clear();
2.106 @@ -596,12 +620,73 @@
2.107 };
2.108
2.109
2.110 + private:
2.111 +
2.112 + template <typename _Base>
2.113 + class MappedIterator {
2.114 + public:
2.115 +
2.116 + typedef _Base Base;
2.117 +
2.118 + typedef typename Base::iterator_category iterator_category;
2.119 + typedef typename Base::difference_type difference_type;
2.120 + typedef const std::pair<int, Value> value_type;
2.121 + typedef value_type reference;
2.122 + class pointer {
2.123 + public:
2.124 + pointer(value_type& _value) : value(_value) {}
2.125 + value_type* operator->() { return &value; }
2.126 + private:
2.127 + value_type value;
2.128 + };
2.129 +
2.130 + MappedIterator(const Base& _base, const LpSolverBase& _lp)
2.131 + : base(_base), lp(_lp) {}
2.132 +
2.133 + reference operator*() {
2.134 + return std::make_pair(lp._lpId(base->first), base->second);
2.135 + }
2.136 +
2.137 + pointer operator->() {
2.138 + return pointer(operator*());
2.139 + }
2.140 +
2.141 + MappedIterator& operator++() {
2.142 + ++base;
2.143 + return *this;
2.144 + }
2.145 +
2.146 + MappedIterator& operator++(int) {
2.147 + MappedIterator tmp(*this);
2.148 + ++base;
2.149 + return tmp;
2.150 + }
2.151 +
2.152 + bool operator==(const MappedIterator& it) const {
2.153 + return base == it.base;
2.154 + }
2.155 +
2.156 + bool operator!=(const MappedIterator& it) const {
2.157 + return base != it.base;
2.158 + }
2.159 +
2.160 + private:
2.161 + Base base;
2.162 + const LpSolverBase& lp;
2.163 + };
2.164 +
2.165 protected:
2.166
2.167 + /// STL compatible iterator for lp col
2.168 + typedef MappedIterator<Expr::const_iterator> LpRowIterator;
2.169 + /// STL compatible iterator for lp row
2.170 + typedef MappedIterator<DualExpr::const_iterator> LpColIterator;
2.171 +
2.172 //Abstract virtual functions
2.173 virtual LpSolverBase &_newLp() = 0;
2.174 virtual LpSolverBase &_copyLp(){
2.175 - ///\todo This should be implemented here, too, when we have problem retrieving routines. It can be overriden.
2.176 + ///\todo This should be implemented here, too, when we have
2.177 + ///problem retrieving routines. It can be overriden.
2.178
2.179 //Starting:
2.180 LpSolverBase & newlp(_newLp());
2.181 @@ -613,16 +698,10 @@
2.182 virtual int _addRow() = 0;
2.183 virtual void _eraseCol(int col) = 0;
2.184 virtual void _eraseRow(int row) = 0;
2.185 - virtual void _getColName(int col, std::string & name) = 0;
2.186 + virtual void _getColName(int col, std::string & name) = 0;
2.187 virtual void _setColName(int col, const std::string & name) = 0;
2.188 - virtual void _setRowCoeffs(int i,
2.189 - int length,
2.190 - int const * indices,
2.191 - Value const * values ) = 0;
2.192 - virtual void _setColCoeffs(int i,
2.193 - int length,
2.194 - int const * indices,
2.195 - Value const * values ) = 0;
2.196 + virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) = 0;
2.197 + virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e) = 0;
2.198 virtual void _setCoeff(int row, int col, Value value) = 0;
2.199 virtual void _setColLowerBound(int i, Value value) = 0;
2.200 virtual void _setColUpperBound(int i, Value value) = 0;
2.201 @@ -631,9 +710,7 @@
2.202 virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
2.203 virtual void _setObjCoeff(int i, Value obj_coef) = 0;
2.204 virtual void _clearObj()=0;
2.205 -// virtual void _setObj(int length,
2.206 -// int const * indices,
2.207 -// Value const * values ) = 0;
2.208 +
2.209 virtual SolveExitStatus _solve() = 0;
2.210 virtual Value _getPrimal(int i) = 0;
2.211 virtual Value _getDual(int i) = 0;
2.212 @@ -652,10 +729,7 @@
2.213
2.214 //Constant component of the objective function
2.215 Value obj_const_comp;
2.216 -
2.217 -
2.218 -
2.219 -
2.220 +
2.221 public:
2.222
2.223 ///\e
2.224 @@ -744,17 +818,9 @@
2.225 ///\param e is a dual linear expression (see \ref DualExpr)
2.226 ///a better one.
2.227 void col(Col c,const DualExpr &e) {
2.228 - std::vector<int> indices;
2.229 - std::vector<Value> values;
2.230 - indices.push_back(0);
2.231 - values.push_back(0);
2.232 - for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
2.233 - if((*i).second!=0) {
2.234 - indices.push_back(rows.floatingId((*i).first.id));
2.235 - values.push_back((*i).second);
2.236 - }
2.237 - _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
2.238 - &indices[0],&values[0]);
2.239 + e.simplify();
2.240 + _setColCoeffs(_lpId(c), LpColIterator(e.begin(), *this),
2.241 + LpColIterator(e.end(), *this));
2.242 }
2.243
2.244 ///Add a new column to the LP
2.245 @@ -849,20 +915,12 @@
2.246 ///\todo Option to control whether a constraint with a single variable is
2.247 ///added or not.
2.248 void row(Row r, Value l,const Expr &e, Value u) {
2.249 - std::vector<int> indices;
2.250 - std::vector<Value> values;
2.251 - indices.push_back(0);
2.252 - values.push_back(0);
2.253 - for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
2.254 - if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
2.255 - indices.push_back(cols.floatingId((*i).first.id));
2.256 - values.push_back((*i).second);
2.257 - }
2.258 - _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
2.259 - &indices[0],&values[0]);
2.260 -// _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
2.261 -// _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
2.262 - _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
2.263 + e.simplify();
2.264 + _setRowCoeffs(_lpId(r), LpRowIterator(e.begin(), *this),
2.265 + LpRowIterator(e.end(), *this));
2.266 +// _setRowLowerBound(_lpId(r),l-e.constComp());
2.267 +// _setRowUpperBound(_lpId(r),u-e.constComp());
2.268 + _setRowBounds(_lpId(r),l-e.constComp(),u-e.constComp());
2.269 }
2.270
2.271 ///Set a row (i.e a constraint) of the LP
2.272 @@ -870,10 +928,8 @@
2.273 ///\param r is the row to be modified
2.274 ///\param c is a linear expression (see \ref Constr)
2.275 void row(Row r, const Constr &c) {
2.276 - row(r,
2.277 - c.lowerBounded()?c.lowerBound():-INF,
2.278 - c.expr(),
2.279 - c.upperBounded()?c.upperBound():INF);
2.280 + row(r, c.lowerBounded()?c.lowerBound():-INF,
2.281 + c.expr(), c.upperBounded()?c.upperBound():INF);
2.282 }
2.283
2.284 ///Add a new row (i.e a new constraint) to the LP
2.285 @@ -904,7 +960,7 @@
2.286 ///\param c is the coloumn to be deleted
2.287 ///\todo Please check this
2.288 void eraseCol(Col c) {
2.289 - _eraseCol(cols.floatingId(c.id));
2.290 + _eraseCol(_lpId(c));
2.291 cols.erase(c.id);
2.292 }
2.293 ///Erase a row (i.e a constraint) from the LP
2.294 @@ -912,7 +968,7 @@
2.295 ///\param r is the row to be deleted
2.296 ///\todo Please check this
2.297 void eraseRow(Row r) {
2.298 - _eraseRow(rows.floatingId(r.id));
2.299 + _eraseRow(_lpId(r));
2.300 rows.erase(r.id);
2.301 }
2.302
2.303 @@ -922,7 +978,7 @@
2.304 ///\return The name of the colunm
2.305 std::string colName(Col c){
2.306 std::string name;
2.307 - _getColName(cols.floatingId(c.id), name);
2.308 + _getColName(_lpId(c), name);
2.309 return name;
2.310 }
2.311
2.312 @@ -930,8 +986,8 @@
2.313
2.314 ///\param c is the coresponding coloumn
2.315 ///\param name The name to be given
2.316 - void colName(Col c, const std::string & name){
2.317 - _setColName(cols.floatingId(c.id), name);
2.318 + void colName(Col c, const std::string& name){
2.319 + _setColName(_lpId(c), name);
2.320 }
2.321
2.322 /// Set an element of the coefficient matrix of the LP
2.323 @@ -941,7 +997,7 @@
2.324 ///\param val is the new value of the coefficient
2.325
2.326 void coeff(Row r, Col c, Value val){
2.327 - _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
2.328 + _setCoeff(_lpId(r),_lpId(c), val);
2.329 }
2.330
2.331 /// Set the lower bound of a column (i.e a variable)
2.332 @@ -950,7 +1006,7 @@
2.333 /// extended number of type Value, i.e. a finite number of type
2.334 /// Value or -\ref INF.
2.335 void colLowerBound(Col c, Value value) {
2.336 - _setColLowerBound(cols.floatingId(c.id),value);
2.337 + _setColLowerBound(_lpId(c),value);
2.338 }
2.339
2.340 ///\brief Set the lower bound of several columns
2.341 @@ -996,7 +1052,7 @@
2.342 /// extended number of type Value, i.e. a finite number of type
2.343 /// Value or \ref INF.
2.344 void colUpperBound(Col c, Value value) {
2.345 - _setColUpperBound(cols.floatingId(c.id),value);
2.346 + _setColUpperBound(_lpId(c),value);
2.347 };
2.348
2.349 ///\brief Set the lower bound of several columns
2.350 @@ -1043,8 +1099,8 @@
2.351 /// extended number of type Value, i.e. a finite number of type
2.352 /// Value, -\ref INF or \ref INF.
2.353 void colBounds(Col c, Value lower, Value upper) {
2.354 - _setColLowerBound(cols.floatingId(c.id),lower);
2.355 - _setColUpperBound(cols.floatingId(c.id),upper);
2.356 + _setColLowerBound(_lpId(c),lower);
2.357 + _setColUpperBound(_lpId(c),upper);
2.358 }
2.359
2.360 ///\brief Set the lower and the upper bound of several columns
2.361 @@ -1091,7 +1147,7 @@
2.362 // /// extended number of type Value, i.e. a finite number of type
2.363 // /// Value or -\ref INF.
2.364 // void rowLowerBound(Row r, Value value) {
2.365 -// _setRowLowerBound(rows.floatingId(r.id),value);
2.366 +// _setRowLowerBound(_lpId(r),value);
2.367 // };
2.368 // /// Set the upper bound of a row (i.e a constraint)
2.369
2.370 @@ -1099,7 +1155,7 @@
2.371 // /// extended number of type Value, i.e. a finite number of type
2.372 // /// Value or \ref INF.
2.373 // void rowUpperBound(Row r, Value value) {
2.374 -// _setRowUpperBound(rows.floatingId(r.id),value);
2.375 +// _setRowUpperBound(_lpId(r),value);
2.376 // };
2.377
2.378 /// Set the lower and the upper bounds of a row (i.e a constraint)
2.379 @@ -1109,12 +1165,12 @@
2.380 /// extended number of type Value, i.e. a finite number of type
2.381 /// Value, -\ref INF or \ref INF.
2.382 void rowBounds(Row c, Value lower, Value upper) {
2.383 - _setRowBounds(rows.floatingId(c.id),lower, upper);
2.384 - // _setRowUpperBound(rows.floatingId(c.id),upper);
2.385 + _setRowBounds(_lpId(c),lower, upper);
2.386 + // _setRowUpperBound(_lpId(c),upper);
2.387 }
2.388
2.389 ///Set an element of the objective function
2.390 - void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
2.391 + void objCoeff(Col c, Value v) {_setObjCoeff(_lpId(c),v); };
2.392 ///Set the objective function
2.393
2.394 ///\param e is a linear expression of type \ref Expr.
2.395 @@ -1170,13 +1226,13 @@
2.396 }
2.397
2.398 ///\e
2.399 - Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
2.400 + Value primal(Col c) { return _getPrimal(_lpId(c)); }
2.401
2.402 ///\e
2.403 - Value dual(Row r) { return _getDual(rows.floatingId(r.id)); }
2.404 + Value dual(Row r) { return _getDual(_lpId(r)); }
2.405
2.406 ///\e
2.407 - bool isBasicCol(Col c) { return _isBasicCol(cols.floatingId(c.id)); }
2.408 + bool isBasicCol(Col c) { return _isBasicCol(_lpId(c)); }
2.409
2.410 ///\e
2.411
2.412 @@ -1213,14 +1269,14 @@
2.413 ///
2.414 ///Sets the type of the given coloumn to the given type.
2.415 void colType(Col c, ColTypes col_type) {
2.416 - _colType(cols.floatingId(c.id),col_type);
2.417 + _colType(_lpId(c),col_type);
2.418 }
2.419
2.420 ///Gives back the type of the column.
2.421 ///
2.422 ///Gives back the type of the column.
2.423 ColTypes colType(Col c){
2.424 - return _colType(cols.floatingId(c.id));
2.425 + return _colType(_lpId(c));
2.426 }
2.427
2.428 ///Sets the type of the given Col to integer or remove that property.
2.429 @@ -1440,7 +1496,7 @@
2.430 ///\relates LpSolverBase::DualExpr
2.431 ///
2.432 inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
2.433 - const LpSolverBase::DualExpr &b)
2.434 + const LpSolverBase::DualExpr &b)
2.435 {
2.436 LpSolverBase::DualExpr tmp(a);
2.437 tmp+=b;
2.438 @@ -1451,7 +1507,7 @@
2.439 ///\relates LpSolverBase::DualExpr
2.440 ///
2.441 inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
2.442 - const LpSolverBase::DualExpr &b)
2.443 + const LpSolverBase::DualExpr &b)
2.444 {
2.445 LpSolverBase::DualExpr tmp(a);
2.446 tmp-=b;
2.447 @@ -1462,7 +1518,7 @@
2.448 ///\relates LpSolverBase::DualExpr
2.449 ///
2.450 inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
2.451 - const LpSolverBase::Value &b)
2.452 + const LpSolverBase::Value &b)
2.453 {
2.454 LpSolverBase::DualExpr tmp(a);
2.455 tmp*=b;
2.456 @@ -1474,7 +1530,7 @@
2.457 ///\relates LpSolverBase::DualExpr
2.458 ///
2.459 inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
2.460 - const LpSolverBase::DualExpr &b)
2.461 + const LpSolverBase::DualExpr &b)
2.462 {
2.463 LpSolverBase::DualExpr tmp(b);
2.464 tmp*=a;
2.465 @@ -1485,7 +1541,7 @@
2.466 ///\relates LpSolverBase::DualExpr
2.467 ///
2.468 inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
2.469 - const LpSolverBase::Value &b)
2.470 + const LpSolverBase::Value &b)
2.471 {
2.472 LpSolverBase::DualExpr tmp(a);
2.473 tmp/=b;
3.1 --- a/lemon/lp_cplex.cc Tue Nov 28 17:25:22 2006 +0000
3.2 +++ b/lemon/lp_cplex.cc Wed Nov 29 15:01:13 2006 +0000
3.3 @@ -109,38 +109,36 @@
3.4 }
3.5
3.6 ///\warning Data at index 0 is ignored in the arrays.
3.7 - void LpCplex::_setRowCoeffs(int i,
3.8 - int length,
3.9 - int const * indices,
3.10 - Value const * values )
3.11 + void LpCplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e)
3.12 {
3.13 - int rowlist[length+1];
3.14 - int* p=rowlist;
3.15 - for (int k=1;k<=length;++k){
3.16 - rowlist[k]=i;
3.17 + std::vector<int> indices;
3.18 + std::vector<int> rowlist;
3.19 + std::vector<Value> values;
3.20 +
3.21 + for(LpRowIterator it=b; it!=e; ++it) {
3.22 + indices.push_back(it->first);
3.23 + values.push_back(it->second);
3.24 + rowlist.push_back(i);
3.25 }
3.26 - status = CPXchgcoeflist(env, lp,
3.27 - length,
3.28 - p+1,
3.29 - const_cast<int * >(indices+1),
3.30 - const_cast<Value * >(values+1));
3.31 +
3.32 + status = CPXchgcoeflist(env, lp, values.size(),
3.33 + &rowlist[0], &indices[0], &values[0]);
3.34 }
3.35
3.36 - void LpCplex::_setColCoeffs(int i,
3.37 - int length,
3.38 - int const * indices,
3.39 - Value const * values)
3.40 + void LpCplex::_setColCoeffs(int i, LpColIterator b, LpColIterator e)
3.41 {
3.42 - int collist[length+1];
3.43 - int* p=collist;
3.44 - for (int k=1;k<=length;++k){
3.45 - collist[k]=i;
3.46 + std::vector<int> indices;
3.47 + std::vector<int> collist;
3.48 + std::vector<Value> values;
3.49 +
3.50 + for(LpColIterator it=b; it!=e; ++it) {
3.51 + indices.push_back(it->first);
3.52 + values.push_back(it->second);
3.53 + collist.push_back(i);
3.54 }
3.55 - status = CPXchgcoeflist(env, lp,
3.56 - length,
3.57 - const_cast<int * >(indices+1),
3.58 - p+1,
3.59 - const_cast<Value * >(values+1));
3.60 +
3.61 + status = CPXchgcoeflist(env, lp, values.size(),
3.62 + &indices[0], &collist[0], &values[0]);
3.63 }
3.64
3.65 void LpCplex::_setCoeff(int row, int col, Value value)
4.1 --- a/lemon/lp_cplex.h Tue Nov 28 17:25:22 2006 +0000
4.2 +++ b/lemon/lp_cplex.h Wed Nov 29 15:01:13 2006 +0000
4.3 @@ -61,14 +61,8 @@
4.4 virtual void _eraseRow(int i);
4.5 virtual void _getColName(int col, std::string & name);
4.6 virtual void _setColName(int col, const std::string & name);
4.7 - virtual void _setRowCoeffs(int i,
4.8 - int length,
4.9 - const int * indices,
4.10 - const Value * values );
4.11 - virtual void _setColCoeffs(int i,
4.12 - int length,
4.13 - const int * indices,
4.14 - const Value * values);
4.15 + virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
4.16 + virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
4.17 virtual void _setCoeff(int row, int col, Value value);
4.18 virtual void _setColLowerBound(int i, Value value);
4.19 virtual void _setColUpperBound(int i, Value value);
5.1 --- a/lemon/lp_glpk.cc Tue Nov 28 17:25:22 2006 +0000
5.2 +++ b/lemon/lp_glpk.cc Wed Nov 29 15:01:13 2006 +0000
5.3 @@ -116,60 +116,96 @@
5.4 lpx_set_col_name(lp,col,const_cast<char*>(name.c_str()));
5.5 }
5.6
5.7 - void LpGlpk::_setRowCoeffs(int i,
5.8 - int length,
5.9 - const int * indices,
5.10 - const Value * values )
5.11 + void LpGlpk::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e)
5.12 {
5.13 - lpx_set_mat_row(lp, i, length,
5.14 - const_cast<int * >(indices) ,
5.15 - const_cast<Value * >(values));
5.16 + std::vector<int> indices;
5.17 + std::vector<Value> values;
5.18 +
5.19 + indices.push_back(0);
5.20 + values.push_back(0);
5.21 +
5.22 + for(LpRowIterator it=b; it!=e; ++it) {
5.23 + indices.push_back(it->first);
5.24 + values.push_back(it->second);
5.25 + }
5.26 +
5.27 + lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]);
5.28 }
5.29
5.30 - void LpGlpk::_setColCoeffs(int i,
5.31 - int length,
5.32 - const int * indices,
5.33 - const Value * values)
5.34 - {
5.35 - lpx_set_mat_col(lp, i, length,
5.36 - const_cast<int * >(indices),
5.37 - const_cast<Value * >(values));
5.38 + void LpGlpk::_setColCoeffs(int i, LpColIterator b, LpColIterator e) {
5.39 +
5.40 + std::vector<int> indices;
5.41 + std::vector<Value> values;
5.42 +
5.43 + indices.push_back(0);
5.44 + values.push_back(0);
5.45 +
5.46 + for(LpColIterator it=b; it!=e; ++it) {
5.47 + indices.push_back(it->first);
5.48 + values.push_back(it->second);
5.49 + }
5.50 +
5.51 + lpx_set_mat_col(lp, i, values.size() - 1, &indices[0], &values[0]);
5.52 }
5.53
5.54
5.55 void LpGlpk::_setCoeff(int row, int col, Value value)
5.56 {
5.57 - ///FIXME Of course this is not efficient at all, but GLPK knows not more.
5.58 - // First approach: get one row, apply changes and set it again
5.59 - //(one idea to improve this: maybe it is better to do this with 1 coloumn)
5.60 +
5.61 + if (lpx_get_num_cols(lp) < lpx_get_num_rows(lp)) {
5.62 +
5.63 + int length=lpx_get_mat_row(lp, row, 0, 0);
5.64 +
5.65 + std::vector<int> indices(length + 2);
5.66 + std::vector<Value> values(length + 2);
5.67 +
5.68 + lpx_get_mat_row(lp, row, &indices[0], &values[0]);
5.69 +
5.70 + //The following code does not suppose that the elements of the
5.71 + //array indices are sorted
5.72 + bool found=false;
5.73 + for (int i = 1; i <= length; ++i) {
5.74 + if (indices[i]==col){
5.75 + found=true;
5.76 + values[i]=value;
5.77 + break;
5.78 + }
5.79 + }
5.80 + if (!found){
5.81 + ++length;
5.82 + indices[length]=col;
5.83 + values[length]=value;
5.84 + }
5.85
5.86 - int mem_length=2+lpx_get_num_cols(lp);
5.87 - int* indices = new int[mem_length];
5.88 - Value* values = new Value[mem_length];
5.89 + lpx_set_mat_row(lp, row, length, &indices[0], &values[0]);
5.90 +
5.91 + } else {
5.92 +
5.93 + int length=lpx_get_mat_col(lp, col, 0, 0);
5.94 +
5.95 + std::vector<int> indices(length + 2);
5.96 + std::vector<Value> values(length + 2);
5.97 +
5.98 + lpx_get_mat_col(lp, col, &indices[0], &values[0]);
5.99 +
5.100 + //The following code does not suppose that the elements of the
5.101 + //array indices are sorted
5.102 + bool found=false;
5.103 + for (int i = 1; i <= length; ++i) {
5.104 + if (indices[i]==col){
5.105 + found=true;
5.106 + values[i]=value;
5.107 + break;
5.108 + }
5.109 + }
5.110 + if (!found){
5.111 + ++length;
5.112 + indices[length]=row;
5.113 + values[length]=value;
5.114 + }
5.115
5.116 -
5.117 - int length=lpx_get_mat_row(lp, row, indices, values);
5.118 -
5.119 - //The following code does not suppose that the elements of the array indices are sorted
5.120 - int i=1;
5.121 - bool found=false;
5.122 - while (i <= length && !found){
5.123 - if (indices[i]==col){
5.124 - found = true;
5.125 - values[i]=value;
5.126 - }
5.127 - ++i;
5.128 + lpx_set_mat_col(lp, col, length, &indices[0], &values[0]);
5.129 }
5.130 - if (!found){
5.131 - ++length;
5.132 - indices[length]=col;
5.133 - values[length]=value;
5.134 - }
5.135 -
5.136 - lpx_set_mat_row(lp, row, length, indices, values);
5.137 - delete [] indices;
5.138 - delete [] values;
5.139 -
5.140 }
5.141
5.142 void LpGlpk::_setColLowerBound(int i, Value lo)
6.1 --- a/lemon/lp_glpk.h Tue Nov 28 17:25:22 2006 +0000
6.2 +++ b/lemon/lp_glpk.h Wed Nov 29 15:01:13 2006 +0000
6.3 @@ -56,14 +56,8 @@
6.4 virtual void _eraseRow(int i);
6.5 virtual void _getColName(int col, std::string & name);
6.6 virtual void _setColName(int col, const std::string & name);
6.7 - virtual void _setRowCoeffs(int i,
6.8 - int length,
6.9 - const int * indices,
6.10 - const Value * values );
6.11 - virtual void _setColCoeffs(int i,
6.12 - int length,
6.13 - const int * indices,
6.14 - const Value * values);
6.15 + virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
6.16 + virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
6.17 virtual void _setCoeff(int row, int col, Value value);
6.18 virtual void _setColLowerBound(int i, Value value);
6.19 virtual void _setColUpperBound(int i, Value value);
7.1 --- a/lemon/lp_skeleton.cc Tue Nov 28 17:25:22 2006 +0000
7.2 +++ b/lemon/lp_skeleton.cc Wed Nov 29 15:01:13 2006 +0000
7.3 @@ -58,18 +58,10 @@
7.4 }
7.5
7.6
7.7 - void LpSkeleton::_setRowCoeffs(int,
7.8 - int,
7.9 - int const *,
7.10 - Value const *)
7.11 - {
7.12 + void LpSkeleton::_setRowCoeffs(int, LpRowIterator, LpRowIterator) {
7.13 }
7.14
7.15 - void LpSkeleton::_setColCoeffs(int,
7.16 - int,
7.17 - int const *,
7.18 - Value const *)
7.19 - {
7.20 + void LpSkeleton::_setColCoeffs(int, LpColIterator, LpColIterator) {
7.21 }
7.22
7.23 void LpSkeleton::_setCoeff(int, int, Value )
8.1 --- a/lemon/lp_skeleton.h Tue Nov 28 17:25:22 2006 +0000
8.2 +++ b/lemon/lp_skeleton.h Wed Nov 29 15:01:13 2006 +0000
8.3 @@ -43,26 +43,14 @@
8.4 /// \e
8.5 virtual void _eraseRow(int i);
8.6 /// \e
8.7 - virtual void _getColName(int col, std::string & name);
8.8 + virtual void _getColName(int col, std::string & name);
8.9 /// \e
8.10 virtual void _setColName(int col, const std::string & name);
8.11
8.12 /// \e
8.13 -
8.14 - /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
8.15 - ///
8.16 - virtual void _setRowCoeffs(int i,
8.17 - int length,
8.18 - int const * indices,
8.19 - Value const * values );
8.20 + virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
8.21 /// \e
8.22 -
8.23 - /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
8.24 - ///
8.25 - virtual void _setColCoeffs(int i,
8.26 - int length,
8.27 - int const * indices,
8.28 - Value const * values );
8.29 + virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
8.30
8.31 /// Set one element of the coefficient matrix
8.32 virtual void _setCoeff(int row, int col, Value value);