1.1 --- a/lemon/lp_base.h Thu Feb 15 14:22:08 2007 +0000
1.2 +++ b/lemon/lp_base.h Thu Feb 15 19:15:14 2007 +0000
1.3 @@ -49,7 +49,7 @@
1.4 _lp_bits::LpId cols;
1.5
1.6 public:
1.7 -
1.8 +
1.9 ///Possible outcomes of an LP solving procedure
1.10 enum SolveExitStatus {
1.11 ///This means that the problem has been successfully solved: either
1.12 @@ -122,6 +122,7 @@
1.13 int id;
1.14 friend class LpSolverBase;
1.15 friend class MipSolverBase;
1.16 + explicit Col(int _id) : id(_id) {}
1.17 public:
1.18 typedef Value ExprValue;
1.19 typedef True LpSolverCol;
1.20 @@ -165,6 +166,7 @@
1.21 protected:
1.22 int id;
1.23 friend class LpSolverBase;
1.24 + explicit Row(int _id) : id(_id) {}
1.25 public:
1.26 typedef Value ExprValue;
1.27 typedef True LpSolverRow;
1.28 @@ -177,6 +179,22 @@
1.29 bool operator!=(Row c) const {return id!=c.id;}
1.30 };
1.31
1.32 + class RowIt : public Row {
1.33 + LpSolverBase *_lp;
1.34 + public:
1.35 + RowIt() {}
1.36 + RowIt(LpSolverBase &lp) : _lp(&lp)
1.37 + {
1.38 + _lp->rows.firstFix(id);
1.39 + }
1.40 + RowIt(const Invalid&) : Row(INVALID) {}
1.41 + RowIt &operator++()
1.42 + {
1.43 + _lp->rows.nextFix(id);
1.44 + return *this;
1.45 + }
1.46 + };
1.47 +
1.48 static int id(const Row& row) { return row.id; }
1.49
1.50 protected:
1.51 @@ -189,6 +207,14 @@
1.52 return rows.floatingId(id(row));
1.53 }
1.54
1.55 + Col _item(int id, Col) const {
1.56 + return Col(cols.fixId(id));
1.57 + }
1.58 +
1.59 + Row _item(int id, Row) const {
1.60 + return Row(rows.fixId(id));
1.61 + }
1.62 +
1.63
1.64 public:
1.65
1.66 @@ -581,11 +607,60 @@
1.67
1.68 private:
1.69
1.70 - template <typename _Base>
1.71 - class MappedIterator {
1.72 + template <typename _Expr>
1.73 + class MappedOutputIterator {
1.74 public:
1.75
1.76 - typedef _Base Base;
1.77 + typedef std::insert_iterator<_Expr> Base;
1.78 +
1.79 + typedef std::output_iterator_tag iterator_category;
1.80 + typedef void difference_type;
1.81 + typedef void value_type;
1.82 + typedef void reference;
1.83 + typedef void pointer;
1.84 +
1.85 + MappedOutputIterator(const Base& _base, const LpSolverBase& _lp)
1.86 + : base(_base), lp(_lp) {}
1.87 +
1.88 + MappedOutputIterator& operator*() {
1.89 + return *this;
1.90 + }
1.91 +
1.92 + MappedOutputIterator& operator=(const std::pair<int, Value>& value) {
1.93 + *base = std::make_pair(lp._item(value.first, typename _Expr::Key()),
1.94 + value.second);
1.95 + return *this;
1.96 + }
1.97 +
1.98 + MappedOutputIterator& operator++() {
1.99 + ++base;
1.100 + return *this;
1.101 + }
1.102 +
1.103 + MappedOutputIterator operator++(int) {
1.104 + MappedOutputIterator tmp(*this);
1.105 + ++base;
1.106 + return tmp;
1.107 + }
1.108 +
1.109 + bool operator==(const MappedOutputIterator& it) const {
1.110 + return base == it.base;
1.111 + }
1.112 +
1.113 + bool operator!=(const MappedOutputIterator& it) const {
1.114 + return base != it.base;
1.115 + }
1.116 +
1.117 + private:
1.118 + Base base;
1.119 + const LpSolverBase& lp;
1.120 + };
1.121 +
1.122 + template <typename Expr>
1.123 + class MappedInputIterator {
1.124 + public:
1.125 +
1.126 + typedef typename Expr::const_iterator Base;
1.127
1.128 typedef typename Base::iterator_category iterator_category;
1.129 typedef typename Base::difference_type difference_type;
1.130 @@ -599,7 +674,7 @@
1.131 value_type value;
1.132 };
1.133
1.134 - MappedIterator(const Base& _base, const LpSolverBase& _lp)
1.135 + MappedInputIterator(const Base& _base, const LpSolverBase& _lp)
1.136 : base(_base), lp(_lp) {}
1.137
1.138 reference operator*() {
1.139 @@ -610,22 +685,22 @@
1.140 return pointer(operator*());
1.141 }
1.142
1.143 - MappedIterator& operator++() {
1.144 + MappedInputIterator& operator++() {
1.145 ++base;
1.146 return *this;
1.147 }
1.148
1.149 - MappedIterator& operator++(int) {
1.150 - MappedIterator tmp(*this);
1.151 + MappedInputIterator operator++(int) {
1.152 + MappedInputIterator tmp(*this);
1.153 ++base;
1.154 return tmp;
1.155 }
1.156
1.157 - bool operator==(const MappedIterator& it) const {
1.158 + bool operator==(const MappedInputIterator& it) const {
1.159 return base == it.base;
1.160 }
1.161
1.162 - bool operator!=(const MappedIterator& it) const {
1.163 + bool operator!=(const MappedInputIterator& it) const {
1.164 return base != it.base;
1.165 }
1.166
1.167 @@ -637,9 +712,14 @@
1.168 protected:
1.169
1.170 /// STL compatible iterator for lp col
1.171 - typedef MappedIterator<Expr::const_iterator> LpRowIterator;
1.172 + typedef MappedInputIterator<Expr> ConstRowIterator;
1.173 /// STL compatible iterator for lp row
1.174 - typedef MappedIterator<DualExpr::const_iterator> LpColIterator;
1.175 + typedef MappedInputIterator<DualExpr> ConstColIterator;
1.176 +
1.177 + /// STL compatible iterator for lp col
1.178 + typedef MappedOutputIterator<Expr> RowIterator;
1.179 + /// STL compatible iterator for lp row
1.180 + typedef MappedOutputIterator<DualExpr> ColIterator;
1.181
1.182 //Abstract virtual functions
1.183 virtual LpSolverBase &_newLp() = 0;
1.184 @@ -659,11 +739,14 @@
1.185 virtual void _eraseRow(int row) = 0;
1.186 virtual void _getColName(int col, std::string & name) = 0;
1.187 virtual void _setColName(int col, const std::string & name) = 0;
1.188 - virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) = 0;
1.189 - virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e) = 0;
1.190 + virtual void _setRowCoeffs(int i, ConstRowIterator b,
1.191 + ConstRowIterator e) = 0;
1.192 + virtual void _getRowCoeffs(int i, RowIterator b) = 0;
1.193 + virtual void _setColCoeffs(int i, ConstColIterator b,
1.194 + ConstColIterator e) = 0;
1.195 + virtual void _getColCoeffs(int i, ColIterator b) = 0;
1.196 virtual void _setCoeff(int row, int col, Value value) = 0;
1.197 virtual Value _getCoeff(int row, int col) = 0;
1.198 -
1.199 virtual void _setColLowerBound(int i, Value value) = 0;
1.200 virtual Value _getColLowerBound(int i) = 0;
1.201 virtual void _setColUpperBound(int i, Value value) = 0;
1.202 @@ -786,8 +869,18 @@
1.203 ///a better one.
1.204 void col(Col c,const DualExpr &e) {
1.205 e.simplify();
1.206 - _setColCoeffs(_lpId(c), LpColIterator(e.begin(), *this),
1.207 - LpColIterator(e.end(), *this));
1.208 + _setColCoeffs(_lpId(c), ConstColIterator(e.begin(), *this),
1.209 + ConstColIterator(e.end(), *this));
1.210 + }
1.211 +
1.212 + ///Get a column (i.e a dual constraint) of the LP
1.213 +
1.214 + ///\param r is the column to get
1.215 + ///\return the dual expression associated to the column
1.216 + DualExpr col(Col c) {
1.217 + DualExpr e;
1.218 + _getColCoeffs(_lpId(c), ColIterator(std::inserter(e, e.end()), *this));
1.219 + return e;
1.220 }
1.221
1.222 ///Add a new column to the LP
1.223 @@ -883,9 +976,9 @@
1.224 ///added or not.
1.225 void row(Row r, Value l,const Expr &e, Value u) {
1.226 e.simplify();
1.227 - _setRowCoeffs(_lpId(r), LpRowIterator(e.begin(), *this),
1.228 - LpRowIterator(e.end(), *this));
1.229 - _setRowBounds(_lpId(r),l-e.constComp(),u-e.constComp());
1.230 + _setRowCoeffs(_lpId(r), ConstRowIterator(e.begin(), *this),
1.231 + ConstRowIterator(e.end(), *this));
1.232 + _setRowBounds(_lpId(r),l-e.constComp(),u-e.constComp());
1.233 }
1.234
1.235 ///Set a row (i.e a constraint) of the LP
1.236 @@ -897,6 +990,17 @@
1.237 c.expr(), c.upperBounded()?c.upperBound():INF);
1.238 }
1.239
1.240 +
1.241 + ///Get a row (i.e a constraint) of the LP
1.242 +
1.243 + ///\param r is the row to get
1.244 + ///\return the expression associated to the row
1.245 + Expr row(Row r) {
1.246 + Expr e;
1.247 + _getRowCoeffs(_lpId(r), RowIterator(std::inserter(e, e.end()), *this));
1.248 + return e;
1.249 + }
1.250 +
1.251 ///Add a new row (i.e a new constraint) to the LP
1.252
1.253 ///\param l is the lower bound (-\ref INF means no bound)
1.254 @@ -1177,6 +1281,21 @@
1.255 obj_const_comp=e.constComp();
1.256 }
1.257
1.258 + ///Get the objective function
1.259 +
1.260 + ///\return the objective function as a linear expression of type \ref Expr.
1.261 + Expr obj() {
1.262 + Expr e;
1.263 + for (ColIt it(*this); it != INVALID; ++it) {
1.264 + double c = objCoeff(it);
1.265 + if (c != 0.0) {
1.266 + e.insert(std::make_pair(it, c));
1.267 + }
1.268 + }
1.269 + return e;
1.270 + }
1.271 +
1.272 +
1.273 ///Maximize
1.274 void max() { _setMax(); }
1.275 ///Minimize
2.1 --- a/lemon/lp_cplex.cc Thu Feb 15 14:22:08 2007 +0000
2.2 +++ b/lemon/lp_cplex.cc Thu Feb 15 19:15:14 2007 +0000
2.3 @@ -109,13 +109,13 @@
2.4 }
2.5
2.6 ///\warning Data at index 0 is ignored in the arrays.
2.7 - void LpCplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e)
2.8 + void LpCplex::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e)
2.9 {
2.10 std::vector<int> indices;
2.11 std::vector<int> rowlist;
2.12 std::vector<Value> values;
2.13
2.14 - for(LpRowIterator it=b; it!=e; ++it) {
2.15 + for(ConstRowIterator it=b; it!=e; ++it) {
2.16 indices.push_back(it->first);
2.17 values.push_back(it->second);
2.18 rowlist.push_back(i);
2.19 @@ -124,14 +124,18 @@
2.20 status = CPXchgcoeflist(env, lp, values.size(),
2.21 &rowlist[0], &indices[0], &values[0]);
2.22 }
2.23 +
2.24 + void LpSoplex::_getRowCoeffs(int i, RowIterator b) {
2.25 + /// \todo implement
2.26 + }
2.27
2.28 - void LpCplex::_setColCoeffs(int i, LpColIterator b, LpColIterator e)
2.29 + void LpCplex::_setColCoeffs(int i, ConstColIterator b, ConstColIterator e)
2.30 {
2.31 std::vector<int> indices;
2.32 std::vector<int> collist;
2.33 std::vector<Value> values;
2.34
2.35 - for(LpColIterator it=b; it!=e; ++it) {
2.36 + for(ConstColIterator it=b; it!=e; ++it) {
2.37 indices.push_back(it->first);
2.38 values.push_back(it->second);
2.39 collist.push_back(i);
2.40 @@ -140,6 +144,10 @@
2.41 status = CPXchgcoeflist(env, lp, values.size(),
2.42 &indices[0], &collist[0], &values[0]);
2.43 }
2.44 +
2.45 + void LpSoplex::_getColCoeffs(int i, ColIterator b) {
2.46 + /// \todo implement
2.47 + }
2.48
2.49 void LpCplex::_setCoeff(int row, int col, Value value)
2.50 {
3.1 --- a/lemon/lp_cplex.h Thu Feb 15 14:22:08 2007 +0000
3.2 +++ b/lemon/lp_cplex.h Thu Feb 15 19:15:14 2007 +0000
3.3 @@ -62,8 +62,10 @@
3.4 virtual void _eraseRow(int i);
3.5 virtual void _getColName(int col, std::string & name);
3.6 virtual void _setColName(int col, const std::string & name);
3.7 - virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
3.8 - virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
3.9 + virtual void _setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e);
3.10 + virtual void _getRowCoeffs(int i, RowIterator b);
3.11 + virtual void _setColCoeffs(int i, ConstColIterator b, ConstColIterator e);
3.12 + virtual void _getColCoeffs(int i, ColIterator b);
3.13 virtual void _setCoeff(int row, int col, Value value);
3.14 virtual Value _getCoeff(int row, int col);
3.15
4.1 --- a/lemon/lp_glpk.cc Thu Feb 15 14:22:08 2007 +0000
4.2 +++ b/lemon/lp_glpk.cc Thu Feb 15 19:15:14 2007 +0000
4.3 @@ -126,7 +126,7 @@
4.4
4.5 }
4.6
4.7 - void LpGlpk::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e)
4.8 + void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e)
4.9 {
4.10 std::vector<int> indices;
4.11 std::vector<Value> values;
4.12 @@ -134,15 +134,30 @@
4.13 indices.push_back(0);
4.14 values.push_back(0);
4.15
4.16 - for(LpRowIterator it=b; it!=e; ++it) {
4.17 + for(ConstRowIterator it=b; it!=e; ++it) {
4.18 indices.push_back(it->first);
4.19 values.push_back(it->second);
4.20 }
4.21
4.22 lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]);
4.23 }
4.24 +
4.25 + void LpGlpk::_getRowCoeffs(int i, RowIterator b)
4.26 + {
4.27 + int length = lpx_get_mat_row(lp, i, 0, 0);
4.28 +
4.29 + std::vector<int> indices(length + 1);
4.30 + std::vector<Value> values(length + 1);
4.31 +
4.32 + lpx_get_mat_row(lp, i, &indices[0], &values[0]);
4.33 +
4.34 + for (int i = 1; i <= length; ++i) {
4.35 + *b = std::make_pair(indices[i], values[i]);
4.36 + ++b;
4.37 + }
4.38 + }
4.39
4.40 - void LpGlpk::_setColCoeffs(int i, LpColIterator b, LpColIterator e) {
4.41 + void LpGlpk::_setColCoeffs(int i, ConstColIterator b, ConstColIterator e) {
4.42
4.43 std::vector<int> indices;
4.44 std::vector<Value> values;
4.45 @@ -150,7 +165,7 @@
4.46 indices.push_back(0);
4.47 values.push_back(0);
4.48
4.49 - for(LpColIterator it=b; it!=e; ++it) {
4.50 + for(ConstColIterator it=b; it!=e; ++it) {
4.51 indices.push_back(it->first);
4.52 values.push_back(it->second);
4.53 }
4.54 @@ -158,6 +173,20 @@
4.55 lpx_set_mat_col(lp, i, values.size() - 1, &indices[0], &values[0]);
4.56 }
4.57
4.58 + void LpGlpk::_getColCoeffs(int i, ColIterator b)
4.59 + {
4.60 + int length = lpx_get_mat_col(lp, i, 0, 0);
4.61 +
4.62 + std::vector<int> indices(length + 1);
4.63 + std::vector<Value> values(length + 1);
4.64 +
4.65 + lpx_get_mat_col(lp, i, &indices[0], &values[0]);
4.66 +
4.67 + for (int i = 1; i <= length; ++i) {
4.68 + *b = std::make_pair(indices[i], values[i]);
4.69 + ++b;
4.70 + }
4.71 + }
4.72
4.73 void LpGlpk::_setCoeff(int row, int col, Value value)
4.74 {
4.75 @@ -223,8 +252,8 @@
4.76
4.77 int length=lpx_get_mat_row(lp, row, 0, 0);
4.78
4.79 - std::vector<int> indices(length + 2);
4.80 - std::vector<Value> values(length + 2);
4.81 + std::vector<int> indices(length + 1);
4.82 + std::vector<Value> values(length + 1);
4.83
4.84 lpx_get_mat_row(lp, row, &indices[0], &values[0]);
4.85
5.1 --- a/lemon/lp_glpk.h Thu Feb 15 14:22:08 2007 +0000
5.2 +++ b/lemon/lp_glpk.h Thu Feb 15 19:15:14 2007 +0000
5.3 @@ -57,8 +57,10 @@
5.4 virtual void _eraseRow(int i);
5.5 virtual void _getColName(int col, std::string & name);
5.6 virtual void _setColName(int col, const std::string & name);
5.7 - virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
5.8 - virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
5.9 + virtual void _setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e);
5.10 + virtual void _getRowCoeffs(int i, RowIterator b);
5.11 + virtual void _setColCoeffs(int i, ConstColIterator b, ConstColIterator e);
5.12 + virtual void _getColCoeffs(int i, ColIterator b);
5.13 virtual void _setCoeff(int row, int col, Value value);
5.14 virtual Value _getCoeff(int row, int col);
5.15
6.1 --- a/lemon/lp_skeleton.cc Thu Feb 15 14:22:08 2007 +0000
6.2 +++ b/lemon/lp_skeleton.cc Thu Feb 15 19:15:14 2007 +0000
6.3 @@ -58,10 +58,16 @@
6.4 }
6.5
6.6
6.7 - void LpSkeleton::_setRowCoeffs(int, LpRowIterator, LpRowIterator) {
6.8 + void LpSkeleton::_setRowCoeffs(int, ConstRowIterator, ConstRowIterator) {
6.9 + }
6.10 +
6.11 + void LpSkeleton::_getRowCoeffs(int, RowIterator) {
6.12 }
6.13
6.14 - void LpSkeleton::_setColCoeffs(int, LpColIterator, LpColIterator) {
6.15 + void LpSkeleton::_setColCoeffs(int, ConstColIterator, ConstColIterator) {
6.16 + }
6.17 +
6.18 + void LpSkeleton::_getColCoeffs(int, ColIterator) {
6.19 }
6.20
6.21 void LpSkeleton::_setCoeff(int, int, Value )
7.1 --- a/lemon/lp_skeleton.h Thu Feb 15 14:22:08 2007 +0000
7.2 +++ b/lemon/lp_skeleton.h Thu Feb 15 19:15:14 2007 +0000
7.3 @@ -49,9 +49,13 @@
7.4 virtual void _setColName(int col, const std::string & name);
7.5
7.6 /// \e
7.7 - virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
7.8 + virtual void _setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e);
7.9 /// \e
7.10 - virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
7.11 + virtual void _getRowCoeffs(int i, RowIterator b);
7.12 + /// \e
7.13 + virtual void _setColCoeffs(int i, ConstColIterator b, ConstColIterator e);
7.14 + /// \e
7.15 + virtual void _getColCoeffs(int i, ColIterator b);
7.16
7.17 /// Set one element of the coefficient matrix
7.18 virtual void _setCoeff(int row, int col, Value value);
8.1 --- a/lemon/lp_soplex.cc Thu Feb 15 14:22:08 2007 +0000
8.2 +++ b/lemon/lp_soplex.cc Thu Feb 15 19:15:14 2007 +0000
8.3 @@ -99,25 +99,41 @@
8.4 }
8.5
8.6
8.7 - void LpSoplex::_setRowCoeffs(int i, LpRowIterator b, LpRowIterator e) {
8.8 + void LpSoplex::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) {
8.9 for (int j = 0; j < soplex->nCols(); ++j) {
8.10 soplex->changeElement(i, j, 0.0);
8.11 }
8.12 - for(LpRowIterator it = b; it != e; ++it) {
8.13 + for(ConstRowIterator it = b; it != e; ++it) {
8.14 soplex->changeElement(i, it->first, it->second);
8.15 }
8.16 solved = false;
8.17 }
8.18 +
8.19 + void LpSoplex::_getRowCoeffs(int i, RowIterator b) {
8.20 + const soplex::SVector& vec = soplex->rowVector(i);
8.21 + for (int k = 0; k < vec.size(); ++k) {
8.22 + *b = std::make_pair(vec.index(k), vec.value(k));
8.23 + ++b;
8.24 + }
8.25 + }
8.26
8.27 - void LpSoplex::_setColCoeffs(int j, LpColIterator b, LpColIterator e) {
8.28 + void LpSoplex::_setColCoeffs(int j, ConstColIterator b, ConstColIterator e) {
8.29 for (int i = 0; i < soplex->nRows(); ++i) {
8.30 soplex->changeElement(i, j, 0.0);
8.31 }
8.32 - for(LpColIterator it = b; it != e; ++it) {
8.33 + for(ConstColIterator it = b; it != e; ++it) {
8.34 soplex->changeElement(it->first, j, it->second);
8.35 }
8.36 solved = false;
8.37 }
8.38 +
8.39 + void LpSoplex::_getColCoeffs(int i, ColIterator b) {
8.40 + const soplex::SVector& vec = soplex->colVector(i);
8.41 + for (int k = 0; k < vec.size(); ++k) {
8.42 + *b = std::make_pair(vec.index(k), vec.value(k));
8.43 + ++b;
8.44 + }
8.45 + }
8.46
8.47 void LpSoplex::_setCoeff(int i, int j, Value value) {
8.48 soplex->changeElement(i, j, value);
9.1 --- a/lemon/lp_soplex.h Thu Feb 15 14:22:08 2007 +0000
9.2 +++ b/lemon/lp_soplex.h Thu Feb 15 19:15:14 2007 +0000
9.3 @@ -72,8 +72,10 @@
9.4 virtual void _eraseRow(int i);
9.5 virtual void _getColName(int col, std::string & name);
9.6 virtual void _setColName(int col, const std::string & name);
9.7 - virtual void _setRowCoeffs(int i, LpRowIterator b, LpRowIterator e);
9.8 - virtual void _setColCoeffs(int i, LpColIterator b, LpColIterator e);
9.9 + virtual void _setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e);
9.10 + virtual void _getRowCoeffs(int i, RowIterator b);
9.11 + virtual void _setColCoeffs(int i, ConstColIterator b, ConstColIterator e);
9.12 + virtual void _getColCoeffs(int i, ColIterator b);
9.13 virtual void _setCoeff(int row, int col, Value value);
9.14 virtual Value _getCoeff(int row, int col);
9.15 virtual void _setColLowerBound(int i, Value value);
10.1 --- a/lemon/lp_utils.h Thu Feb 15 14:22:08 2007 +0000
10.2 +++ b/lemon/lp_utils.h Thu Feb 15 19:15:14 2007 +0000
10.3 @@ -68,11 +68,16 @@
10.4
10.5 private:
10.6
10.7 + enum SubSection {
10.8 + CONSTRAINTS, BOUNDS, OBJECTIVE
10.9 + };
10.10 +
10.11 enum Relation {
10.12 LE, EQ, GE
10.13 };
10.14
10.15 - std::istream& readConstraint(std::istream& is, LpSolverBase::Constr& c) {
10.16 + std::istream& readConstraint(std::istream& is) {
10.17 + LpSolverBase::Constr c;
10.18 char x;
10.19 LpSolverBase::Expr e1, e2;
10.20 Relation op1;
10.21 @@ -82,13 +87,27 @@
10.22 readRelation(is, op1);
10.23 is >> std::ws;
10.24 readExpression(is, e2);
10.25 + is >> std::ws;
10.26 if (!is.get(x)) {
10.27 if (op1 == LE) {
10.28 + if (e1.size() == 0) {
10.29 + c = e2 >= e1;
10.30 + } else {
10.31 + c = e1 <= e2;
10.32 + }
10.33 c = e1 <= e2;
10.34 } else if (op1 == GE) {
10.35 - c = e1 >= e2;
10.36 + if (e1.size() == 0) {
10.37 + c = e2 <= e1;
10.38 + } else {
10.39 + c = e1 >= e2;
10.40 + }
10.41 } else {
10.42 - c = e1 == e2;
10.43 + if (e1.size() == 0) {
10.44 + c = e2 == e1;
10.45 + } else {
10.46 + c = e1 == e2;
10.47 + }
10.48 }
10.49 } else {
10.50 is.putback(x);
10.51 @@ -108,7 +127,104 @@
10.52 } else {
10.53 c = e1.constComp() >= e2 >= e3.constComp();
10.54 }
10.55 + is >> std::ws;
10.56 + if (is.get(x)) {
10.57 + throw DataFormatError("Wrong variable bounds format");
10.58 + }
10.59 }
10.60 + lp.addRow(c);
10.61 + return is;
10.62 + }
10.63 +
10.64 + std::istream& readObjective(std::istream& is) {
10.65 + is >> std::ws;
10.66 + std::string sense;
10.67 + is >> sense;
10.68 + if (sense != "min" && sense != "max") {
10.69 + throw DataFormatError("Wrong objective function format");
10.70 + }
10.71 + LpSolverBase::Expr expr;
10.72 + is >> std::ws;
10.73 + readExpression(is, expr);
10.74 + lp.setObj(expr);
10.75 + if (sense == "min") {
10.76 + lp.min();
10.77 + } else {
10.78 + lp.max();
10.79 + }
10.80 + return is;
10.81 + }
10.82 +
10.83 + std::istream& readBounds(std::istream& is) {
10.84 + LpSolverBase::Col c;
10.85 + char x;
10.86 + is >> std::ws;
10.87 + if (!is.get(x)) {
10.88 + throw DataFormatError("Wrong variable bounds format");
10.89 + }
10.90 + if (varFirstChar(x)) {
10.91 + is.putback(x);
10.92 + readCol(is, c);
10.93 + is >> std::ws;
10.94 + Relation op1;
10.95 + readRelation(is, op1);
10.96 + double v;
10.97 + readNum(is, v);
10.98 + if (op1 == EQ) {
10.99 + lp.colLowerBound(c, v);
10.100 + lp.colUpperBound(c, v);
10.101 + } else if (op1 == LE) {
10.102 + lp.colUpperBound(c, v);
10.103 + } else {
10.104 + lp.colLowerBound(c, v);
10.105 + }
10.106 + is >> std::ws;
10.107 + if (is.get(x)) {
10.108 + throw DataFormatError("Wrong variable bounds format");
10.109 + }
10.110 + } else {
10.111 + is.putback(x);
10.112 + double v;
10.113 + readNum(is, v);
10.114 + is >> std::ws;
10.115 + Relation op1;
10.116 + readRelation(is, op1);
10.117 + is >> std::ws;
10.118 + readCol(is, c);
10.119 + is >> std::ws;
10.120 + if (is.get(x)) {
10.121 + is.putback(x);
10.122 + is >> std::ws;
10.123 + Relation op2;
10.124 + readRelation(is, op2);
10.125 + double w;
10.126 + is >> std::ws;
10.127 + readNum(is, w);
10.128 + if (op2 != op1 || op1 == EQ) {
10.129 + throw DataFormatError("Wrong range format");
10.130 + }
10.131 + if (op1 == LE) {
10.132 + lp.colLowerBound(c, v);
10.133 + lp.colUpperBound(c, w);
10.134 + } else {
10.135 + lp.colLowerBound(c, w);
10.136 + lp.colUpperBound(c, v);
10.137 + }
10.138 + if (is.get(x)) {
10.139 + throw DataFormatError("Wrong variable bounds format");
10.140 + }
10.141 + } else {
10.142 + if (op1 == EQ) {
10.143 + lp.colLowerBound(c, v);
10.144 + lp.colUpperBound(c, v);
10.145 + } else if (op1 == LE) {
10.146 + lp.colLowerBound(c, v);
10.147 + } else {
10.148 + lp.colUpperBound(c, v);
10.149 + }
10.150 + }
10.151 + }
10.152 + return is;
10.153 }
10.154
10.155 std::istream& readExpression(std::istream& is, LpSolverBase::Expr& e) {
10.156 @@ -277,40 +393,9 @@
10.157
10.158 static bool varChar(char c) {
10.159 return (c >= '0' && c <= '9') ||
10.160 - (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
10.161 - }
10.162 -
10.163 -
10.164 - void addConstraint(const LpSolverBase::Constr& constr) {
10.165 - if (constr.expr().size() != 1) {
10.166 - lp.addRow(constr);
10.167 - } else {
10.168 - Lp::Expr e = constr.expr();
10.169 - LpSolverBase::Col col = e.begin()->first;
10.170 - double coeff = e.begin()->second;
10.171 - double lb = LpSolverBase::NaN;
10.172 - double ub = LpSolverBase::NaN;
10.173 - if (coeff > 0) {
10.174 - if (constr.upperBounded()) {
10.175 - lb = (constr.lowerBound() - e.constComp()) / coeff;
10.176 - }
10.177 - if (constr.lowerBounded()) {
10.178 - ub = (constr.upperBound() - e.constComp()) / coeff;
10.179 - }
10.180 - } else if (coeff < 0) {
10.181 - if (constr.upperBounded()) {
10.182 - lb = (constr.upperBound() - e.constComp()) / coeff;
10.183 - }
10.184 - if (constr.lowerBounded()) {
10.185 - ub = (constr.lowerBound() - e.constComp()) / coeff;
10.186 - }
10.187 - } else {
10.188 - lb = -LpSolverBase::INF;
10.189 - ub = LpSolverBase::INF;
10.190 - }
10.191 - lp.colLowerBound(col, lb);
10.192 - lp.colUpperBound(col, ub);
10.193 - }
10.194 + (c >= 'a' && c <= 'z') ||
10.195 + (c >= 'A' && c <= 'Z') ||
10.196 + c == '[' || c == ']';
10.197 }
10.198
10.199 protected:
10.200 @@ -320,26 +405,30 @@
10.201 /// It reads the content of the section.
10.202 virtual void read(std::istream& is) {
10.203 std::string line;
10.204 + SubSection sub = CONSTRAINTS;
10.205 while (getline(is, line)) {
10.206 std::istringstream ls(line);
10.207 - std::string sense;
10.208 - ls >> sense;
10.209 - if (sense == "min" || sense == "max") {
10.210 - LpSolverBase::Expr expr;
10.211 - ls >> std::ws;
10.212 - readExpression(ls, expr);
10.213 - lp.setObj(expr);
10.214 - if (sense == "min") {
10.215 - lp.min();
10.216 - } else {
10.217 - lp.max();
10.218 - }
10.219 + std::string type;
10.220 + ls >> type;
10.221 + if (type == "constraints") {
10.222 + sub = CONSTRAINTS;
10.223 + } else if (type == "bounds") {
10.224 + sub = BOUNDS;
10.225 + } else if (type == "objective") {
10.226 + sub = OBJECTIVE;
10.227 } else {
10.228 ls.str(line);
10.229 - LpSolverBase::Constr constr;
10.230 - ls >> std::ws;
10.231 - readConstraint(ls, constr);
10.232 - addConstraint(constr);
10.233 + switch (sub) {
10.234 + case CONSTRAINTS:
10.235 + readConstraint(ls);
10.236 + break;
10.237 + case BOUNDS:
10.238 + readBounds(ls);
10.239 + break;
10.240 + case OBJECTIVE:
10.241 + readObjective(ls);
10.242 + break;
10.243 + }
10.244 }
10.245 }
10.246 }
10.247 @@ -360,334 +449,177 @@
10.248 };
10.249
10.250
10.251 -// class LpWriter : public LemonWriter::SectionWriter {
10.252 -// typedef LemonWriter::SectionWriter Parent;
10.253 -// public:
10.254 + class LpWriter : public LemonWriter::SectionWriter {
10.255 + typedef LemonWriter::SectionWriter Parent;
10.256 + public:
10.257
10.258
10.259 -// /// \brief Constructor.
10.260 -// ///
10.261 -// /// Constructor for LpWriter. It creates the LpWriter and attach
10.262 -// /// it into the given LemonWriter. The lp writer will add
10.263 -// /// variables, constraints and objective function to the
10.264 -// /// given lp solver.
10.265 -// LpWriter(LemonWriter& _writer, LpSolverBase& _lp,
10.266 -// const std::string& _name = std::string())
10.267 -// : Parent(_writer), lp(_lp), name(_name) {}
10.268 + /// \brief Constructor.
10.269 + ///
10.270 + /// Constructor for LpWriter. It creates the LpWriter and attach
10.271 + /// it into the given LemonWriter. The lp writer will add
10.272 + /// variables, constraints and objective function to the
10.273 + /// given lp solver.
10.274 + LpWriter(LemonWriter& _writer, LpSolverBase& _lp,
10.275 + const std::string& _name = std::string())
10.276 + : Parent(_writer), lp(_lp), name(_name) {}
10.277
10.278
10.279 -// /// \brief Destructor.
10.280 -// ///
10.281 -// /// Destructor for NodeSetWriter.
10.282 -// virtual ~LpWriter() {}
10.283 + /// \brief Destructor.
10.284 + ///
10.285 + /// Destructor for NodeSetWriter.
10.286 + virtual ~LpWriter() {}
10.287
10.288 -// private:
10.289 -// LpWriter(const LpWriter&);
10.290 -// void operator=(const LpWriter&);
10.291 + private:
10.292 + LpWriter(const LpWriter&);
10.293 + void operator=(const LpWriter&);
10.294
10.295 -// protected:
10.296 + protected:
10.297
10.298 -// /// \brief Gives back true when the SectionWriter can process
10.299 -// /// the section with the given header line.
10.300 -// ///
10.301 -// /// It gives back the header line of the \c \@lp section.
10.302 -// virtual std::string header() {
10.303 -// std::ostringstream ls(line);
10.304 -// ls << "@lp " << name;
10.305 -// return ls.str();
10.306 -// }
10.307 + /// \brief Gives back true when the SectionWriter can process
10.308 + /// the section with the given header line.
10.309 + ///
10.310 + /// It gives back the header line of the \c \@lp section.
10.311 + virtual std::string header() {
10.312 + std::ostringstream ls;
10.313 + ls << "@lp " << name;
10.314 + return ls.str();
10.315 + }
10.316
10.317 -// private:
10.318 + private:
10.319
10.320 -// std::ostream& writeConstraint(std::ostream& is, LpSolverBase::Constr& c) {
10.321 -// char x;
10.322 + void createCols() {
10.323 + int num = 1;
10.324
10.325 + std::map<std::string, LpSolverBase::Col> inverse;
10.326 +
10.327 + for (LpSolverBase::ColIt it(lp); it != INVALID; ++it) {
10.328 + std::string name = lp.colName(it);
10.329 + if (!name.empty() && inverse.find(name) == inverse.end()) {
10.330 + cols.insert(std::make_pair(it, name));
10.331 + inverse.insert(std::make_pair(name, it));
10.332 + } else {
10.333 + std::ostringstream ls;
10.334 + ls << "var" << num;
10.335 + ++num;
10.336 + cols.insert(std::make_pair(it, ls.str()));
10.337 + inverse.insert(std::make_pair(ls.str(), it));
10.338 + }
10.339 + }
10.340 + }
10.341 +
10.342 + void writeExpression(std::ostream& os, const LpSolverBase::Expr& e) {
10.343 + bool first = true;
10.344 + for (LpSolverBase::Expr::const_iterator jt = e.begin();
10.345 + jt != e.end(); ++jt) {
10.346 + if (jt->second < 0.0) {
10.347 + os << "- ";
10.348 + if (jt->second != -1.0) {
10.349 + os << -jt->second << " * ";
10.350 + }
10.351 + } else if (jt->second > 0.0) {
10.352 + if (!first) {
10.353 + os << "+ ";
10.354 + }
10.355 + if (jt->second != 1.0) {
10.356 + os << jt->second << " * ";
10.357 + }
10.358 + }
10.359 + first = false;
10.360 + os << cols[jt->first] << " ";
10.361 + }
10.362 + if (e.constComp() < 0.0) {
10.363 + os << "- " << -e.constComp() << " ";
10.364 + } else if (e.constComp() > 0.0) {
10.365 + if (!first) {
10.366 + os << "+ ";
10.367 + }
10.368 + os << e.constComp() << " ";
10.369 + }
10.370 + }
10.371 +
10.372 + protected:
10.373 +
10.374 + /// \brief Writer function of the section.
10.375 + ///
10.376 + /// It writes the content of the section.
10.377 + virtual void write(std::ostream& os) {
10.378 + createCols();
10.379 +
10.380 + os << "constraints" << std::endl;
10.381
10.382 -// LpSolverBase::Expr e1, e2;
10.383 -// Relation op1;
10.384 -// is >> std::ws;
10.385 -// writexpression(is, e1);
10.386 -// is >> std::ws;
10.387 -// writeRelation(is, op1);
10.388 -// is >> std::ws;
10.389 -// writexpression(is, e2);
10.390 -// if (!is.get(x)) {
10.391 -// if (op1 == LE) {
10.392 -// c = e1 <= e2;
10.393 -// } else if (op1 == GE) {
10.394 -// c = e1 >= e2;
10.395 -// } else {
10.396 -// c = e1 == e2;
10.397 -// }
10.398 -// } else {
10.399 -// is.putback(x);
10.400 -// LpSolverBase::Expr e3;
10.401 -// Relation op2;
10.402 -// writeRelation(is, op2);
10.403 -// is >> std::ws;
10.404 -// writexpression(is, e3);
10.405 -// if (!e1.empty() || !e3.empty()) {
10.406 -// throw DataFormatError("Wrong range format");
10.407 -// }
10.408 -// if (op2 != op1 || op1 == EQ) {
10.409 -// throw DataFormatError("Wrong range format");
10.410 -// }
10.411 -// if (op1 == LE) {
10.412 -// c = e1.constComp() <= e2 <= e3.constComp();
10.413 -// } else {
10.414 -// c = e1.constComp() >= e2 >= e3.constComp();
10.415 -// }
10.416 -// }
10.417 -// }
10.418 + for (LpSolverBase::RowIt it(lp); it != INVALID; ++it) {
10.419 + double lower, upper;
10.420 + lp.getRowBounds(it, lower, upper);
10.421 + if (lower == -LpSolverBase::INF && upper == LpSolverBase::INF)
10.422 + continue;
10.423 + os << " ";
10.424 +
10.425 + if (lower != upper) {
10.426 + if (lower != -LpSolverBase::INF) {
10.427 + os << lower << " <= ";
10.428 + }
10.429 +
10.430 + writeExpression(os, lp.row(it));
10.431 +
10.432 + if (upper != LpSolverBase::INF) {
10.433 + os << "<= " << upper << " ";
10.434 + }
10.435 + } else {
10.436
10.437 -// std::ostream& writexpression(std::ostream& is, LpSolverBase::Expr& e) {
10.438 -// LpSolverBase::Col c;
10.439 -// double d;
10.440 -// char x;
10.441 -// writelement(is, c, d);
10.442 -// if (c != INVALID) {
10.443 -// e += d * c;
10.444 -// } else {
10.445 -// e += d;
10.446 -// }
10.447 -// is >> std::ws;
10.448 -// while (is.get(x) && (x == '+' || x == '-')) {
10.449 -// is >> std::ws;
10.450 -// writelement(is, c, d);
10.451 -// if (c != INVALID) {
10.452 -// e += (x == '+' ? d : -d) * c;
10.453 -// } else {
10.454 -// e += (x == '+' ? d : -d);
10.455 -// }
10.456 -// is >> std::ws;
10.457 -// }
10.458 -// if (!is) {
10.459 -// is.clear();
10.460 -// } else {
10.461 -// is.putback(x);
10.462 -// }
10.463 -// return is;
10.464 -// }
10.465 + writeExpression(os, lp.row(it));
10.466 + os << "== " << upper << " ";
10.467 +
10.468 + }
10.469
10.470 -// std::ostream& writelement(std::ostream& is,
10.471 -// LpSolverBase::Col& c, double& d) {
10.472 -// d = 1.0;
10.473 -// c = INVALID;
10.474 -// char x, y;
10.475 -// if (!is.get(x)) throw DataFormatError("Cannot find lp element");
10.476 -// if (x == '+' || x == '-') {
10.477 -// is >> std::ws;
10.478 -// d *= x == '-' ? -1 : 1;
10.479 -// while (is.get(x) && (x == '+' || x == '-')) {
10.480 -// d *= x == '-' ? -1 : 1;
10.481 -// is >> std::ws;
10.482 -// }
10.483 -// if (!is) throw DataFormatError("Cannot find lp element");
10.484 -// }
10.485 -// if (numFirstChar(x)) {
10.486 -// is.putback(x);
10.487 -// double e;
10.488 -// writeNum(is, e);
10.489 -// d *= e;
10.490 -// } else if (varFirstChar(x)) {
10.491 -// is.putback(x);
10.492 -// LpSolverBase::Col f;
10.493 -// writeCol(is, f);
10.494 -// c = f;
10.495 -// } else {
10.496 -// throw DataFormatError("Invalid expression format");
10.497 -// }
10.498 -// is >> std::ws;
10.499 -// while (is.get(y) && (y == '*' || y == '/')) {
10.500 -// is >> std::ws;
10.501 -// if (!is.get(x)) throw DataFormatError("Cannot find lp element");
10.502 -// if (x == '+' || x == '-') {
10.503 -// is >> std::ws;
10.504 -// d *= x == '-' ? -1 : 1;
10.505 -// while (is.get(x) && (x == '+' || x == '-')) {
10.506 -// d *= x == '-' ? -1 : 1;
10.507 -// is >> std::ws;
10.508 -// }
10.509 -// if (!is) throw DataFormatError("Cannot find lp element");
10.510 -// }
10.511 -// if (numFirstChar(x)) {
10.512 -// is.putback(x);
10.513 -// double e;
10.514 -// writeNum(is, e);
10.515 -// if (y == '*') {
10.516 -// d *= e;
10.517 -// } else {
10.518 -// d /= e;
10.519 -// }
10.520 -// } else if (varFirstChar(x)) {
10.521 -// is.putback(x);
10.522 -// LpSolverBase::Col f;
10.523 -// writeCol(is, f);
10.524 -// if (y == '*') {
10.525 -// if (c == INVALID) {
10.526 -// c = f;
10.527 -// } else {
10.528 -// throw DataFormatError("Quadratic element in expression");
10.529 -// }
10.530 -// } else {
10.531 -// throw DataFormatError("Division by variable");
10.532 -// }
10.533 -// } else {
10.534 -// throw DataFormatError("Invalid expression format");
10.535 -// }
10.536 -// is >> std::ws;
10.537 -// }
10.538 -// if (!is) {
10.539 -// is.clear();
10.540 -// } else {
10.541 -// is.putback(y);
10.542 -// }
10.543 -// return is;
10.544 -// }
10.545 + os << std::endl;
10.546 + }
10.547
10.548 -// std::ostream& writeCol(std::ostream& is, LpSolverBase::Col& c) {
10.549 -// char x;
10.550 -// std::string var;
10.551 -// while (is.get(x) && varChar(x)) {
10.552 -// var += x;
10.553 -// }
10.554 -// if (!is) {
10.555 -// is.clear();
10.556 -// } else {
10.557 -// is.putback(x);
10.558 -// }
10.559 -// ColMap::const_iterator it = cols.find(var);
10.560 -// if (cols.find(var) != cols.end()) {
10.561 -// c = it->second;
10.562 -// } else {
10.563 -// c = lp.addCol();
10.564 -// cols.insert(std::make_pair(var, c));
10.565 -// lp.colName(c, var);
10.566 -// }
10.567 -// return is;
10.568 -// }
10.569 + os << "bounds" << std::endl;
10.570 +
10.571 + for (LpSolverBase::ColIt it(lp); it != INVALID; ++it) {
10.572 + double lower = lp.colLowerBound(it);
10.573 + double upper = lp.colUpperBound(it);
10.574 + if (lower == -LpSolverBase::INF && upper == LpSolverBase::INF)
10.575 + continue;
10.576 + os << " ";
10.577
10.578 -// std::ostream& writeNum(std::ostream& is, double& d) {
10.579 -// is >> d;
10.580 -// if (!is) throw DataFormatError("Wrong number format");
10.581 -// return is;
10.582 -// }
10.583 + if (lower != upper) {
10.584 + if (lower != -LpSolverBase::INF) {
10.585 + os << lower << " <= ";
10.586 + }
10.587 +
10.588 + os << cols[it] << " ";
10.589 +
10.590 + if (upper != LpSolverBase::INF) {
10.591 + os << "<= " << upper << " ";
10.592 + }
10.593 + } else {
10.594 + os << cols[it] << " == " << upper << " ";
10.595 + }
10.596 + os << std::endl;
10.597 + }
10.598
10.599 -// std::ostream& writeRelation(std::ostream& is, Relation& op) {
10.600 -// char x, y;
10.601 -// if (!is.get(x) || !(x == '<' || x == '=' || x == '>')) {
10.602 -// throw DataFormatError("Wrong relation operator");
10.603 -// }
10.604 -// if (!is.get(y) || y != '=') {
10.605 -// throw DataFormatError("Wrong relation operator");
10.606 -// }
10.607 -// switch (x) {
10.608 -// case '<': op = LE;
10.609 -// break;
10.610 -// case '=': op = EQ;
10.611 -// break;
10.612 -// case '>': op = GE;
10.613 -// break;
10.614 -// }
10.615 -// return is;
10.616 -// }
10.617 + os << "objective" << std::endl;
10.618 + os << " ";
10.619 + if (lp.is_min()) {
10.620 + os << "min ";
10.621 + } else {
10.622 + os << "max ";
10.623 + }
10.624 + writeExpression(os, lp.obj());
10.625 + os << std::endl;
10.626 + }
10.627 +
10.628
10.629 -// static bool relationFirstChar(char c) {
10.630 -// return c == '<' || c == '=' || c == '>';
10.631 -// }
10.632 + private:
10.633
10.634 -// static bool varFirstChar(char c) {
10.635 -// return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
10.636 -// }
10.637 -
10.638 -// static bool numFirstChar(char c) {
10.639 -// return (c >= '0' && c <= '9') || c == '.';
10.640 -// }
10.641 -
10.642 -// static bool varChar(char c) {
10.643 -// return (c >= '0' && c <= '9') ||
10.644 -// (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
10.645 -// }
10.646 -
10.647 -
10.648 -// void addConstraint(const LpSolverBase::Constr& constr) {
10.649 -// if (constr.expr().size() != 1) {
10.650 -// lp.addRow(constr);
10.651 -// } else {
10.652 -// Lp::Expr e = constr.expr();
10.653 -// LpSolverBase::Col col = e.begin()->first;
10.654 -// double coeff = e.begin()->second;
10.655 -// double lb = LpSolverBase::NaN;
10.656 -// double ub = LpSolverBase::NaN;
10.657 -// if (coeff > 0) {
10.658 -// if (constr.upperBounded()) {
10.659 -// lb = (constr.lowerBound() - e.constComp()) / coeff;
10.660 -// }
10.661 -// if (constr.lowerBounded()) {
10.662 -// ub = (constr.upperBound() - e.constComp()) / coeff;
10.663 -// }
10.664 -// } else if (coeff < 0) {
10.665 -// if (constr.upperBounded()) {
10.666 -// lb = (constr.upperBound() - e.constComp()) / coeff;
10.667 -// }
10.668 -// if (constr.lowerBounded()) {
10.669 -// ub = (constr.lowerBound() - e.constComp()) / coeff;
10.670 -// }
10.671 -// } else {
10.672 -// lb = -LpSolverBase::INF;
10.673 -// ub = LpSolverBase::INF;
10.674 -// }
10.675 -// lp.colLowerBound(col, lb);
10.676 -// lp.colUpperBound(col, ub);
10.677 -// }
10.678 -// }
10.679 -
10.680 -// protected:
10.681 -
10.682 -// /// \brief Writer function of the section.
10.683 -// ///
10.684 -// /// It writes the content of the section.
10.685 -// virtual void write(std::ostream& is) {
10.686 -// std::string line;
10.687 -// std::map<std::string, LpSolverBase::Col> vars;
10.688 -// while (getline(is, line)) {
10.689 -// std::istringstream ls(line);
10.690 -// std::string sense;
10.691 -// ls >> sense;
10.692 -// if (sense == "min" || sense == "max") {
10.693 -// LpSolverBase::Expr expr;
10.694 -// ls >> std::ws;
10.695 -// writeExpression(ls, expr);
10.696 -// lp.setObj(expr);
10.697 -// if (sense == "min") {
10.698 -// lp.min();
10.699 -// } else {
10.700 -// lp.max();
10.701 -// }
10.702 -// } else {
10.703 -// ls.str(line);
10.704 -// LpSolverBase::Constr constr;
10.705 -// ls >> std::ws;
10.706 -// writeConstraint(ls, constr);
10.707 -// addConstraint(constr);
10.708 -// }
10.709 -// }
10.710 -// }
10.711 + typedef std::map<LpSolverBase::Col, std::string> ColMap;
10.712
10.713 -// virtual void missing() {
10.714 -// ErrorMessage msg;
10.715 -// msg << "Lp section not found in file: @lp " << name;
10.716 -// throw IoParameterError(msg.message());
10.717 -// }
10.718 -
10.719 -// private:
10.720 -
10.721 -// typedef std::map<std::string, LpSolverBase::Col> ColMap;
10.722 -
10.723 -// LpSolverBase& lp;
10.724 -// std::string name;
10.725 -// ColMap cols;
10.726 -// };
10.727 + LpSolverBase& lp;
10.728 + std::string name;
10.729 + ColMap cols;
10.730 + };
10.731
10.732 }
10.733