lemon/lp_base.h
author alpar
Sat, 04 Jun 2005 12:50:15 +0000
changeset 1445 4635352e5524
parent 1439 2c43106bef85
child 1458 7a483c1d38b5
permissions -rw-r--r--
DualExpr added.
     1 /* -*- C++ -*-
     2  * lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Research Group on Combinatorial Optimization, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_LP_BASE_H
    18 #define LEMON_LP_BASE_H
    19 
    20 #include<vector>
    21 #include<map>
    22 #include<limits>
    23 #include<cmath>
    24 
    25 #include<lemon/utility.h>
    26 #include<lemon/error.h>
    27 #include<lemon/invalid.h>
    28 
    29 //#include"lin_expr.h"
    30 
    31 ///\file
    32 ///\brief The interface of the LP solver interface.
    33 ///\ingroup gen_opt_group
    34 namespace lemon {
    35   
    36   ///Internal data structure to convert floating id's to fix one's
    37     
    38   ///\todo This might be implemented to be also usable in other places.
    39   class _FixId 
    40   {
    41     std::vector<int> index;
    42     std::vector<int> cross;
    43     int first_free;
    44   public:
    45     _FixId() : first_free(-1) {};
    46     ///Convert a floating id to a fix one
    47 
    48     ///\param n is a floating id
    49     ///\return the corresponding fix id
    50     int fixId(int n) {return cross[n];}
    51     ///Convert a fix id to a floating one
    52 
    53     ///\param n is a fix id
    54     ///\return the corresponding floating id
    55     int floatingId(int n) { return index[n];}
    56     ///Add a new floating id.
    57 
    58     ///\param n is a floating id
    59     ///\return the fix id of the new value
    60     ///\todo Multiple additions should also be handled.
    61     int insert(int n)
    62     {
    63       if(n>=int(cross.size())) {
    64 	cross.resize(n+1);
    65 	if(first_free==-1) {
    66 	  cross[n]=index.size();
    67 	  index.push_back(n);
    68 	}
    69 	else {
    70 	  cross[n]=first_free;
    71 	  int next=index[first_free];
    72 	  index[first_free]=n;
    73 	  first_free=next;
    74 	}
    75 	return cross[n];
    76       }
    77       ///\todo Create an own exception type.
    78       else throw LogicError(); //floatingId-s must form a continuous range;
    79     }
    80     ///Remove a fix id.
    81 
    82     ///\param n is a fix id
    83     ///
    84     void erase(int n) 
    85     {
    86       int fl=index[n];
    87       index[n]=first_free;
    88       first_free=n;
    89       for(int i=fl+1;i<int(cross.size());++i) {
    90 	cross[i-1]=cross[i];
    91 	index[cross[i]]--;
    92       }
    93       cross.pop_back();
    94     }
    95     ///An upper bound on the largest fix id.
    96 
    97     ///\todo Do we need this?
    98     ///
    99     std::size_t maxFixId() { return cross.size()-1; }
   100   
   101   };
   102     
   103   ///Common base class for LP solvers
   104   
   105   ///\todo Much more docs
   106   ///\ingroup gen_opt_group
   107   class LpSolverBase {
   108 
   109   public:
   110 
   111     ///\e
   112     enum SolveExitStatus {
   113       ///\e
   114       SOLVED = 0,
   115       ///\e
   116       UNSOLVED = 1
   117     };
   118       
   119     ///\e
   120     enum SolutionStatus {
   121       ///Feasible solution has'n been found (but may exist).
   122 
   123       ///\todo NOTFOUND might be a better name.
   124       ///
   125       UNDEFINED = 0,
   126       ///The problem has no feasible solution
   127       INFEASIBLE = 1,
   128       ///Feasible solution found
   129       FEASIBLE = 2,
   130       ///Optimal solution exists and found
   131       OPTIMAL = 3,
   132       ///The cost function is unbounded
   133 
   134       ///\todo Give a feasible solution and an infinite ray (and the
   135       ///corresponding bases)
   136       INFINITE = 4
   137     };
   138       
   139     ///The floating point type used by the solver
   140     typedef double Value;
   141     ///The infinity constant
   142     static const Value INF;
   143     ///The not a number constant
   144     static const Value NaN;
   145     
   146     ///Refer to a column of the LP.
   147 
   148     ///This type is used to refer to a column of the LP.
   149     ///
   150     ///Its value remains valid and correct even after the addition or erase of
   151     ///other columns.
   152     ///
   153     ///\todo Document what can one do with a Col (INVALID, comparing,
   154     ///it is similar to Node/Edge)
   155     class Col {
   156     protected:
   157       int id;
   158       friend class LpSolverBase;
   159     public:
   160       typedef Value ExprValue;
   161       typedef True LpSolverCol;
   162       Col() {}
   163       Col(const Invalid&) : id(-1) {}
   164       bool operator<(Col c) const  {return id<c.id;}
   165       bool operator==(Col c) const  {return id==c.id;}
   166       bool operator!=(Col c) const  {return id==c.id;}
   167     };
   168 
   169     ///Refer to a row of the LP.
   170 
   171     ///This type is used to refer to a row of the LP.
   172     ///
   173     ///Its value remains valid and correct even after the addition or erase of
   174     ///other rows.
   175     ///
   176     ///\todo Document what can one do with a Row (INVALID, comparing,
   177     ///it is similar to Node/Edge)
   178     class Row {
   179     protected:
   180       int id;
   181       friend class LpSolverBase;
   182     public:
   183       typedef Value ExprValue;
   184       typedef True LpSolverRow;
   185       Row() {}
   186       Row(const Invalid&) : id(-1) {}
   187 
   188       bool operator<(Row c) const  {return id<c.id;}
   189       bool operator==(Row c) const  {return id==c.id;}
   190       bool operator!=(Row c) const  {return id==c.id;} 
   191    };
   192     
   193     ///Linear expression of variables and a constant component
   194     
   195     ///This data structure strores a linear expression of the variables
   196     ///(\ref Col "Col"s) and also has a constant component.
   197     ///
   198     ///There are several ways to access and modify the contents of this
   199     ///container.
   200     ///- Its it fully compatible with \c std::map<Col,double>, so for expamle
   201     ///if \c e is an Expr and \c v and \c w are of type \ref Col, then you can
   202     ///read and modify the coefficients like
   203     ///these.
   204     ///\code
   205     ///e[v]=5;
   206     ///e[v]+=12;
   207     ///e.erase(v);
   208     ///\endcode
   209     ///or you can also iterate through its elements.
   210     ///\code
   211     ///double s=0;
   212     ///for(LpSolverBase::Expr::iterator i=e.begin();i!=e.end();++i)
   213     ///  s+=i->second;
   214     ///\endcode
   215     ///(This code computes the sum of all coefficients).
   216     ///- Numbers (<tt>double</tt>'s)
   217     ///and variables (\ref Col "Col"s) directly convert to an
   218     ///\ref Expr and the usual linear operations are defined so  
   219     ///\code
   220     ///v+w
   221     ///2*v-3.12*(v-w/2)+2
   222     ///v*2.1+(3*v+(v*12+w+6)*3)/2
   223     ///\endcode
   224     ///are valid \ref Expr "Expr"essions.
   225     ///The usual assignment operations are also defined.
   226     ///\code
   227     ///e=v+w;
   228     ///e+=2*v-3.12*(v-w/2)+2;
   229     ///e*=3.4;
   230     ///e/=5;
   231     ///\endcode
   232     ///- The constant member can be set and read by \ref constComp()
   233     ///\code
   234     ///e.constComp()=12;
   235     ///double c=e.constComp();
   236     ///\endcode
   237     ///
   238     ///\note \ref clear() not only sets all coefficients to 0 but also
   239     ///clears the constant components.
   240     ///
   241     ///\sa Constr
   242     ///
   243     class Expr : public std::map<Col,Value>
   244     {
   245     public:
   246       typedef LpSolverBase::Col Key; 
   247       typedef LpSolverBase::Value Value;
   248       
   249     protected:
   250       typedef std::map<Col,Value> Base;
   251       
   252       Value const_comp;
   253   public:
   254       typedef True IsLinExpression;
   255       ///\e
   256       Expr() : Base(), const_comp(0) { }
   257       ///\e
   258       Expr(const Key &v) : const_comp(0) {
   259 	Base::insert(std::make_pair(v, 1));
   260       }
   261       ///\e
   262       Expr(const Value &v) : const_comp(v) {}
   263       ///\e
   264       void set(const Key &v,const Value &c) {
   265 	Base::insert(std::make_pair(v, c));
   266       }
   267       ///\e
   268       Value &constComp() { return const_comp; }
   269       ///\e
   270       const Value &constComp() const { return const_comp; }
   271       
   272       ///Removes the components with zero coefficient.
   273       void simplify() {
   274 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
   275 	  Base::iterator j=i;
   276 	  ++j;
   277 	  if ((*i).second==0) Base::erase(i);
   278 	  j=i;
   279 	}
   280       }
   281 
   282       ///Sets all coefficients and the constant component to 0.
   283       void clear() {
   284 	Base::clear();
   285 	const_comp=0;
   286       }
   287 
   288       ///\e
   289       Expr &operator+=(const Expr &e) {
   290 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   291 	  (*this)[j->first]+=j->second;
   292 	///\todo it might be speeded up using "hints"
   293 	const_comp+=e.const_comp;
   294 	return *this;
   295       }
   296       ///\e
   297       Expr &operator-=(const Expr &e) {
   298 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   299 	  (*this)[j->first]-=j->second;
   300 	const_comp-=e.const_comp;
   301 	return *this;
   302       }
   303       ///\e
   304       Expr &operator*=(const Value &c) {
   305 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   306 	  j->second*=c;
   307 	const_comp*=c;
   308 	return *this;
   309       }
   310       ///\e
   311       Expr &operator/=(const Value &c) {
   312 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   313 	  j->second/=c;
   314 	const_comp/=c;
   315 	return *this;
   316       }
   317     };
   318     
   319     ///Linear constraint
   320 
   321     ///This data stucture represents a linear constraint in the LP.
   322     ///Basically it is a linear expression with a lower or an upper bound
   323     ///(or both). These parts of the constraint can be obtained by the member
   324     ///functions \ref expr(), \ref lowerBound() and \ref upperBound(),
   325     ///respectively.
   326     ///There are two ways to construct a constraint.
   327     ///- You can set the linear expression and the bounds directly
   328     ///  by the functions above.
   329     ///- The operators <tt>\<=</tt>, <tt>==</tt> and  <tt>\>=</tt>
   330     ///  are defined between expressions, or even between constraints whenever
   331     ///  it makes sense. Therefore if \c e and \c f are linear expressions and
   332     ///  \c s and \c t are numbers, then the followings are valid expressions
   333     ///  and thus they can be used directly e.g. in \ref addRow() whenever
   334     ///  it makes sense.
   335     ///  \code
   336     ///  e<=s
   337     ///  e<=f
   338     ///  s<=e<=t
   339     ///  e>=t
   340     ///  \endcode
   341     ///\warning The validity of a constraint is checked only at run time, so
   342     ///e.g. \ref addRow(<tt>x[1]\<=x[2]<=5</tt>) will compile, but will throw a
   343     ///\ref LogicError exception.
   344     class Constr
   345     {
   346     public:
   347       typedef LpSolverBase::Expr Expr;
   348       typedef Expr::Key Key;
   349       typedef Expr::Value Value;
   350       
   351 //       static const Value INF;
   352 //       static const Value NaN;
   353 
   354     protected:
   355       Expr _expr;
   356       Value _lb,_ub;
   357     public:
   358       ///\e
   359       Constr() : _expr(), _lb(NaN), _ub(NaN) {}
   360       ///\e
   361       Constr(Value lb,const Expr &e,Value ub) :
   362 	_expr(e), _lb(lb), _ub(ub) {}
   363       ///\e
   364       Constr(const Expr &e,Value ub) : 
   365 	_expr(e), _lb(NaN), _ub(ub) {}
   366       ///\e
   367       Constr(Value lb,const Expr &e) :
   368 	_expr(e), _lb(lb), _ub(NaN) {}
   369       ///\e
   370       Constr(const Expr &e) : 
   371 	_expr(e), _lb(NaN), _ub(NaN) {}
   372       ///\e
   373       void clear() 
   374       {
   375 	_expr.clear();
   376 	_lb=_ub=NaN;
   377       }
   378 
   379       ///Reference to the linear expression 
   380       Expr &expr() { return _expr; }
   381       ///Cont reference to the linear expression 
   382       const Expr &expr() const { return _expr; }
   383       ///Reference to the lower bound.
   384 
   385       ///\return
   386       ///- -\ref INF: the constraint is lower unbounded.
   387       ///- -\ref NaN: lower bound has not been set.
   388       ///- finite number: the lower bound
   389       Value &lowerBound() { return _lb; }
   390       ///The const version of \ref lowerBound()
   391       const Value &lowerBound() const { return _lb; }
   392       ///Reference to the upper bound.
   393 
   394       ///\return
   395       ///- -\ref INF: the constraint is upper unbounded.
   396       ///- -\ref NaN: upper bound has not been set.
   397       ///- finite number: the upper bound
   398       Value &upperBound() { return _ub; }
   399       ///The const version of \ref upperBound()
   400       const Value &upperBound() const { return _ub; }
   401       ///Is the constraint lower bounded?
   402       bool lowerBounded() const { 
   403 	using namespace std;
   404 	return finite(_lb);
   405       }
   406       ///Is the constraint upper bounded?
   407       bool upperBounded() const {
   408 	using namespace std;
   409 	return finite(_ub);
   410       }
   411     };
   412     
   413     ///Linear expression of rows
   414     
   415     ///This data structure represents a column of the matrix,
   416     ///thas is it strores a linear expression of the dual variables
   417     ///(\ref Row "Row"s).
   418     ///
   419     ///There are several ways to access and modify the contents of this
   420     ///container.
   421     ///- Its it fully compatible with \c std::map<Row,double>, so for expamle
   422     ///if \c e is an DualExpr and \c v
   423     ///and \c w are of type \ref Row, then you can
   424     ///read and modify the coefficients like
   425     ///these.
   426     ///\code
   427     ///e[v]=5;
   428     ///e[v]+=12;
   429     ///e.erase(v);
   430     ///\endcode
   431     ///or you can also iterate through its elements.
   432     ///\code
   433     ///double s=0;
   434     ///for(LpSolverBase::DualExpr::iterator i=e.begin();i!=e.end();++i)
   435     ///  s+=i->second;
   436     ///\endcode
   437     ///(This code computes the sum of all coefficients).
   438     ///- Numbers (<tt>double</tt>'s)
   439     ///and variables (\ref Row "Row"s) directly convert to an
   440     ///\ref DualExpr and the usual linear operations are defined so  
   441     ///\code
   442     ///v+w
   443     ///2*v-3.12*(v-w/2)
   444     ///v*2.1+(3*v+(v*12+w)*3)/2
   445     ///\endcode
   446     ///are valid \ref DualExpr "DualExpr"essions.
   447     ///The usual assignment operations are also defined.
   448     ///\code
   449     ///e=v+w;
   450     ///e+=2*v-3.12*(v-w/2);
   451     ///e*=3.4;
   452     ///e/=5;
   453     ///\endcode
   454     ///
   455     ///\sa Expr
   456     ///
   457     class DualExpr : public std::map<Row,Value>
   458     {
   459     public:
   460       typedef LpSolverBase::Row Key; 
   461       typedef LpSolverBase::Value Value;
   462       
   463     protected:
   464       typedef std::map<Row,Value> Base;
   465       
   466     public:
   467       typedef True IsLinExpression;
   468       ///\e
   469       DualExpr() : Base() { }
   470       ///\e
   471       DualExpr(const Key &v) {
   472 	Base::insert(std::make_pair(v, 1));
   473       }
   474       ///\e
   475       DualExpr(const Value &v) {}
   476       ///\e
   477       void set(const Key &v,const Value &c) {
   478 	Base::insert(std::make_pair(v, c));
   479       }
   480       
   481       ///Removes the components with zero coefficient.
   482       void simplify() {
   483 	for (Base::iterator i=Base::begin(); i!=Base::end();) {
   484 	  Base::iterator j=i;
   485 	  ++j;
   486 	  if ((*i).second==0) Base::erase(i);
   487 	  j=i;
   488 	}
   489       }
   490 
   491       ///Sets all coefficients to 0.
   492       void clear() {
   493 	Base::clear();
   494       }
   495 
   496       ///\e
   497       DualExpr &operator+=(const DualExpr &e) {
   498 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   499 	  (*this)[j->first]+=j->second;
   500 	///\todo it might be speeded up using "hints"
   501 	return *this;
   502       }
   503       ///\e
   504       DualExpr &operator-=(const DualExpr &e) {
   505 	for (Base::const_iterator j=e.begin(); j!=e.end(); ++j)
   506 	  (*this)[j->first]-=j->second;
   507 	return *this;
   508       }
   509       ///\e
   510       DualExpr &operator*=(const Value &c) {
   511 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   512 	  j->second*=c;
   513 	return *this;
   514       }
   515       ///\e
   516       DualExpr &operator/=(const Value &c) {
   517 	for (Base::iterator j=Base::begin(); j!=Base::end(); ++j)
   518 	  j->second/=c;
   519 	return *this;
   520       }
   521     };
   522     
   523 
   524   protected:
   525     _FixId rows;
   526     _FixId cols;
   527 
   528     //Abstract virtual functions
   529     virtual LpSolverBase &_newLp() = 0;
   530     virtual LpSolverBase &_copyLp(){
   531       ///\todo This should be implemented here, too,  when we have problem retrieving routines. It can be overriden.
   532 
   533       //Starting:
   534       LpSolverBase & newlp(_newLp());
   535       return newlp;
   536       //return *(LpSolverBase*)0;
   537     };
   538 
   539     virtual int _addCol() = 0;
   540     virtual int _addRow() = 0;
   541     virtual void _setRowCoeffs(int i, 
   542 			       int length,
   543                                int  const * indices, 
   544                                Value  const * values ) = 0;
   545     virtual void _setColCoeffs(int i, 
   546 			       int length,
   547                                int  const * indices, 
   548                                Value  const * values ) = 0;
   549     virtual void _setCoeff(int row, int col, Value value) = 0;
   550     virtual void _setColLowerBound(int i, Value value) = 0;
   551     virtual void _setColUpperBound(int i, Value value) = 0;
   552 //     virtual void _setRowLowerBound(int i, Value value) = 0;
   553 //     virtual void _setRowUpperBound(int i, Value value) = 0;
   554     virtual void _setRowBounds(int i, Value lower, Value upper) = 0;
   555     virtual void _setObjCoeff(int i, Value obj_coef) = 0;
   556     virtual void _clearObj()=0;
   557 //     virtual void _setObj(int length,
   558 //                          int  const * indices, 
   559 //                          Value  const * values ) = 0;
   560     virtual SolveExitStatus _solve() = 0;
   561     virtual Value _getPrimal(int i) = 0;
   562     virtual Value _getPrimalValue() = 0;
   563     virtual SolutionStatus _getPrimalStatus() = 0;
   564     virtual void _setMax() = 0;
   565     virtual void _setMin() = 0;
   566     
   567     //Own protected stuff
   568     
   569     //Constant component of the objective function
   570     Value obj_const_comp;
   571     
   572 
   573 
   574     
   575   public:
   576 
   577     ///\e
   578     LpSolverBase() : obj_const_comp(0) {}
   579 
   580     ///\e
   581     virtual ~LpSolverBase() {}
   582 
   583     ///Creates a new LP problem
   584     LpSolverBase &newLp() {return _newLp();}
   585     ///Makes a copy of the LP problem
   586     LpSolverBase &copyLp() {return _copyLp();}
   587     
   588     ///\name Build up and modify of the LP
   589 
   590     ///@{
   591 
   592     ///Add a new empty column (i.e a new variable) to the LP
   593     Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
   594 
   595     ///\brief Adds several new columns
   596     ///(i.e a variables) at once
   597     ///
   598     ///This magic function takes a container as its argument
   599     ///and fills its elements
   600     ///with new columns (i.e. variables)
   601     ///\param t can be
   602     ///- a standard STL compatible iterable container with
   603     ///\ref Col as its \c values_type
   604     ///like
   605     ///\code
   606     ///std::vector<LpSolverBase::Col>
   607     ///std::list<LpSolverBase::Col>
   608     ///\endcode
   609     ///- a standard STL compatible iterable container with
   610     ///\ref Col as its \c mapped_type
   611     ///like
   612     ///\code
   613     ///std::map<AnyType,LpSolverBase::Col>
   614     ///\endcode
   615     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   616     ///\code
   617     ///ListGraph::NodeMap<LpSolverBase::Col>
   618     ///ListGraph::EdgeMap<LpSolverBase::Col>
   619     ///\endcode
   620     ///\return The number of the created column.
   621 #ifdef DOXYGEN
   622     template<class T>
   623     int addColSet(T &t) { return 0;} 
   624 #else
   625     template<class T>
   626     typename enable_if<typename T::value_type::LpSolverCol,int>::type
   627     addColSet(T &t,dummy<0> = 0) {
   628       int s=0;
   629       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;}
   630       return s;
   631     }
   632     template<class T>
   633     typename enable_if<typename T::value_type::second_type::LpSolverCol,
   634 		       int>::type
   635     addColSet(T &t,dummy<1> = 1) { 
   636       int s=0;
   637       for(typename T::iterator i=t.begin();i!=t.end();++i) {
   638 	i->second=addCol();
   639 	s++;
   640       }
   641       return s;
   642     }
   643     template<class T>
   644     typename enable_if<typename T::ValueSet::value_type::LpSolverCol,
   645 		       int>::type
   646     addColSet(T &t,dummy<2> = 2) { 
   647       ///\bug <tt>return addColSet(t.valueSet());</tt> should also work.
   648       int s=0;
   649       for(typename T::ValueSet::iterator i=t.valueSet().begin();
   650 	  i!=t.valueSet().end();
   651 	  ++i)
   652 	{
   653 	  *i=addCol();
   654 	  s++;
   655 	}
   656       return s;
   657     }
   658 #endif
   659 
   660     ///Set a column (i.e a dual constraint) of the LP
   661 
   662     ///\param c is the column to be modified
   663     ///\param e is a dual linear expression (see \ref DualExpr)
   664     ///\bug This is a temportary function. The interface will change to
   665     ///a better one.
   666     void setCol(Col c,const DualExpr &e) {
   667       std::vector<int> indices;
   668       std::vector<Value> values;
   669       indices.push_back(0);
   670       values.push_back(0);
   671       for(DualExpr::const_iterator i=e.begin(); i!=e.end(); ++i)
   672 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
   673 	  indices.push_back(cols.floatingId((*i).first.id));
   674 	  values.push_back((*i).second);
   675 	}
   676       _setColCoeffs(cols.floatingId(c.id),indices.size()-1,
   677 		    &indices[0],&values[0]);
   678     }
   679 
   680     ///Add a new column to the LP
   681 
   682     ///\param e is a dual linear expression (see \ref DualExpr)
   683     ///\param obj is the corresponding component of the objective
   684     ///function. It is 0 by default.
   685     ///\return The created column.
   686     ///\bug This is a temportary function. The interface will change to
   687     ///a better one.
   688     Col addCol(Value l,const DualExpr &e, Value obj=0) {
   689       Col c=addCol();
   690       setCol(c,e);
   691       objCoeff(c,0);
   692       return c;
   693     }
   694 
   695     ///Add a new empty row (i.e a new constraint) to the LP
   696 
   697     ///This function adds a new empty row (i.e a new constraint) to the LP.
   698     ///\return The created row
   699     Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
   700 
   701     ///\brief Adds several new row
   702     ///(i.e a variables) at once
   703     ///
   704     ///This magic function takes a container as its argument
   705     ///and fills its elements
   706     ///with new row (i.e. variables)
   707     ///\param t can be
   708     ///- a standard STL compatible iterable container with
   709     ///\ref Row as its \c values_type
   710     ///like
   711     ///\code
   712     ///std::vector<LpSolverBase::Row>
   713     ///std::list<LpSolverBase::Row>
   714     ///\endcode
   715     ///- a standard STL compatible iterable container with
   716     ///\ref Row as its \c mapped_type
   717     ///like
   718     ///\code
   719     ///std::map<AnyType,LpSolverBase::Row>
   720     ///\endcode
   721     ///- an iterable lemon \ref concept::WriteMap "write map" like 
   722     ///\code
   723     ///ListGraph::NodeMap<LpSolverBase::Row>
   724     ///ListGraph::EdgeMap<LpSolverBase::Row>
   725     ///\endcode
   726     ///\return The number of rows created.
   727 #ifdef DOXYGEN
   728     template<class T>
   729     int addRowSet(T &t) { return 0;} 
   730 #else
   731     template<class T>
   732     typename enable_if<typename T::value_type::LpSolverRow,int>::type
   733     addRowSet(T &t,dummy<0> = 0) {
   734       int s=0;
   735       for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;}
   736       return s;
   737     }
   738     template<class T>
   739     typename enable_if<typename T::value_type::second_type::LpSolverRow,
   740 		       int>::type
   741     addRowSet(T &t,dummy<1> = 1) { 
   742       int s=0;
   743       for(typename T::iterator i=t.begin();i!=t.end();++i) {
   744 	i->second=addRow();
   745 	s++;
   746       }
   747       return s;
   748     }
   749     template<class T>
   750     typename enable_if<typename T::ValueSet::value_type::LpSolverRow,
   751 		       int>::type
   752     addRowSet(T &t,dummy<2> = 2) { 
   753       ///\bug <tt>return addRowSet(t.valueSet());</tt> should also work.
   754       int s=0;
   755       for(typename T::ValueSet::iterator i=t.valueSet().begin();
   756 	  i!=t.valueSet().end();
   757 	  ++i)
   758 	{
   759 	  *i=addRow();
   760 	  s++;
   761 	}
   762       return s;
   763     }
   764 #endif
   765 
   766     ///Set a row (i.e a constraint) of the LP
   767 
   768     ///\param r is the row to be modified
   769     ///\param l is lower bound (-\ref INF means no bound)
   770     ///\param e is a linear expression (see \ref Expr)
   771     ///\param u is the upper bound (\ref INF means no bound)
   772     ///\bug This is a temportary function. The interface will change to
   773     ///a better one.
   774     ///\todo Option to control whether a constraint with a single variable is
   775     ///added or not.
   776     void setRow(Row r, Value l,const Expr &e, Value u) {
   777       std::vector<int> indices;
   778       std::vector<Value> values;
   779       indices.push_back(0);
   780       values.push_back(0);
   781       for(Expr::const_iterator i=e.begin(); i!=e.end(); ++i)
   782 	if((*i).second!=0) { ///\bug EPSILON would be necessary here!!!
   783 	  indices.push_back(cols.floatingId((*i).first.id));
   784 	  values.push_back((*i).second);
   785 	}
   786       _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
   787 		    &indices[0],&values[0]);
   788 //       _setRowLowerBound(rows.floatingId(r.id),l-e.constComp());
   789 //       _setRowUpperBound(rows.floatingId(r.id),u-e.constComp());
   790        _setRowBounds(rows.floatingId(r.id),l-e.constComp(),u-e.constComp());
   791     }
   792 
   793     ///Set a row (i.e a constraint) of the LP
   794 
   795     ///\param r is the row to be modified
   796     ///\param c is a linear expression (see \ref Constr)
   797     void setRow(Row r, const Constr &c) {
   798       setRow(r,
   799 	     c.lowerBounded()?c.lowerBound():-INF,
   800 	     c.expr(),
   801 	     c.upperBounded()?c.upperBound():INF);
   802     }
   803 
   804     ///Add a new row (i.e a new constraint) to the LP
   805 
   806     ///\param l is the lower bound (-\ref INF means no bound)
   807     ///\param e is a linear expression (see \ref Expr)
   808     ///\param u is the upper bound (\ref INF means no bound)
   809     ///\return The created row.
   810     ///\bug This is a temportary function. The interface will change to
   811     ///a better one.
   812     Row addRow(Value l,const Expr &e, Value u) {
   813       Row r=addRow();
   814       setRow(r,l,e,u);
   815       return r;
   816     }
   817 
   818     ///Add a new row (i.e a new constraint) to the LP
   819 
   820     ///\param c is a linear expression (see \ref Constr)
   821     ///\return The created row.
   822     Row addRow(const Constr &c) {
   823       Row r=addRow();
   824       setRow(r,c);
   825       return r;
   826     }
   827 
   828     ///Set an element of the coefficient matrix of the LP
   829 
   830     ///\param r is the row of the element to be modified
   831     ///\param c is the coloumn of the element to be modified
   832     ///\param val is the new value of the coefficient
   833     void setCoeff(Row r, Col c, Value val){
   834       _setCoeff(rows.floatingId(r.id),cols.floatingId(c.id), val);
   835     }
   836 
   837     /// Set the lower bound of a column (i.e a variable)
   838 
   839     /// The upper bound of a variable (column) has to be given by an 
   840     /// extended number of type Value, i.e. a finite number of type 
   841     /// Value or -\ref INF.
   842     void colLowerBound(Col c, Value value) {
   843       _setColLowerBound(cols.floatingId(c.id),value);
   844     }
   845     /// Set the upper bound of a column (i.e a variable)
   846 
   847     /// The upper bound of a variable (column) has to be given by an 
   848     /// extended number of type Value, i.e. a finite number of type 
   849     /// Value or \ref INF.
   850     void colUpperBound(Col c, Value value) {
   851       _setColUpperBound(cols.floatingId(c.id),value);
   852     };
   853     /// Set the lower and the upper bounds of a column (i.e a variable)
   854 
   855     /// The lower and the upper bounds of
   856     /// a variable (column) have to be given by an 
   857     /// extended number of type Value, i.e. a finite number of type 
   858     /// Value, -\ref INF or \ref INF.
   859     void colBounds(Col c, Value lower, Value upper) {
   860       _setColLowerBound(cols.floatingId(c.id),lower);
   861       _setColUpperBound(cols.floatingId(c.id),upper);
   862     }
   863     
   864 //     /// Set the lower bound of a row (i.e a constraint)
   865 
   866 //     /// The lower bound of a linear expression (row) has to be given by an 
   867 //     /// extended number of type Value, i.e. a finite number of type 
   868 //     /// Value or -\ref INF.
   869 //     void rowLowerBound(Row r, Value value) {
   870 //       _setRowLowerBound(rows.floatingId(r.id),value);
   871 //     };
   872 //     /// Set the upper bound of a row (i.e a constraint)
   873 
   874 //     /// The upper bound of a linear expression (row) has to be given by an 
   875 //     /// extended number of type Value, i.e. a finite number of type 
   876 //     /// Value or \ref INF.
   877 //     void rowUpperBound(Row r, Value value) {
   878 //       _setRowUpperBound(rows.floatingId(r.id),value);
   879 //     };
   880 
   881     /// Set the lower and the upper bounds of a row (i.e a constraint)
   882 
   883     /// The lower and the upper bounds of
   884     /// a constraint (row) have to be given by an 
   885     /// extended number of type Value, i.e. a finite number of type 
   886     /// Value, -\ref INF or \ref INF.
   887     void rowBounds(Row c, Value lower, Value upper) {
   888       _setRowBounds(rows.floatingId(c.id),lower, upper);
   889       // _setRowUpperBound(rows.floatingId(c.id),upper);
   890     }
   891     
   892     ///Set an element of the objective function
   893     void objCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
   894     ///Set the objective function
   895     
   896     ///\param e is a linear expression of type \ref Expr.
   897     ///\bug The previous objective function is not cleared!
   898     void setObj(Expr e) {
   899       _clearObj();
   900       for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
   901 	objCoeff((*i).first,(*i).second);
   902       obj_const_comp=e.constComp();
   903     }
   904 
   905     ///Maximize
   906     void max() { _setMax(); }
   907     ///Minimize
   908     void min() { _setMin(); }
   909 
   910     
   911     ///@}
   912 
   913 
   914     ///\name Solve the LP
   915 
   916     ///@{
   917 
   918     ///\e
   919     SolveExitStatus solve() { return _solve(); }
   920     
   921     ///@}
   922     
   923     ///\name Obtain the solution
   924 
   925     ///@{
   926 
   927     ///\e
   928     SolutionStatus primalStatus() {
   929       return _getPrimalStatus();
   930     }
   931 
   932     ///\e
   933     Value primal(Col c) { return _getPrimal(cols.floatingId(c.id)); }
   934 
   935     ///\e
   936 
   937     ///\return
   938     ///- \ref INF or -\ref INF means either infeasibility or unboundedness
   939     /// of the primal problem, depending on whether we minimize or maximize.
   940     ///- \ref NaN if no primal solution is found.
   941     ///- The (finite) objective value if an optimal solution is found.
   942     Value primalValue() { return _getPrimalValue()+obj_const_comp;}
   943     ///@}
   944     
   945   };  
   946 
   947   ///\e
   948   
   949   ///\relates LpSolverBase::Expr
   950   ///
   951   inline LpSolverBase::Expr operator+(const LpSolverBase::Expr &a,
   952 				      const LpSolverBase::Expr &b) 
   953   {
   954     LpSolverBase::Expr tmp(a);
   955     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   956     return tmp;
   957   }
   958   ///\e
   959   
   960   ///\relates LpSolverBase::Expr
   961   ///
   962   inline LpSolverBase::Expr operator-(const LpSolverBase::Expr &a,
   963 				      const LpSolverBase::Expr &b) 
   964   {
   965     LpSolverBase::Expr tmp(a);
   966     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   967     return tmp;
   968   }
   969   ///\e
   970   
   971   ///\relates LpSolverBase::Expr
   972   ///
   973   inline LpSolverBase::Expr operator*(const LpSolverBase::Expr &a,
   974 				      const LpSolverBase::Value &b) 
   975   {
   976     LpSolverBase::Expr tmp(a);
   977     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
   978     return tmp;
   979   }
   980   
   981   ///\e
   982   
   983   ///\relates LpSolverBase::Expr
   984   ///
   985   inline LpSolverBase::Expr operator*(const LpSolverBase::Value &a,
   986 				      const LpSolverBase::Expr &b) 
   987   {
   988     LpSolverBase::Expr tmp(b);
   989     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
   990     return tmp;
   991   }
   992   ///\e
   993   
   994   ///\relates LpSolverBase::Expr
   995   ///
   996   inline LpSolverBase::Expr operator/(const LpSolverBase::Expr &a,
   997 				      const LpSolverBase::Value &b) 
   998   {
   999     LpSolverBase::Expr tmp(a);
  1000     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1001     return tmp;
  1002   }
  1003   
  1004   ///\e
  1005   
  1006   ///\relates LpSolverBase::Constr
  1007   ///
  1008   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
  1009 					 const LpSolverBase::Expr &f) 
  1010   {
  1011     return LpSolverBase::Constr(-LpSolverBase::INF,e-f,0);
  1012   }
  1013 
  1014   ///\e
  1015   
  1016   ///\relates LpSolverBase::Constr
  1017   ///
  1018   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &e,
  1019 					 const LpSolverBase::Expr &f) 
  1020   {
  1021     return LpSolverBase::Constr(e,f);
  1022   }
  1023 
  1024   ///\e
  1025   
  1026   ///\relates LpSolverBase::Constr
  1027   ///
  1028   inline LpSolverBase::Constr operator<=(const LpSolverBase::Expr &e,
  1029 					 const LpSolverBase::Value &f) 
  1030   {
  1031     return LpSolverBase::Constr(e,f);
  1032   }
  1033 
  1034   ///\e
  1035   
  1036   ///\relates LpSolverBase::Constr
  1037   ///
  1038   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
  1039 					 const LpSolverBase::Expr &f) 
  1040   {
  1041     return LpSolverBase::Constr(-LpSolverBase::INF,f-e,0);
  1042   }
  1043 
  1044 
  1045   ///\e
  1046   
  1047   ///\relates LpSolverBase::Constr
  1048   ///
  1049   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &e,
  1050 					 const LpSolverBase::Expr &f) 
  1051   {
  1052     return LpSolverBase::Constr(f,e);
  1053   }
  1054 
  1055 
  1056   ///\e
  1057   
  1058   ///\relates LpSolverBase::Constr
  1059   ///
  1060   inline LpSolverBase::Constr operator>=(const LpSolverBase::Expr &e,
  1061 					 const LpSolverBase::Value &f) 
  1062   {
  1063     return LpSolverBase::Constr(f,e);
  1064   }
  1065 
  1066   ///\e
  1067   
  1068   ///\relates LpSolverBase::Constr
  1069   ///
  1070   inline LpSolverBase::Constr operator==(const LpSolverBase::Expr &e,
  1071 					 const LpSolverBase::Expr &f) 
  1072   {
  1073     return LpSolverBase::Constr(0,e-f,0);
  1074   }
  1075 
  1076   ///\e
  1077   
  1078   ///\relates LpSolverBase::Constr
  1079   ///
  1080   inline LpSolverBase::Constr operator<=(const LpSolverBase::Value &n,
  1081 					 const LpSolverBase::Constr&c) 
  1082   {
  1083     LpSolverBase::Constr tmp(c);
  1084     ///\todo Create an own exception type.
  1085     if(!isnan(tmp.lowerBound())) throw LogicError();
  1086     else tmp.lowerBound()=n;
  1087     return tmp;
  1088   }
  1089   ///\e
  1090   
  1091   ///\relates LpSolverBase::Constr
  1092   ///
  1093   inline LpSolverBase::Constr operator<=(const LpSolverBase::Constr& c,
  1094 					 const LpSolverBase::Value &n)
  1095   {
  1096     LpSolverBase::Constr tmp(c);
  1097     ///\todo Create an own exception type.
  1098     if(!isnan(tmp.upperBound())) throw LogicError();
  1099     else tmp.upperBound()=n;
  1100     return tmp;
  1101   }
  1102 
  1103   ///\e
  1104   
  1105   ///\relates LpSolverBase::Constr
  1106   ///
  1107   inline LpSolverBase::Constr operator>=(const LpSolverBase::Value &n,
  1108 					 const LpSolverBase::Constr&c) 
  1109   {
  1110     LpSolverBase::Constr tmp(c);
  1111     ///\todo Create an own exception type.
  1112     if(!isnan(tmp.upperBound())) throw LogicError();
  1113     else tmp.upperBound()=n;
  1114     return tmp;
  1115   }
  1116   ///\e
  1117   
  1118   ///\relates LpSolverBase::Constr
  1119   ///
  1120   inline LpSolverBase::Constr operator>=(const LpSolverBase::Constr& c,
  1121 					 const LpSolverBase::Value &n)
  1122   {
  1123     LpSolverBase::Constr tmp(c);
  1124     ///\todo Create an own exception type.
  1125     if(!isnan(tmp.lowerBound())) throw LogicError();
  1126     else tmp.lowerBound()=n;
  1127     return tmp;
  1128   }
  1129 
  1130   ///\e
  1131   
  1132   ///\relates LpSolverBase::DualExpr
  1133   ///
  1134   inline LpSolverBase::DualExpr operator+(const LpSolverBase::DualExpr &a,
  1135 				      const LpSolverBase::DualExpr &b) 
  1136   {
  1137     LpSolverBase::DualExpr tmp(a);
  1138     tmp+=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1139     return tmp;
  1140   }
  1141   ///\e
  1142   
  1143   ///\relates LpSolverBase::DualExpr
  1144   ///
  1145   inline LpSolverBase::DualExpr operator-(const LpSolverBase::DualExpr &a,
  1146 				      const LpSolverBase::DualExpr &b) 
  1147   {
  1148     LpSolverBase::DualExpr tmp(a);
  1149     tmp-=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1150     return tmp;
  1151   }
  1152   ///\e
  1153   
  1154   ///\relates LpSolverBase::DualExpr
  1155   ///
  1156   inline LpSolverBase::DualExpr operator*(const LpSolverBase::DualExpr &a,
  1157 				      const LpSolverBase::Value &b) 
  1158   {
  1159     LpSolverBase::DualExpr tmp(a);
  1160     tmp*=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1161     return tmp;
  1162   }
  1163   
  1164   ///\e
  1165   
  1166   ///\relates LpSolverBase::DualExpr
  1167   ///
  1168   inline LpSolverBase::DualExpr operator*(const LpSolverBase::Value &a,
  1169 				      const LpSolverBase::DualExpr &b) 
  1170   {
  1171     LpSolverBase::DualExpr tmp(b);
  1172     tmp*=a; ///\todo Doesn't STL have some special 'merge' algorithm?
  1173     return tmp;
  1174   }
  1175   ///\e
  1176   
  1177   ///\relates LpSolverBase::DualExpr
  1178   ///
  1179   inline LpSolverBase::DualExpr operator/(const LpSolverBase::DualExpr &a,
  1180 				      const LpSolverBase::Value &b) 
  1181   {
  1182     LpSolverBase::DualExpr tmp(a);
  1183     tmp/=b; ///\todo Doesn't STL have some special 'merge' algorithm?
  1184     return tmp;
  1185   }
  1186   
  1187 
  1188 } //namespace lemon
  1189 
  1190 #endif //LEMON_LP_BASE_H