diff -r 6455f64a85dc -r 3bb4ed285c39 src/work/athos/lp/lp_base.h --- a/src/work/athos/lp/lp_base.h Thu Mar 24 12:19:05 2005 +0000 +++ b/src/work/athos/lp/lp_base.h Fri Mar 25 08:18:27 2005 +0000 @@ -18,8 +18,11 @@ #define LEMON_LP_BASE_H #include +#include +#include #include +#include #include"lin_expr.h" ///\file @@ -65,6 +68,7 @@ index[first_free]=n; first_free=next; } + return cross[n]; } else throw LogicError(); //floatingId-s must form a continuous range; } @@ -96,15 +100,56 @@ public: - /// \e + ///The floating point type used by the solver typedef double Value; - /// \e + ///The infinity constant static const Value INF; - ///\e - class Col { protected: int id; friend class LpSolverBase; }; - ///\e - class Row { protected: int id; friend class LpSolverBase; }; + ///Refer to a column of the LP. + + ///This type is used to refer to a column of the LP. + /// + ///Its value remains valid and correct even after the addition or erase of + ///new column (unless the referred column itself was also deleted, + ///of course). + /// + ///\todo Document what can one do with a Col (INVALID, comparing, + ///it is similar to Node/Edge) + class Col { + protected: + int id; + friend class LpSolverBase; + public: + typedef True LpSolverCol; + Col() {} + Col(const Invalid&) : id(-1) {} + bool operator<(Col c) const {return id Expr; @@ -175,6 +220,44 @@ ///Add a new empty column (i.e a new variable) to the LP Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;} + ///\brief Fill the elements of a container with newly created columns + ///(i.e a new variables) + /// + ///This magic function takes container as its argument + ///and fills its elements + ///with new columns (i.e. variables) + ///\param t can be either any standard STL iterable container with + ///\ref Col \c values_type or \c mapped_type + ///like std::vector, + /// std::list or + /// std::map or + ///it can be an iterable lemon map like + /// ListGraph::NodeMap. + ///\return The number of the created column. + ///\bug Iterable nodemap hasn't been implemented yet. +#ifdef DOXYGEN + template + int addColSet(T &t) { return 0;} +#else + template + typename enable_if::type + addColSet(T &t,dummy<0> = 0) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;} + return s; + } + template + typename enable_if::type + addColSet(T &t,dummy<1> = 1) { + int s=0; + for(typename T::iterator i=t.begin();i!=t.end();++i) { + i->second=addCol(); + s++; + } + return s; + } +#endif ///Add a new empty row (i.e a new constaint) to the LP Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;} @@ -191,14 +274,15 @@ std::vector values; indices.push_back(0); values.push_back(0); - for(Expr::iterator i=e.begin(); i!=e.end(); ++i) { - indices.push_back(cols.floatingId((*i).first.id)); - values.push_back((*i).second); - } + for(Expr::iterator i=e.begin(); i!=e.end(); ++i) + if((*i).second!=0) { ///\bug EPSILON would be necessary here!!! + indices.push_back(cols.floatingId((*i).first.id)); + values.push_back((*i).second); + } _setRowCoeffs(rows.floatingId(r.id),indices.size()-1, &indices[0],&values[0]); - _setRowLowerBound(rows.floatingId(r.id),l); - _setRowUpperBound(rows.floatingId(r.id),l); + _setRowLowerBound(rows.floatingId(r.id),l-e.constComp()); + _setRowUpperBound(rows.floatingId(r.id),u-e.constComp()); return r; }