lemon/lp_base.h
author deba
Tue, 17 Oct 2006 10:50:57 +0000
changeset 2247 269a0dcee70b
parent 2185 e2bf51eab7f7
child 2260 4274224f8a7d
permissions -rw-r--r--
Update the Path concept
Concept check for paths

DirPath renamed to Path
The interface updated to the new lemon interface
Make difference between the empty path and the path from one node
Builder interface have not been changed
// I wanted but there was not accordance about it

UPath is removed
It was a buggy implementation, it could not iterate on the
nodes in the right order
Right way to use undirected paths => path of edges in undirected graphs

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