src/work/athos/lp_old/lp_solver_base.h
author deba
Sat, 09 Apr 2005 19:27:48 +0000
changeset 1330 52ef02524468
parent 1241 dadc9987c537
permissions -rw-r--r--
Heap concept moved to namespace concept.
marci@1031
     1
// -*- c++ -*-
marci@1152
     2
#ifndef LEMON_LP_SOLVER_BASE_H
marci@1152
     3
#define LEMON_LP_SOLVER_BASE_H
marci@1031
     4
marci@1031
     5
///\ingroup misc
marci@1031
     6
///\file
marci@1031
     7
marci@1031
     8
// #include <stdio.h>
marci@1031
     9
#include <stdlib.h>
marci@1097
    10
#include <iostream>
marci@1097
    11
#include <map>
marci@1104
    12
#include <limits>
marci@1031
    13
// #include <stdio>
marci@1031
    14
//#include <stdlib>
marci@1031
    15
marci@1031
    16
#include <iostream>
marci@1031
    17
#include <vector>
marci@1031
    18
#include <string>
marci@1031
    19
#include <list>
marci@1031
    20
#include <memory>
marci@1031
    21
#include <utility>
marci@1031
    22
marci@1031
    23
#include <lemon/invalid.h>
marci@1099
    24
#include <expression.h>
marci@1031
    25
//#include <stp.h>
marci@1031
    26
//#include <lemon/max_flow.h>
marci@1031
    27
//#include <augmenting_flow.h>
marci@1031
    28
//#include <iter_map.h>
marci@1031
    29
marci@1031
    30
using std::cout;
marci@1031
    31
using std::cin;
marci@1031
    32
using std::endl;
marci@1031
    33
marci@1031
    34
