src/work/athos/lp/lp_base.h
author alpar
Thu, 24 Mar 2005 12:15:50 +0000
changeset 1254 c9558638fe42
parent 1251 8f7ce70899e6
child 1256 3bb4ed285c39
permissions -rw-r--r--
- lp_solver_skeleton.h/cc: skeleton for actual lp implenetations
- lp_test.cc: test file
- updated Makefile
athos@1247
     1
/* -*- C++ -*-
alpar@1253
     2
 * src/lemon/lp_base.h - Part of LEMON, a generic C++ optimization library
athos@1247
     3
 *
athos@1247
     4
 * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
athos@1247
     5
 * (Egervary Combinatorial Optimization Research Group, EGRES).
athos@1247
     6
 *
athos@1247
     7
 * Permission to use, modify and distribute this software is granted
athos@1247
     8
 * provided that this copyright notice appears in all copies. For
athos@1247
     9
 * precise terms see the accompanying LICENSE file.
athos@1247
    10
 *
athos@1247
    11
 * This software is provided "AS IS" with no warranty of any kind,
athos@1247
    12
 * express or implied, and with no claim as to its suitability for any
athos@1247
    13
 * purpose.
athos@1247
    14
 *
athos@1247
    15
 */
athos@1247
    16
athos@1246
    17
#ifndef LEMON_LP_BASE_H
athos@1246
    18
#define LEMON_LP_BASE_H
athos@1246
    19
alpar@1253
    20
#include<vector>
alpar@1253
    21
alpar@1253
    22
#include<lemon/error.h>
alpar@1253
    23
alpar@1253
    24
#include"lin_expr.h"
athos@1246
    25
///\file
athos@1246
    26
///\brief The interface of the LP solver interface.
athos@1246
    27
