Scippy

SoPlex

Sequential object-oriented simPlex

spxpricer.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 
17 /**@file spxpricer.h
18  * @brief Abstract pricer base class.
19  */
20 #ifndef _SPXPRICE_H_
21 #define _SPXPRICE_H_
22 
23 #include <assert.h>
24 
25 #include "spxdefines.h"
26 #include "spxsolver.h"
27 #include "sorter.h"
28 
29 namespace soplex
30 {
31 
32 /**@brief Abstract pricer base class.
33  @ingroup Algo
34 
35  Class SPxPricer is a pure virtual class defining the interface for pricer
36  classes to be used by SoPlex. The pricer's task is to select a vector to
37  enter or leave the simplex basis, depending on the chosen simplex type.
38 
39  An SPxPricer first #load%s the SoPlex object for which pricing is to
40  be performed. Then, depending of the SPxSolver::Type, methods
41  #selectEnter() and #entered4() (for entering Simplex) or #selectLeave()
42  and #left4() (for leaving Simplex) are called by SoPlex. The SPxPricer
43  object is informed of a change of the SPxSolver::Type by calling method
44  #setType().
45 */
46 class SPxPricer
47 {
48 protected:
49 
50  //-------------------------------------
51  /**@name Data */
52  //@{
53  /// name of the pricer
54  const char* m_name;
55  /// the solver
57  /// violation bound
59  /// vector to store pricing weights or norms
62  /// are the weights already set up?
64  //@}
65 
66 
67  struct IdxElement
68  {
69  int idx;
71  };
72 
73  /// Compare class to sort idx/val pairs, used for hypersparse pricing leaving
74  struct IdxCompare
75  {
76  public:
77  /// constructor
79  : elements(0)
80  {}
81 
83 
84  Real operator() (
85  IdxElement a,
86  IdxElement b
87  ) const
88  {
89  return b.val - a.val;
90  }
91  };
92 
94 
95 public:
96 
97  // violation types used for (hyper) sparse pricing
99  {
101  VIOLATED = 1,
103  };
104 
105  //-------------------------------------
106  /**@name Initialization */
107  //@{
108  /// get name of pricer.
109  virtual const char* getName() const
110  {
111  return m_name;
112  }
113 
114  /// loads LP.
115  /** Loads the solver and LP for which pricing steps are to be performed.
116  */
117  virtual void load(SPxSolver* p_solver)
118  {
119  thesolver = p_solver;
120  }
121 
122  /// unloads LP.
123  virtual void clear()
124  {
125  thesolver = 0;
126  }
127 
128  /// returns loaded SPxSolver object.
129  virtual SPxSolver* solver() const
130  {
131  return thesolver;
132  }
133 
134  /// returns violation bound \ref soplex::SPxPricer::theeps "theeps".
135  virtual Real epsilon() const
136  {
137  return theeps;
138  }
139 
140  /// sets violation bound.
141  /** Inequality violations are accepted, if their size is less than \p eps.
142  */
143  virtual void setEpsilon(Real eps)
144  {
145  assert(eps >= 0.0);
146 
147  theeps = eps;
148  }
149 
150  /// sets pricing type.
151  /** Informs pricer about (a change of) the loaded SoPlex's Type. In
152  the sequel, only the corresponding select methods may be called.
153  */
154  virtual void setType(SPxSolver::Type)
155  {}
156 
157  /// sets basis representation.
158  /** Informs pricer about (a change of) the loaded SoPlex's
159  Representation.
160  */
162  {}
163  //@}
164 
165  //-------------------------------------
166  /**@name Pivoting */
167  //@{
168  /// returns selected index to leave basis.
169  /** Selects the index of a vector to leave the basis. The selected index
170  i, say, must be in the range 0 <= i < solver()->dim() and its
171  tested value must fullfill solver()->test()[i] < -#epsilon().
172  */
173  virtual int selectLeave() = 0;
174 
175  /// performs leaving pivot.
176  /** Method #left4() is called after each simplex iteration in LEAVE
177  mode. It informs the SPxPricer that the \p n 'th variable has left
178  the basis for \p id to come in at this position. When being called,
179  all vectors of SoPlex involved in such an entering update are
180  setup correctly and may be accessed via the corresponding methods
181  (\ref SPxSolver::fVec() "fVec()", \ref SPxSolver::pVec() "pVec()",
182  etc.). In general, argument \p n will be the one returned by the
183  SPxPricer at the previous call to #selectLeave(). However, one can not
184  rely on this.
185  */
186  virtual void left4(int /*n*/, SPxId /*id*/) {}
187 
188  /// selects Id to enter basis.
189  /** Selects the SPxId of a vector to enter the basis. The selected
190  id, must not represent a basic index (i.e. solver()->isBasic(id) must
191  be false). However, the corresponding test value needs not to be less
192  than -#epsilon(). If not, SoPlex will discard the pivot.
193 
194  Note:
195  When method #selectEnter() is called by the loaded SoPlex
196  object, all values from \ref SPxSolver::coTest() "coTest()" are
197  up to date. However, whether the elements of
198  \ref SPxSolver::test() "test()" are up to date depends on the
199  SPxSolver::Pricing type.
200  */
201  virtual SPxId selectEnter() = 0;
202 
203  /// performs entering pivot.
204  /** Method #entered4() is called after each simplex iteration in ENTER
205  mode. It informs the SPxPricer that variable \p id has entered
206  at the \p n 'th position. When being called, all vectors of SoPlex
207  involved in such an entering update are setup correctly and may be
208  accessed via the corresponding methods
209  (\ref SPxSolver::fVec() "fVec()", \ref SPxSolver::pVec() "pVec()",
210  etc.). In general, argument \p id will be the one returned by the
211  SPxPricer at the previous call to #selectEnter(). However, one can not
212  rely on this.
213  */
214  virtual void entered4(SPxId /*id*/, int /*n*/)
215  {}
216  //@}
217 
218 
219  //-------------------------------------
220  /**@name Extension */
221  //@{
222  /// \p n vectors have been added to loaded LP.
223  virtual void addedVecs (int /*n*/)
224  {}
225  /// \p n covectors have been added to loaded LP.
226  virtual void addedCoVecs(int /*n*/)
227  {}
228  //@}
229 
230  //-------------------------------------
231  /**@name Shrinking */
232  //@{
233  /// vector \p i was removed from loaded LP.
234  virtual void removedVec(int /*i*/)
235  {}
236  /// vectors given by \p perm have been removed from loaded LP.
237  virtual void removedVecs(const int* /*perm*/)
238  {}
239  /// covector \p i was removed from loaded LP.
240  virtual void removedCoVec(int /*i*/)
241  {}
242  /// covectors given by \p perm have been removed from loaded LP.
243  virtual void removedCoVecs(const int* /*perm*/)
244  {}
245  //@}
246 
247  /**@name Import/Export norms */
248  //@{
249  /// get number of available norms
250  virtual void getNdualNorms(int& nrows, int& ncols) const
251  {
252  nrows = 0;
253  ncols = 0;
254 
255  if( weightsAreSetup )
256  {
257  if( thesolver->type() == SPxSolver::LEAVE && thesolver->rep() == SPxSolver::COLUMN )
258  {
259  ncols = 0;
260  nrows = coWeights.dim();
261 
262  assert(nrows == thesolver->dim());
263  }
264  else if( thesolver->type() == SPxSolver::ENTER && thesolver->rep() == SPxSolver::ROW )
265  {
266  nrows = weights.dim();
267  ncols = coWeights.dim();
268 
269  assert(ncols == thesolver->dim());
270  assert(nrows == thesolver->coDim());
271  }
272  }
273  }
274 
275  /// export norms from pricer
276  virtual bool getDualNorms(int& nrows, int& ncols, Real* norms) const
277  {
278  nrows = 0;
279  ncols = 0;
280 
281  if( !weightsAreSetup )
282  return false;
283 
284  if( thesolver->type() == SPxSolver::LEAVE && thesolver->rep() == SPxSolver::COLUMN )
285  {
286  ncols = 0;
287  nrows = coWeights.dim();
288 
289  assert(nrows == thesolver->dim());
290 
291  for( int i = 0; i < nrows; ++i)
292  norms[i] = coWeights[i];
293  }
294  else if( thesolver->type() == SPxSolver::ENTER && thesolver->rep() == SPxSolver::ROW )
295  {
296  nrows = weights.dim();
297  ncols = coWeights.dim();
298 
299  assert(ncols == thesolver->dim());
300  assert(nrows == thesolver->coDim());
301 
302  for( int i = 0; i < nrows; ++i )
303  norms[i] = weights[i];
304 
305  for( int i = 0; i < ncols; ++i )
306  norms[nrows + i] = coWeights[i];
307  }
308  else
309  return false;
310 
311  return true;
312  }
313  /// import norms into pricer
314  virtual bool setDualNorms(int nrows, int ncols, Real* norms)
315  {
316  weightsAreSetup = false;
317 
318  if( thesolver == NULL )
319  return false;
320 
321  if( thesolver->type() == SPxSolver::LEAVE && thesolver->rep() == SPxSolver::COLUMN)
322  {
323  assert(coWeights.dim() >= nrows);
324  for( int i = 0; i < nrows; ++i )
325  coWeights[i] = norms[i];
326  weightsAreSetup = true;
327  }
328  else if( thesolver->type() == SPxSolver::ENTER && thesolver->rep() == SPxSolver::ROW)
329  {
330  assert(weights.dim() >= nrows);
331  assert(coWeights.dim() >= ncols);
332  for( int i = 0; i < nrows; ++i )
333  weights[i] = norms[i];
334  for( int i = 0; i < ncols; ++i )
335  coWeights[i] = norms[nrows + i];
336  weightsAreSetup = true;
337  }
338  else
339  return false;
340 
341  return true;
342  }
343  //@}
344 
345  //-------------------------------------
346  /**@name Debugging */
347  //@{
348  virtual bool isConsistent() const
349  {
350 #ifdef ENABLE_CONSISTENCY_CHECKS
351  return thesolver != 0;
352 #else
353  return true;
354 #endif
355  }
356  //@}
357 
358  //-------------------------------------
359  /**@name Constructors / Destructors */
360  //@{
361  /// constructor
362  explicit SPxPricer(const char* p_name)
363  : m_name(p_name)
364  , thesolver(0)
365  , theeps(0.0)
366  , weights(0)
367  , coWeights(0)
368  , weightsAreSetup(false)
369  {}
370 
371  /// copy constructor
372  SPxPricer(const SPxPricer& old)
373  : m_name(old.m_name)
374  , thesolver(old.thesolver)
375  , theeps(old.theeps)
376  , weights(old.weights)
377  , coWeights(old.coWeights)
378  , weightsAreSetup(old.weightsAreSetup)
379  {}
380 
381  /// assignment operator
383  {
384  if(this != &rhs)
385  {
386  m_name = rhs.m_name;
387  thesolver = rhs.thesolver;
388  theeps = rhs.theeps;
389  weights = rhs.weights;
390  coWeights = rhs.coWeights;
391  weightsAreSetup = rhs.weightsAreSetup;
392 
393  assert(isConsistent());
394  }
395 
396  return *this;
397  }
398 
399  /// destructor.
400  virtual ~SPxPricer()
401  {
402  m_name = 0;
403  thesolver = 0;
404  }
405 
406  /// clone function for polymorphism
407  virtual SPxPricer* clone() const = 0;
408  //@}
409 
410 };
411 
412 
413 } // namespace soplex
414 #endif // _SPXPRICER_H_
virtual void entered4(SPxId, int)
performs entering pivot.
Definition: spxpricer.h:214
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:936
int coDim() const
codimension.
Definition: spxsolver.h:941
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:406
virtual SPxId selectEnter()=0
selects Id to enter basis.
Type
Algorithmic type.
Definition: spxsolver.h:124
virtual SPxPricer * clone() const =0
clone function for polymorphism
virtual const char * getName() const
get name of pricer.
Definition: spxpricer.h:109
virtual void removedVecs(const int *)
vectors given by perm have been removed from loaded LP.
Definition: spxpricer.h:237
Representation
LP basis representation.
Definition: spxsolver.h:105
virtual bool isConsistent() const
Definition: spxpricer.h:348
virtual void setRep(SPxSolver::Representation)
sets basis representation.
Definition: spxpricer.h:161
SPxPricer & operator=(const SPxPricer &rhs)
assignment operator
Definition: spxpricer.h:382
DVector weights
vector to store pricing weights or norms
Definition: spxpricer.h:60
virtual void removedCoVec(int)
covector i was removed from loaded LP.
Definition: spxpricer.h:240
rowwise representation.
Definition: spxsolver.h:107
bool weightsAreSetup
are the weights already set up?
Definition: spxpricer.h:63
Entering Simplex.
Definition: spxsolver.h:134
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
virtual void addedCoVecs(int)
n covectors have been added to loaded LP.
Definition: spxpricer.h:226
Leaving Simplex.
Definition: spxsolver.h:143
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
virtual void addedVecs(int)
n vectors have been added to loaded LP.
Definition: spxpricer.h:223
virtual void left4(int, SPxId)
performs leaving pivot.
Definition: spxpricer.h:186
virtual void clear()
unloads LP.
Definition: spxpricer.h:123
Compare class to sort idx/val pairs, used for hypersparse pricing leaving.
Definition: spxpricer.h:74
main LP solver class
SPxSolver * thesolver
the solver
Definition: spxpricer.h:56
virtual SPxSolver * solver() const
returns loaded SPxSolver object.
Definition: spxpricer.h:129
Abstract pricer base class.Class SPxPricer is a pure virtual class defining the interface for pricer ...
Definition: spxpricer.h:46
int dim() const
Dimension of vector.
Definition: vectorbase.h:174
Type type() const
return current Type.
Definition: spxsolver.h:412
const char * m_name
name of the pricer
Definition: spxpricer.h:54
Generic QuickSort implementation.
virtual void removedCoVecs(const int *)
covectors given by perm have been removed from loaded LP.
Definition: spxpricer.h:243
Debugging, floating point type and parameter definitions.
virtual void setEpsilon(Real eps)
sets violation bound.
Definition: spxpricer.h:143
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
virtual void load(SPxSolver *p_solver)
loads LP.
Definition: spxpricer.h:117
Everything should be within this namespace.
virtual void setType(SPxSolver::Type)
sets pricing type.
Definition: spxpricer.h:154
IdxCompare compare
Definition: spxpricer.h:93
virtual bool setDualNorms(int nrows, int ncols, Real *norms)
import norms into pricer
Definition: spxpricer.h:314
virtual Real epsilon() const
returns violation bound theeps.
Definition: spxpricer.h:135
DVector coWeights
Definition: spxpricer.h:61
Real theeps
violation bound
Definition: spxpricer.h:58
SPxPricer(const char *p_name)
constructor
Definition: spxpricer.h:362
virtual void removedVec(int)
vector i was removed from loaded LP.
Definition: spxpricer.h:234
virtual int selectLeave()=0
returns selected index to leave basis.
SPxPricer(const SPxPricer &old)
copy constructor
Definition: spxpricer.h:372
virtual ~SPxPricer()
destructor.
Definition: spxpricer.h:400
const IdxElement * elements
Definition: spxpricer.h:82
columnwise representation.
Definition: spxsolver.h:108
virtual bool getDualNorms(int &nrows, int &ncols, Real *norms) const
export norms from pricer
Definition: spxpricer.h:276
virtual void getNdualNorms(int &nrows, int &ncols) const
get number of available norms
Definition: spxpricer.h:250