namespace lemon {
marci@1031
    35
  
marci@1031
    36
  /// \addtogroup misc
marci@1031
    37
  /// @{
marci@1031
    38
marci@1031
    39
  /// \brief A partitioned vector with iterable classes.
marci@1031
    40
  ///
marci@1031
    41
  /// This class implements a container in which the data is stored in an 
marci@1031
    42
  /// stl vector, the range is partitioned into sets and each set is 
marci@1031
    43
  /// doubly linked in a list. 
marci@1031
    44
  /// That is, each class is iterable by lemon iterators, and any member of 
marci@1031
    45
  /// the vector can bo moved to an other class.
marci@1031
    46
  template <typename T>
marci@1031
    47
  class IterablePartition {
marci@1031
    48
  protected:
marci@1031
    49
    struct Node {
marci@1031
    50
      T data;
marci@1031
    51
      int prev; //invalid az -1
marci@1031
    52
      int next; 
marci@1031
    53
    };
marci@1031
    54
    std::vector<Node> nodes;
marci@1031
    55
    struct Tip {
marci@1031
    56
      int first;
marci@1031
    57
      int last;
marci@1031
    58
    };
marci@1031
    59
    std::vector<Tip> tips;
marci@1031
    60
  public:
marci@1031
    61
    /// The classes are indexed by integers from \c 0 to \c classNum()-1.
marci@1031
    62
    int classNum() const { return tips.size(); }
marci@1031
    63
    /// This lemon style iterator iterates through a class. 
marci@1152
    64
    class Class;
marci@1031
    65
    /// Constructor. The number of classes is to be given which is fixed 
marci@1031
    66
    /// over the life of the container. 
marci@1031
    67
    /// The partition classes are indexed from 0 to class_num-1. 
marci@1031
    68
    IterablePartition(int class_num) { 
marci@1031
    69
      for (int i=0; i<class_num; ++i) {
marci@1031
    70
	Tip t;
marci@1031
    71
	t.first=t.last=-1;
marci@1031
    72
	tips.push_back(t);
marci@1031
    73
      }
marci@1031
    74
    }
marci@1031
    75
  protected:
marci@1152
    76
    void befuz(Class it, int class_id) {
marci@1031
    77
      if (tips[class_id].first==-1) {
marci@1031
    78
	if (tips[class_id].last==-1) {
marci@1031
    79
	  nodes[it.i].prev=nodes[it.i].next=-1;
marci@1031
    80
	  tips[class_id].first=tips[class_id].last=it.i;
marci@1031
    81
	}
marci@1031
    82
      } else {
marci@1031
    83
	nodes[it.i].prev=tips[class_id].last;
marci@1031
    84
	nodes[it.i].next=-1;
marci@1031
    85
	nodes[tips[class_id].last].next=it.i;
marci@1031
    86
	tips[class_id].last=it.i;
marci@1031
    87
      }
marci@1031
    88
    }
marci@1152
    89
    void kifuz(Class it, int class_id) {
marci@1031
    90
      if (tips[class_id].first==it.i) {
marci@1031
    91
	if (tips[class_id].last==it.i) {
marci@1031
    92
	  tips[class_id].first=tips[class_id].last=-1;
marci@1031
    93
	} else {
marci@1031
    94
	  tips[class_id].first=nodes[it.i].next;
marci@1031
    95
	  nodes[nodes[it.i].next].prev=-1;
marci@1031
    96
	}
marci@1031
    97
      } else {
marci@1031
    98
	if (tips[class_id].last==it.i) {
marci@1031
    99
	  tips[class_id].last=nodes[it.i].prev;
marci@1031
   100
	  nodes[nodes[it.i].prev].next=-1;
marci@1031
   101
	} else {
marci@1031
   102
	  nodes[nodes[it.i].next].prev=nodes[it.i].prev;
marci@1031
   103
	  nodes[nodes[it.i].prev].next=nodes[it.i].next;
marci@1031
   104
	}
marci@1031
   105
      }
marci@1031
   106
    }
marci@1031
   107
  public:
marci@1031
   108
    /// A new element with data \c t is pushed into the vector and into class 
marci@1031
   109
    /// \c class_id.
marci@1152
   110
    Class push_back(const T& t, int class_id) { 
marci@1031
   111
      Node n;
marci@1031
   112
      n.data=t;
marci@1031
   113
      nodes.push_back(n);
marci@1031
   114
      int i=nodes.size()-1;
marci@1031
   115
      befuz(i, class_id);
marci@1031
   116
      return i;
marci@1031
   117
    }
marci@1031
   118
    /// A member is moved to an other class.
marci@1152
   119
    void set(Class it, int old_class_id, int new_class_id) {
marci@1031
   120
      kifuz(it.i, old_class_id);
marci@1031
   121
      befuz(it.i, new_class_id);
marci@1031
   122
    }
marci@1031
   123
    /// Returns the data pointed by \c it.
marci@1152
   124
    T& operator[](Class it) { return nodes[it.i].data; }
marci@1031
   125
    /// Returns the data pointed by \c it.
marci@1152
   126
    const T& operator[](Class it) const { return nodes[it.i].data; }
marci@1031
   127
    ///.
marci@1152
   128
    class Class {
marci@1031
   129
      friend class IterablePartition;
marci@1031
   130
    protected:
marci@1031
   131
      int i;
marci@1031
   132
    public:
marci@1031
   133
      /// Default constructor.
marci@1152
   134
      Class() { }
marci@1031
   135
      /// This constructor constructs an iterator which points
marci@1031
   136
      /// to the member of th container indexed by the integer _i.
marci@1152
   137
      Class(const int& _i) : i(_i) { }
marci@1031
   138
      /// Invalid constructor.
marci@1152
   139
      Class(const Invalid&) : i(-1) { }
marci@1152
   140
      friend bool operator<(const Class& x, const Class& y);
marci@1099
   141
      friend std::ostream& operator<<(std::ostream& os, 
marci@1152
   142
				      const Class& it);
marci@1152
   143
      bool operator==(const Class& node) const {return i == node.i;}
marci@1152
   144
      bool operator!=(const Class& node) const {return i != node.i;}
marci@1031
   145
    };
marci@1152
   146
    friend bool operator<(const Class& x, const Class& y) {
marci@1099
   147
      return (x.i < y.i);
marci@1099
   148
    }
marci@1099
   149
    friend std::ostream& operator<<(std::ostream& os, 
marci@1152
   150
				    const Class& it) {
marci@1099
   151
      os << it.i;
marci@1099
   152
      return os;
marci@1099
   153
    }
marci@1031
   154
    /// First member of class \c class_id.
marci@1152
   155
    Class& first(Class& it, int class_id) const {
marci@1031
   156
      it.i=tips[class_id].first;
marci@1031
   157
      return it;
marci@1031
   158
    }
marci@1031
   159
    /// Next member.
marci@1152
   160
    Class& next(Class& it) const {
marci@1031
   161
      it.i=nodes[it.i].next;
marci@1031
   162
      return it;
marci@1031
   163
    }
marci@1031
   164
    /// True iff the iterator is valid.
marci@1152
   165
    bool valid(const Class& it) const { return it.i!=-1; }
marci@1152
   166
marci@1152
   167
    class ClassIt : public Class {
marci@1152
   168
      const IterablePartition* iterable_partition;
marci@1152
   169
    public:
marci@1152
   170
      ClassIt() { }
marci@1152
   171
      ClassIt(Invalid i) : Class(i) { }
marci@1152
   172
      ClassIt(const IterablePartition& _iterable_partition, 
marci@1152
   173
	      const int& i) : iterable_partition(&_iterable_partition) {
marci@1152
   174
        _iterable_partition.first(*this, i);
marci@1152
   175
      }
marci@1152
   176
      ClassIt(const IterablePartition& _iterable_partition, 
marci@1152
   177
	      const Class& _class) : 
marci@1152
   178
	Class(_class), iterable_partition(&_iterable_partition) { }
marci@1152
   179
      ClassIt& operator++() {
marci@1152
   180
        iterable_partition->next(*this);
marci@1152
   181
        return *this;
marci@1152
   182
      }
marci@1152
   183
    };
marci@1152
   184
marci@1031
   185
  };
marci@1031
   186
marci@1097
   187
marci@1031
   188
  /*! \e
marci@1143
   189
    \todo kellenene uj iterable structure bele, mert ez nem az igazi
marci@1111
   190
    \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
marci@1111
   191
    \todo LEKERDEZESEK!!!
marci@1111
   192
    \todo DOKSI!!!! Doxygen group!!!
marci@1111
   193
    The aim of this class is to give a general surface to different 
marci@1111
   194
    solvers, i.e. it makes possible to write algorithms using LP's, 
marci@1111
   195
    in which the solver can be changed to an other one easily.
marci@1112
   196
    \nosubgrouping
marci@1111
   197
  */
marci@1048
   198
  template <typename _Value>
athos@1241
   199
  class LpSolverBase {
marci@1112
   200
    
marci@1113
   201
    /*! @name Uncategorized functions and types (public members)
marci@1112
   202
    */
marci@1112
   203
    //@{
marci@1031
   204
  public:
marci@1112
   205
marci@1112
   206
    //UNCATEGORIZED
marci@1112
   207
marci@1031
   208
    /// \e
marci@1152
   209
    typedef IterablePartition<int> Rows;
marci@1152
   210
    /// \e
marci@1152
   211
    typedef IterablePartition<int> Cols;
marci@1152
   212
    /// \e
marci@1048
   213
    typedef _Value Value;
marci@1048
   214
    /// \e
marci@1152
   215
    typedef Rows::Class Row;
marci@1031
   216
    /// \e
marci@1152
   217
    typedef Cols::Class Col;
marci@1074
   218
  public:
marci@1031
   219
    /// \e
marci@1031
   220
    IterablePartition<int> row_iter_map;
marci@1031
   221
    /// \e
marci@1031
   222
    IterablePartition<int> col_iter_map;
marci@1031
   223
    /// \e
marci@1144
   224
    std::vector<Row> int_row_map;
marci@1143
   225
    /// \e
marci@1144
   226
    std::vector<Col> int_col_map;
marci@1143
   227
    /// \e
marci@1074
   228
    const int VALID_CLASS;
marci@1031
   229
    /// \e
marci@1074
   230
    const int INVALID_CLASS;
marci@1104
   231
    /// \e 
athos@1241
   232
    static const Value INF;
marci@1031
   233
  public:
marci@1031
   234
    /// \e
athos@1241
   235
    LpSolverBase() : row_iter_map(2), 
marci@1031
   236
		     col_iter_map(2), 
marci@1074
   237
		     VALID_CLASS(0), INVALID_CLASS(1) { }
marci@1031
   238
    /// \e
athos@1241
   239
    virtual ~LpSolverBase() { }
marci@1112
   240
    //@}
marci@1081
   241
marci@1112
   242
    /*! @name Medium level interface (public members)
marci@1112
   243
      These functions appear in the low level and also in the high level 
marci@1112
   244
      interfaces thus these each of these functions have to be implemented 
marci@1112
   245
      only once in the different interfaces.
marci@1112
   246
      This means that these functions have to be reimplemented for all of the 
marci@1112
   247
      different lp solvers. These are basic functions, and have the same 
marci@1112
   248
      parameter lists in the low and high level interfaces. 
marci@1112
   249
    */
marci@1112
   250
    //@{
marci@1112
   251
  public:
marci@1081
   252
marci@1112
   253
    //UNCATEGORIZED FUNCTIONS
marci@1112
   254
marci@1031
   255
    /// \e
marci@1031
   256
    virtual void setMinimize() = 0;
marci@1031
   257
    /// \e
marci@1031
   258
    virtual void setMaximize() = 0;
marci@1081
   259
marci@1112
   260
    //SOLVER FUNCTIONS
marci@1081
   261
marci@1112
   262
    /// \e
marci@1112
   263
    virtual void solveSimplex() = 0;
marci@1112
   264
    /// \e
marci@1112
   265
    virtual void solvePrimalSimplex() = 0;
marci@1112
   266
    /// \e
marci@1112
   267
    virtual void solveDualSimplex() = 0;
marci@1112
   268
marci@1112
   269
    //SOLUTION RETRIEVING
marci@1112
   270
marci@1112
   271
    /// \e
athos@1241
   272
    virtual Value getObjVal() = 0;
marci@1112
   273
marci@1112
   274
    //OTHER FUNCTIONS
marci@1112
   275
marci@1112
   276
    /// \e
marci@1112
   277
    virtual int rowNum() const = 0;
marci@1112
   278
    /// \e
marci@1112
   279
    virtual int colNum() const = 0;
marci@1112
   280
    /// \e
marci@1112
   281
    virtual int warmUp() = 0;
marci@1112
   282
    /// \e
marci@1112
   283
    virtual void printWarmUpStatus(int i) = 0;
marci@1112
   284
    /// \e
marci@1112
   285
    virtual int getPrimalStatus() = 0;
marci@1112
   286
    /// \e
marci@1112
   287
    virtual void printPrimalStatus(int i) = 0;
marci@1112
   288
    /// \e
marci@1112
   289
    virtual int getDualStatus() = 0;
marci@1112
   290
    /// \e
marci@1112
   291
    virtual void printDualStatus(int i) = 0;
marci@1144
   292
    /// Returns the status of the slack variable assigned to row \c row.
marci@1144
   293
    virtual int getRowStat(const Row& row) = 0;
marci@1112
   294
    /// \e
marci@1112
   295
    virtual void printRowStatus(int i) = 0;
marci@1144
   296
    /// Returns the status of the variable assigned to column \c col.
marci@1144
   297
    virtual int getColStat(const Col& col) = 0;
marci@1112
   298
    /// \e
marci@1112
   299
    virtual void printColStatus(int i) = 0;
marci@1112
   300
marci@1112
   301
    //@}
marci@1112
   302
marci@1112
   303
    /*! @name Low level interface (protected members)
marci@1112
   304
      Problem manipulating functions in the low level interface
marci@1112
   305
    */
marci@1112
   306
    //@{
marci@1074
   307
  protected:
marci@1112
   308
marci@1112
   309
    //MATRIX MANIPULATING FUNCTIONS
marci@1112
   310
marci@1031
   311
    /// \e
marci@1111
   312
    virtual int _addCol() = 0;
marci@1111
   313
    /// \e
marci@1074
   314
    virtual int _addRow() = 0;
marci@1031
   315
    /// \e
marci@1111
   316
    virtual void _eraseCol(int i) = 0;
marci@1111
   317
    /// \e
marci@1111
   318
    virtual void _eraseRow(int i) = 0;
marci@1081
   319
    /// \e
marci@1081
   320
    virtual void _setRowCoeffs(int i, 
athos@1241
   321
			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
marci@1081
   322
    /// \e
marci@1143
   323
    /// This routine modifies \c coeffs only by the \c push_back method.
marci@1143
   324
    virtual void _getRowCoeffs(int i, 
athos@1241
   325
			       std::vector<std::pair<int, Value> >& coeffs) = 0;
marci@1152
   326
    /// \e
marci@1081
   327
    virtual void _setColCoeffs(int i, 
athos@1241
   328
			       const std::vector<std::pair<int, Value> >& coeffs) = 0;
marci@1143
   329
    /// \e
marci@1143
   330
    /// This routine modifies \c coeffs only by the \c push_back method.
marci@1143
   331
    virtual void _getColCoeffs(int i, 
athos@1241
   332
			       std::vector<std::pair<int, Value> >& coeffs) = 0;
marci@1081
   333
    /// \e
athos@1241
   334
    virtual void _setCoeff(int col, int row, Value value) = 0;
marci@1152
   335
    /// \e
athos@1241
   336
    virtual Value _getCoeff(int col, int row) = 0;
marci@1152
   337
    //  public:
marci@1152
   338
    //    /// \e
marci@1152
   339
    //    enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
marci@1081
   340
  protected:
marci@1081
   341
    /// \e
marci@1110
   342
    /// The lower bound of a variable (column) have to be given by an 
athos@1241
   343
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   344
    /// Value or -INF.
athos@1241
   345
    virtual void _setColLowerBound(int i, Value value) = 0;
marci@1110
   346
    /// \e
marci@1111
   347
    /// The lower bound of a variable (column) is an 
athos@1241
   348
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   349
    /// Value or -INF.
athos@1241
   350
    virtual Value _getColLowerBound(int i) = 0;
marci@1111
   351
    /// \e
marci@1110
   352
    /// The upper bound of a variable (column) have to be given by an 
athos@1241
   353
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   354
    /// Value or INF.
athos@1241
   355
    virtual void _setColUpperBound(int i, Value value) = 0;
marci@1110
   356
    /// \e
marci@1110
   357
    /// The upper bound of a variable (column) is an 
athos@1241
   358
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   359
    /// Value or INF.
athos@1241
   360
    virtual Value _getColUpperBound(int i) = 0;
marci@1110
   361
    /// \e
marci@1111
   362
    /// The lower bound of a linear expression (row) have to be given by an 
athos@1241
   363
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   364
    /// Value or -INF.
athos@1241
   365
    virtual void _setRowLowerBound(int i, Value value) = 0;
marci@1081
   366
    /// \e
marci@1111
   367
    /// The lower bound of a linear expression (row) is an 
athos@1241
   368
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   369
    /// Value or -INF.
athos@1241
   370
    virtual Value _getRowLowerBound(int i) = 0;
marci@1111
   371
    /// \e
marci@1111
   372
    /// The upper bound of a linear expression (row) have to be given by an 
athos@1241
   373
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   374
    /// Value or INF.
athos@1241
   375
    virtual void _setRowUpperBound(int i, Value value) = 0;
marci@1111
   376
    /// \e
marci@1111
   377
    /// The upper bound of a linear expression (row) is an 
athos@1241
   378
    /// extended number of type Value, i.e. a finite number of type 
athos@1241
   379
    /// Value or INF.
athos@1241
   380
    virtual Value _getRowUpperBound(int i) = 0;
marci@1081
   381
    /// \e
athos@1241
   382
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
marci@1081
   383
    /// \e
athos@1241
   384
    virtual Value _getObjCoeff(int i) = 0;
marci@1112
   385
    
marci@1112
   386
    //SOLUTION RETRIEVING
marci@1081
   387
marci@1111
   388
    /// \e
athos@1241
   389
    virtual Value _getPrimal(int i) = 0;
marci@1112
   390
    //@}
marci@1112
   391
    
marci@1112
   392
    /*! @name High level interface (public members)
marci@1112
   393
      Problem manipulating functions in the high level interface
marci@1112
   394
    */
marci@1112
   395
    //@{
marci@1112
   396
  public:
marci@1081
   397
marci@1112
   398
    //MATRIX MANIPULATING FUNCTIONS
marci@1081
   399
marci@1074
   400
    /// \e
marci@1144
   401
    Col addCol() {
marci@1074
   402
      int i=_addCol();  
marci@1144
   403
      Col col;
marci@1144
   404
      col_iter_map.first(col, INVALID_CLASS);
marci@1144
   405
      if (col_iter_map.valid(col)) { //van hasznalhato hely
marci@1144
   406
	col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
marci@1144
   407
	col_iter_map[col]=i;
marci@1074
   408
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1144
   409
	col=col_iter_map.push_back(i, VALID_CLASS);
marci@1074
   410
      }
marci@1144
   411
      int_col_map.push_back(col);
marci@1144
   412
      return col;
marci@1074
   413
    }
marci@1074
   414
    /// \e
marci@1144
   415
    Row addRow() {
marci@1111
   416
      int i=_addRow();
marci@1144
   417
      Row row;
marci@1144
   418
      row_iter_map.first(row, INVALID_CLASS);
marci@1144
   419
      if (row_iter_map.valid(row)) { //van hasznalhato hely
marci@1144
   420
	row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
marci@1144
   421
	row_iter_map[row]=i;
marci@1111
   422
      } else { //a cucc vegere kell inzertalni mert nincs szabad hely
marci@1144
   423
	row=row_iter_map.push_back(i, VALID_CLASS);
marci@1031
   424
      }
marci@1144
   425
      int_row_map.push_back(row);
marci@1144
   426
      return row;
marci@1074
   427
    }
marci@1074
   428
    /// \e
marci@1144
   429
    void eraseCol(const Col& col) {
marci@1144
   430
      col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
marci@1074
   431
      int cols[2];
marci@1144
   432
      cols[1]=col_iter_map[col];
marci@1074
   433
      _eraseCol(cols[1]);
marci@1144
   434
      col_iter_map[col]=0; //glpk specifikus, de kell ez??
marci@1144
   435
      Col it;
marci@1074
   436
      for (col_iter_map.first(it, VALID_CLASS); 
marci@1074
   437
	   col_iter_map.valid(it); col_iter_map.next(it)) {
marci@1074
   438
	if (col_iter_map[it]>cols[1]) --col_iter_map[it];
marci@1074
   439
      }
marci@1143
   440
      int_col_map.erase(int_col_map.begin()+cols[1]);
marci@1031
   441
    }
marci@1031
   442
    /// \e
marci@1144
   443
    void eraseRow(const Row& row) {
marci@1144
   444
      row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
marci@1074
   445
      int rows[2];
marci@1144
   446
      rows[1]=row_iter_map[row];
marci@1074
   447
      _eraseRow(rows[1]);
marci@1144
   448
      row_iter_map[row]=0; //glpk specifikus, de kell ez??
marci@1144
   449
      Row it;
marci@1074
   450
      for (row_iter_map.first(it, VALID_CLASS); 
marci@1074
   451
	   row_iter_map.valid(it); row_iter_map.next(it)) {
marci@1074
   452
	if (row_iter_map[it]>rows[1]) --row_iter_map[it];
marci@1074
   453
      }
marci@1143
   454
      int_row_map.erase(int_row_map.begin()+rows[1]);
marci@1074
   455
    }
marci@1031
   456
    /// \e
athos@1241
   457
    void setCoeff(Col col, Row row, Value value) {
marci@1152
   458
      _setCoeff(col_iter_map[col], row_iter_map[row], value);
marci@1152
   459
    }
marci@1152
   460
    /// \e
athos@1241
   461
    Value getCoeff(Col col, Row row) {
marci@1152
   462
      return _getCoeff(col_iter_map[col], row_iter_map[row], value);
marci@1152
   463
    }
marci@1152
   464
    /// \e
athos@1241
   465
    void setColLowerBound(Col col, Value lo) {
marci@1144
   466
      _setColLowerBound(col_iter_map[col], lo);
marci@1111
   467
    }
marci@1111
   468
    /// \e
athos@1241
   469
    Value getColLowerBound(Col col) {
marci@1144
   470
      return _getColLowerBound(col_iter_map[col]);
marci@1111
   471
    }
marci@1111
   472
    /// \e
athos@1241
   473
    void setColUpperBound(Col col, Value up) {
marci@1144
   474
      _setColUpperBound(col_iter_map[col], up);
marci@1110
   475
    }
marci@1110
   476
    /// \e
athos@1241
   477
    Value getColUpperBound(Col col) {      
marci@1144
   478
      return _getColUpperBound(col_iter_map[col]);
marci@1111
   479
    }
marci@1111
   480
    /// \e
athos@1241
   481
    void setRowLowerBound(Row row, Value lo) {
marci@1144
   482
      _setRowLowerBound(row_iter_map[row], lo);
marci@1110
   483
    }
marci@1110
   484
    /// \e
athos@1241
   485
    Value getRowLowerBound(Row row) {
marci@1144
   486
      return _getRowLowerBound(row_iter_map[row]);
marci@1110
   487
    }
marci@1110
   488
    /// \e
athos@1241
   489
    void setRowUpperBound(Row row, Value up) {
marci@1144
   490
      _setRowUpperBound(row_iter_map[row], up);
marci@1081
   491
    }
marci@1031
   492
    /// \e
athos@1241
   493
    Value getRowUpperBound(Row row) {      
marci@1144
   494
      return _getRowUpperBound(row_iter_map[row]);
marci@1111
   495
    }
marci@1111
   496
    /// \e
athos@1241
   497
    void setObjCoeff(const Col& col, Value obj_coef) {
marci@1152
   498
      _setObjCoeff(col_iter_map[col], obj_coef);
marci@1111
   499
    }
marci@1111
   500
    /// \e
athos@1241
   501
    Value getObjCoeff(const Col& col) {
marci@1152
   502
      return _getObjCoeff(col_iter_map[col]);
marci@1081
   503
    }
marci@1081
   504
marci@1112
   505
    //SOLUTION RETRIEVING FUNCTIONS
marci@1112
   506
marci@1112
   507
    /// \e
athos@1241
   508
    Value getPrimal(const Col& col) {
marci@1144
   509
      return _getPrimal(col_iter_map[col]);
marci@1112
   510
    }    
marci@1112
   511
marci@1112
   512
    //@}
marci@1112
   513
marci@1112
   514
    /*! @name User friend interface
marci@1112
   515
      Problem manipulating functions in the user friend interface
marci@1112
   516
    */
marci@1112
   517
    //@{
marci@1112
   518
marci@1112
   519
    //EXPRESSION TYPES
marci@1099
   520
marci@1099
   521
    /// \e
athos@1241
   522
    typedef Expr<Col, Value> Expression;
marci@1099
   523
    /// \e
athos@1241
   524
    typedef Expr<Row, Value> DualExpression;
marci@1144
   525
    /// \e
athos@1241
   526
    typedef Constr<Col, Value> Constraint;
marci@1112
   527
marci@1112
   528
    //MATRIX MANIPULATING FUNCTIONS
marci@1112
   529
marci@1099
   530
    /// \e
marci@1144
   531
    void setRowCoeffs(Row row, const Expression& expr) {
athos@1241
   532
      std::vector<std::pair<int, Value> > row_coeffs;
marci@1099
   533
      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   534
	  i!=expr.data.end(); ++i) {
marci@1099
   535
	row_coeffs.push_back(std::make_pair
marci@1099
   536
			     (col_iter_map[(*i).first], (*i).second));
marci@1099
   537
      }
marci@1144
   538
      _setRowCoeffs(row_iter_map[row], row_coeffs);
marci@1144
   539
    }
marci@1144
   540
    /// \e 
marci@1144
   541
    void setRow(Row row, const Constraint& constr) {
marci@1144
   542
      setRowCoeffs(row, constr.expr);
marci@1144
   543
      setRowLowerBound(row, constr.lo);
marci@1144
   544
      setRowUpperBound(row, constr.up);
marci@1144
   545
    }
marci@1144
   546
    /// \e 
marci@1144
   547
    Row addRow(const Constraint& constr) {
marci@1144
   548
      Row row=addRow();
marci@1144
   549
      setRowCoeffs(row, constr.expr);
marci@1144
   550
      setRowLowerBound(row, constr.lo);
marci@1144
   551
      setRowUpperBound(row, constr.up);
marci@1144
   552
      return row;
marci@1099
   553
    }
marci@1099
   554
    /// \e
marci@1143
   555
    /// This routine modifies \c expr by only adding to it.
marci@1144
   556
    void getRowCoeffs(Row row, Expression& expr) {
athos@1241
   557
      std::vector<std::pair<int, Value> > row_coeffs;
marci@1144
   558
      _getRowCoeffs(row_iter_map[row], row_coeffs);
athos@1241
   559
      for(typename std::vector<std::pair<int, Value> >::const_iterator 
marci@1143
   560
 	    i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
marci@1143
   561
 	expr+= (*i).second*int_col_map[(*i).first];
marci@1143
   562
      }
marci@1143
   563
    }
marci@1143
   564
    /// \e
marci@1144
   565
    void setColCoeffs(Col col, const DualExpression& expr) {
athos@1241
   566
      std::vector<std::pair<int, Value> > col_coeffs;
marci@1099
   567
      for(typename DualExpression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   568
	  i!=expr.data.end(); ++i) {
marci@1099
   569
	col_coeffs.push_back(std::make_pair
marci@1099
   570
			     (row_iter_map[(*i).first], (*i).second));
marci@1099
   571
      }
marci@1144
   572
      _setColCoeffs(col_iter_map[col], col_coeffs);
marci@1099
   573
    }
marci@1099
   574
    /// \e
marci@1143
   575
    /// This routine modifies \c expr by only adding to it.
marci@1144
   576
    void getColCoeffs(Col col, DualExpression& expr) {
athos@1241
   577
      std::vector<std::pair<int, Value> > col_coeffs;
marci@1144
   578
      _getColCoeffs(col_iter_map[col], col_coeffs);
athos@1241
   579
      for(typename std::vector<std::pair<int, Value> >::const_iterator 
marci@1143
   580
 	    i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
marci@1143
   581
 	expr+= (*i).second*int_row_map[(*i).first];
marci@1143
   582
      }
marci@1143
   583
    }
marci@1143
   584
    /// \e
marci@1099
   585
    void setObjCoeffs(const Expression& expr) {
marci@1152
   586
      // writing zero everywhere
marci@1152
   587
      for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
marci@1152
   588
	setObjCoeff(it, 0.0);
marci@1152
   589
      // writing the data needed
marci@1099
   590
      for(typename Expression::Data::const_iterator i=expr.data.begin(); 
marci@1099
   591
	  i!=expr.data.end(); ++i) {
marci@1152
   592
	setObjCoeff((*i).first, (*i).second);
marci@1099
   593
      }
marci@1099
   594
    }
marci@1143
   595
    /// \e
marci@1143
   596
    /// This routine modifies \c expr by only adding to it.
marci@1143
   597
    void getObjCoeffs(Expression& expr) {
marci@1152
   598
      for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
marci@1152
   599
	expr+=getObjCoeff(it)*it;
marci@1152
   600
    }
marci@1152
   601
    //@}
marci@1152
   602
marci@1152
   603
marci@1152
   604
    /*! @name MIP functions and types (public members)
marci@1152
   605
    */
marci@1152
   606
    //@{
marci@1152
   607
  public:
marci@1152
   608
    /// \e
marci@1152
   609
    virtual void solveBandB() = 0;
marci@1152
   610
    /// \e
marci@1152
   611
    virtual void setLP() = 0;
marci@1152
   612
    /// \e
marci@1152
   613
    virtual void setMIP() = 0;
marci@1152
   614
  protected:
marci@1152
   615
   /// \e
marci@1152
   616
    virtual void _setColCont(int i) = 0;
marci@1152
   617
    /// \e
marci@1152
   618
    virtual void _setColInt(int i) = 0;
marci@1153
   619
    /// \e
athos@1241
   620
    virtual Value _getMIPPrimal(int i) = 0;
marci@1152
   621
  public:
marci@1152
   622
    /// \e
marci@1152
   623
    void setColCont(Col col) {
marci@1152
   624
      _setColCont(col_iter_map[col]);
marci@1152
   625
    }
marci@1152
   626
    /// \e
marci@1152
   627
    void setColInt(Col col) {
marci@1152
   628
      _setColInt(col_iter_map[col]);
marci@1143
   629
    }
marci@1153
   630
    /// \e
athos@1241
   631
    Value getMIPPrimal(Col col) {
marci@1153
   632
      return _getMIPPrimal(col_iter_map[col]);
marci@1153
   633
    }
marci@1112
   634
    //@}
marci@1031
   635
  };
marci@1031
   636
marci@1031
   637
} //namespace lemon
marci@1031
   638
marci@1152
   639
#endif //LEMON_LP_SOLVER_BASE_H