namespace lemon {
alpar@1253
    28
  
alpar@1253
    29
  ///Internal data structure to convert floating id's to fix one's
alpar@1253
    30
    
alpar@1253
    31
  ///\todo This might by implemented to be usable in other places.
alpar@1253
    32
  class _FixId 
alpar@1253
    33
  {
alpar@1253
    34
    std::vector<int> index;
alpar@1253
    35
    std::vector<int> cross;
alpar@1253
    36
    int first_free;
alpar@1253
    37
  public:
alpar@1253
    38
    _FixId() : first_free(-1) {};
alpar@1253
    39
    ///Convert a floating id to a fix one
alpar@1253
    40
alpar@1253
    41
    ///\param n is a floating id
alpar@1253
    42
    ///\return the corresponding fix id
alpar@1253
    43
    int fixId(int n) {return cross[n];}
alpar@1253
    44
    ///Convert a fix id to a floating one
alpar@1253
    45
alpar@1253
    46
    ///\param n is a fix id
alpar@1253
    47
    ///\return the corresponding floating id
alpar@1253
    48
    int floatingId(int n) { return index[n];}
alpar@1253
    49
    ///Add a new floating id.
alpar@1253
    50
alpar@1253
    51
    ///\param n is a floating id
alpar@1253
    52
    ///\return the fix id of the new value
alpar@1253
    53
    ///\todo Multiple additions should also be handled.
alpar@1253
    54
    int insert(int n)
alpar@1253
    55
    {
alpar@1253
    56
      if(n>=int(cross.size())) {
alpar@1253
    57
	cross.resize(n+1);
alpar@1253
    58
	if(first_free==-1) {
alpar@1253
    59
	  cross[n]=index.size();
alpar@1253
    60
	  index.push_back(n);
alpar@1253
    61
	}
alpar@1253
    62
	else {
alpar@1253
    63
	  cross[n]=first_free;
alpar@1253
    64
	  int next=index[first_free];
alpar@1253
    65
	  index[first_free]=n;
alpar@1253
    66
	  first_free=next;
alpar@1253
    67
	}
alpar@1253
    68
      }
alpar@1253
    69
      else throw LogicError(); //floatingId-s must form a continuous range;
alpar@1253
    70
    }
alpar@1253
    71
    ///Remove a fix id.
alpar@1253
    72
alpar@1253
    73
    ///\param n is a fix id
alpar@1253
    74
    ///
alpar@1253
    75
    void erase(int n) 
alpar@1253
    76
    {
alpar@1253
    77
      int fl=index[n];
alpar@1253
    78
      index[n]=first_free;
alpar@1253
    79
      first_free=n;
alpar@1253
    80
      for(int i=fl+1;i<int(cross.size());++i) {
alpar@1253
    81
	cross[i-1]=cross[i];
alpar@1253
    82
	index[cross[i]]--;
alpar@1253
    83
      }
alpar@1253
    84
      cross.pop_back();
alpar@1253
    85
    }
alpar@1253
    86
    ///An upper bound on the largest fix id.
alpar@1253
    87
alpar@1253
    88
    ///\todo Do we need this?
alpar@1253
    89
    ///
alpar@1253
    90
    std::size_t maxFixId() { return cross.size()-1; }
alpar@1253
    91
  
alpar@1253
    92
  };
alpar@1253
    93
    
alpar@1253
    94
  ///Common base class for LP solvers
athos@1246
    95
  class LpSolverBase {
alpar@1253
    96
    
athos@1247
    97
  public:
athos@1247
    98
athos@1247
    99
    /// \e
athos@1247
   100
    typedef double Value;
athos@1247
   101
    /// \e 
athos@1247
   102
    static const Value INF;
alpar@1253
   103
    
alpar@1253
   104
    ///\e
alpar@1253
   105
    class Col { protected: int id; friend class LpSolverBase; };
alpar@1253
   106
    ///\e
alpar@1253
   107
    class Row { protected: int id; friend class LpSolverBase; };
alpar@1253
   108
alpar@1253
   109
    typedef SparseLinExpr<Col, Value> Expr;
alpar@1253
   110
alpar@1253
   111
  protected:
alpar@1253
   112
    _FixId rows;
alpar@1253
   113
    _FixId cols;
athos@1246
   114
athos@1246
   115
    //MATRIX MANIPULATING FUNCTIONS
athos@1246
   116
athos@1246
   117
    /// \e
athos@1246
   118
    virtual int _addCol() = 0;
athos@1246
   119
    /// \e
athos@1246
   120
    virtual int _addRow() = 0;
athos@1246
   121
    /// \e
alpar@1253
   122
athos@1246
   123
    /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
alpar@1253
   124
    ///
athos@1246
   125
    virtual void _setRowCoeffs(int i, 
athos@1251
   126
			       int length,
athos@1247
   127
                               int  const * indices, 
athos@1247
   128
                               Value  const * values ) = 0;
athos@1246
   129
    /// \e
alpar@1253
   130
athos@1246
   131
    /// \warning Arrays are indexed from 1 (datum at index 0 is ignored)
alpar@1253
   132
    ///
athos@1246
   133
    virtual void _setColCoeffs(int i, 
athos@1251
   134
			       int length,
athos@1247
   135
                               int  const * indices, 
athos@1247
   136
                               Value  const * values ) = 0;
athos@1246
   137
    
athos@1247
   138
    /// \e
alpar@1253
   139
athos@1247
   140
    /// The lower bound of a variable (column) have to be given by an 
athos@1247
   141
    /// extended number of type Value, i.e. a finite number of type 
athos@1247
   142
    /// Value or -INF.
athos@1247
   143
    virtual void _setColLowerBound(int i, Value value) = 0;
athos@1247
   144
    /// \e
alpar@1253
   145
athos@1247
   146
    /// The upper bound of a variable (column) have to be given by an 
athos@1247
   147
    /// extended number of type Value, i.e. a finite number of type 
athos@1247
   148
    /// Value or INF.
athos@1247
   149
    virtual void _setColUpperBound(int i, Value value) = 0;
athos@1247
   150
    /// \e
alpar@1253
   151
athos@1247
   152
    /// The lower bound of a linear expression (row) have to be given by an 
athos@1247
   153
    /// extended number of type Value, i.e. a finite number of type 
athos@1247
   154
    /// Value or -INF.
athos@1247
   155
    virtual void _setRowLowerBound(int i, Value value) = 0;
athos@1247
   156
    /// \e
alpar@1253
   157
athos@1247
   158
    /// The upper bound of a linear expression (row) have to be given by an 
athos@1247
   159
    /// extended number of type Value, i.e. a finite number of type 
athos@1247
   160
    /// Value or INF.
athos@1247
   161
    virtual void _setRowUpperBound(int i, Value value) = 0;
athos@1247
   162
athos@1247
   163
    /// \e
athos@1247
   164
    virtual void _setObjCoeff(int i, Value obj_coef) = 0;
alpar@1253
   165
alpar@1253
   166
    ///\e
alpar@1253
   167
alpar@1253
   168
    ///\bug unimplemented!!!!
alpar@1253
   169
    void clearObj() {}
alpar@1253
   170
  public:
alpar@1253
   171
alpar@1253
   172
alpar@1253
   173
    ///\e
alpar@1253
   174
    virtual ~LpSolverBase() {}
alpar@1253
   175
alpar@1253
   176
    ///Add a new empty column (i.e a new variable) to the LP
alpar@1253
   177
    Col addCol() { Col c; c.id=cols.insert(_addCol()); return c;}
alpar@1253
   178
    ///Add a new empty row (i.e a new constaint) to the LP
alpar@1253
   179
    Row addRow() { Row r; r.id=rows.insert(_addRow()); return r;}
alpar@1253
   180
alpar@1253
   181
    ///Add a new row (i.e a new constaint) to the LP
alpar@1253
   182
alpar@1253
   183
    ///\param l lower bound (-INF means no bound)
alpar@1253
   184
    ///\param e a linear expression (see \ref Expr)
alpar@1253
   185
    ///\param u upper bound (INF means no bound)
alpar@1253
   186
    ///\bug This is a temportary function. The interface will change to
alpar@1253
   187
    ///a better one.
alpar@1253
   188
    Row addRow(Value l,Expr e, Value u) {
alpar@1253
   189
      Row r=addRow();
alpar@1253
   190
      std::vector<int> indices;
alpar@1253
   191
      std::vector<Value> values;
alpar@1253
   192
      indices.push_back(0);
alpar@1253
   193
      values.push_back(0);
alpar@1253
   194
      for(Expr::iterator i=e.begin(); i!=e.end(); ++i) {
alpar@1253
   195
	indices.push_back(cols.floatingId((*i).first.id));
alpar@1253
   196
	values.push_back((*i).second);
alpar@1253
   197
      }
alpar@1253
   198
      _setRowCoeffs(rows.floatingId(r.id),indices.size()-1,
alpar@1253
   199
		    &indices[0],&values[0]);
alpar@1253
   200
      _setRowLowerBound(rows.floatingId(r.id),l);
alpar@1253
   201
      _setRowUpperBound(rows.floatingId(r.id),l);
alpar@1253
   202
      return r;
alpar@1253
   203
    }
alpar@1253
   204
alpar@1253
   205
    /// Set the lower bound of a column (i.e a variable)
alpar@1253
   206
alpar@1253
   207
    /// The upper bound of a variable (column) have to be given by an 
alpar@1253
   208
    /// extended number of type Value, i.e. a finite number of type 
alpar@1253
   209
    /// Value or -INF.
alpar@1253
   210
    virtual void setColLowerBound(Col c, Value value) {
alpar@1253
   211
      _setColLowerBound(cols.floatingId(c.id),value);
alpar@1253
   212
    }
alpar@1253
   213
    /// Set the upper bound of a column (i.e a variable)
alpar@1253
   214
alpar@1253
   215
    /// The upper bound of a variable (column) have to be given by an 
alpar@1253
   216
    /// extended number of type Value, i.e. a finite number of type 
alpar@1253
   217
    /// Value or INF.
alpar@1253
   218
    virtual void setColUpperBound(Col c, Value value) {
alpar@1253
   219
      _setColUpperBound(cols.floatingId(c.id),value);
alpar@1253
   220
    };
alpar@1253
   221
    /// Set the lower bound of a row (i.e a constraint)
alpar@1253
   222
alpar@1253
   223
    /// The lower bound of a linear expression (row) have to be given by an 
alpar@1253
   224
    /// extended number of type Value, i.e. a finite number of type 
alpar@1253
   225
    /// Value or -INF.
alpar@1253
   226
    virtual void setRowLowerBound(Row r, Value value) {
alpar@1253
   227
      _setRowLowerBound(rows.floatingId(r.id),value);
alpar@1253
   228
    };
alpar@1253
   229
    /// Set the upper bound of a row (i.e a constraint)
alpar@1253
   230
alpar@1253
   231
    /// The upper bound of a linear expression (row) have to be given by an 
alpar@1253
   232
    /// extended number of type Value, i.e. a finite number of type 
alpar@1253
   233
    /// Value or INF.
alpar@1253
   234
    virtual void setRowUpperBound(Row r, Value value) {
alpar@1253
   235
      _setRowUpperBound(rows.floatingId(r.id),value);
alpar@1253
   236
    };
alpar@1253
   237
    ///Set an element of the objective function
alpar@1253
   238
    void setObjCoeff(Col c, Value v) {_setObjCoeff(cols.floatingId(c.id),v); };
alpar@1253
   239
    ///Set the objective function
alpar@1253
   240
    
alpar@1253
   241
    ///\param e is a linear expression of type \ref Expr.
alpar@1253
   242
    ///\todo What to do with the constant component?
alpar@1253
   243
    void setObj(Expr e) {
alpar@1253
   244
      clearObj();
alpar@1253
   245
      for (Expr::iterator i=e.begin(); i!=e.end(); ++i)
alpar@1253
   246
	setObjCoeff((*i).first,(*i).second);
alpar@1253
   247
    }
alpar@1253
   248
    
athos@1248
   249
  };  
athos@1246
   250
athos@1246
   251
} //namespace lemon
athos@1246
   252
athos@1246
   253
#endif //LEMON_LP_BASE_H