# HG changeset patch # User alpar # Date 1111738707 0 # Node ID 3bb4ed285c39b8650c69fe1d7758cb09105bbc85 # Parent 6455f64a85dc39b8cf321ed8acf2cef7b665bc92 - src/lemon/utility.h: dummy<> template added - LpSolverBase::INF is now really defined - AddColSet() to add several column at once - using enable_if - with some doxygen hack - More doc improvements - Better Makefile diff -r 6455f64a85dc -r 3bb4ed285c39 src/lemon/utility.h --- a/src/lemon/utility.h Thu Mar 24 12:19:05 2005 +0000 +++ b/src/lemon/utility.h Fri Mar 25 08:18:27 2005 +0000 @@ -56,7 +56,9 @@ Wrap(const T &t) : value(t) {} }; + /**************** dummy class to avoid ambiguity ****************/ + template struct dummy { dummy(int) {} }; /**************** enable_if from BOOST ****************/ diff -r 6455f64a85dc -r 3bb4ed285c39 src/work/athos/lp/Makefile --- a/src/work/athos/lp/Makefile Thu Mar 24 12:19:05 2005 +0000 +++ b/src/work/athos/lp/Makefile Fri Mar 25 08:18:27 2005 +0000 @@ -2,6 +2,9 @@ all: lp_test +clean: + rm lp_test *.o + lp_base.o: lp_base.cc lp_base.h lin_expr.h lp_solver_skeleton.o: lp_solver_skeleton.cc lp_solver_skeleton.h lp_base.h \ lin_expr.h diff -r 6455f64a85dc -r 3bb4ed285c39 src/work/athos/lp/lp_base.cc --- a/src/work/athos/lp/lp_base.cc Thu Mar 24 12:19:05 2005 +0000 +++ b/src/work/athos/lp/lp_base.cc Fri Mar 25 08:18:27 2005 +0000 @@ -19,7 +19,9 @@ #include "lp_base.h" namespace lemon { - + + const LpSolverBase::Value + LpSolverBase::INF = std::numeric_limits::infinity(); } //namespace lemon 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; } diff -r 6455f64a85dc -r 3bb4ed285c39 src/work/athos/lp/lp_test.cc --- a/src/work/athos/lp/lp_test.cc Thu Mar 24 12:19:05 2005 +0000 +++ b/src/work/athos/lp/lp_test.cc Fri Mar 25 08:18:27 2005 +0000 @@ -4,5 +4,30 @@ int main() { - LpSolverSkeleton lp; + typedef LpSolverSkeleton LP; + LP lp; + + std::vector x; + for(int i=0;i<10;i++) x.push_back(lp.addCol()); + + std::vector y(10); + lp.addColSet(y); + + std::map z; + + z.insert(std::make_pair(12,INVALID)); + z.insert(std::make_pair(2,INVALID)); + z.insert(std::make_pair(7,INVALID)); + z.insert(std::make_pair(5,INVALID)); + + lp.addColSet(z); + + + LP::Expr e; + e[x[3]]=2; + e[x[3]]=4; + e[x[3]]=1; + e.constComp()=12; + lp.addRow(LP::INF,e,23); + }