Lp row and col getter function
authordeba
Thu, 15 Feb 2007 19:15:14 +0000
changeset 23643a5e67bd42d2
parent 2363 2aabce558574
child 2365 751a14b992f2
Lp row and col getter function
lp section reader and writer for lemon IO
lemon/lp_base.h
lemon/lp_cplex.cc
lemon/lp_cplex.h
lemon/lp_glpk.cc
lemon/lp_glpk.h
lemon/lp_skeleton.cc
lemon/lp_skeleton.h
lemon/lp_soplex.cc
lemon/lp_soplex.h
lemon/lp_utils.h
     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