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