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