Scippy

SoPlex

Sequential object-oriented simPlex

spxvecs.cpp
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-2017 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 #include <assert.h>
17 #include <iostream>
18 
19 #include "spxdefines.h"
20 #include "spxsolver.h"
21 #include "exceptions.h"
22 
23 namespace soplex
24 {
25 /** Initialize Vectors
26 
27  Computing the right hand side vector for the feasibility vector depends on
28  the chosen representation and type of the basis.
29 
30  In columnwise case, |theFvec| = \f$x_B = A_B^{-1} (- A_N x_N)\f$, where \f$x_N\f$
31  are either upper or lower bounds for the nonbasic variables (depending on
32  the variables |Status|). If these values remain unchanged throughout the
33  simplex algorithm, they may be taken directly from LP. However, in the
34  entering type algorith they are changed and, hence, retreived from the
35  column or row upper or lower bound vectors.
36 
37  In rowwise case, |theFvec| = \f$\pi^T_B = (c^T - 0^T A_N) A_B^{-1}\f$. However,
38  this applies only to leaving type algorithm, where no bounds on dual
39  variables are altered. In entering type algorithm they are changed and,
40  hence, retreived from the column or row upper or lower bound vectors.
41  */
43 {
44 
45  if (rep() == COLUMN)
46  {
47  theFrhs->clear();
48 
49  if (type() == LEAVE)
50  {
52 
53  for(int i = 0; i < nRows(); i++)
54  {
55  Real x;
56 
58 
59  if (!isBasic(stat))
60  {
61  switch (stat)
62  {
63  // columnwise cases:
65  continue;
66 
68  assert(EQ(lhs(i), rhs(i)));
69  //lint -fallthrough
71  x = rhs(i);
72  break;
74  x = lhs(i);
75  break;
76 
77  default:
78  MSG_ERROR( std::cerr << "ESVECS01 ERROR: "
79  << "inconsistent basis must not happen!"
80  << std::endl; )
81  throw SPxInternalCodeException("XSVECS01 This should never happen.");
82  }
83  assert(x < infinity);
84  assert(x > -infinity);
85  (*theFrhs)[i] += x; // slack !
86  }
87  }
88  }
89  else
90  {
93  }
94  }
95  else
96  {
97  assert(rep() == ROW);
98 
99  if (type() == ENTER)
100  {
101  theFrhs->clear();
104  *theFrhs += maxObj();
105  }
106  else
107  {
108  ///@todo put this into a separate method
109  *theFrhs = maxObj();
110  const SPxBasis::Desc& ds = desc();
111  for (int i = 0; i < nRows(); ++i)
112  {
113  SPxBasis::Desc::Status stat = ds.rowStatus(i);
114 
115  if (!isBasic(stat))
116  {
117  Real x;
118 
119  switch (stat)
120  {
122  continue;
123 
127  x = maxRowObj(i);
128  break;
129 
130  default:
131  assert(lhs(i) <= -infinity && rhs(i) >= infinity);
132  x = 0.0;
133  break;
134  }
135  assert(x < infinity);
136  assert(x > -infinity);
137  // assert(x == 0.0);
138 
139  if (x != 0.0)
140  theFrhs->multAdd(x, vector(i));
141  }
142  }
143  }
144  }
145 }
146 
148 {
149 
150  assert(rep() == COLUMN);
151  assert(type() == LEAVE);
152 
153  for (int i = 0; i < nCols(); ++i)
154  {
156 
157  if (!isBasic(stat))
158  {
159  Real x;
160 
161  switch (stat)
162  {
163  // columnwise cases:
165  continue;
166 
167  case (SPxBasis::Desc::P_FIXED) :
168  assert(EQ(SPxLP::lower(i), SPxLP::upper(i)));
169  //lint -fallthrough
171  x = SPxLP::upper(i);
172  break;
174  x = SPxLP::lower(i);
175  break;
176 
177  default:
178  MSG_ERROR( std::cerr << "ESVECS02 ERROR: "
179  << "inconsistent basis must not happen!"
180  << std::endl; )
181  throw SPxInternalCodeException("XSVECS02 This should never happen.");
182  }
183  assert(x < infinity);
184  assert(x > -infinity);
185 
186  if (x != 0.0)
187  theFrhs->multAdd(-x, vector(i));
188  }
189  }
190 }
191 
192 
193 /** This methods subtracts \f$A_N x_N\f$ or \f$\pi_N^T A_N\f$ from |theFrhs| as
194  specified by the |Status| of all nonbasic variables. The values of \f$x_N\f$ or
195  \f$\pi_N\f$ are taken from the passed arrays.
196  */
198  const Vector& ufb, ///< upper feasibility bound for variables
199  const Vector& lfb) ///< lower feasibility bound for variables
200 {
201 
202  const SPxBasis::Desc& ds = desc();
203 
204  for (int i = 0; i < coDim(); ++i)
205  {
206  SPxBasis::Desc::Status stat = ds.status(i);
207 
208  if (!isBasic(stat))
209  {
210  Real x;
211 
212  switch (stat)
213  {
217  continue;
218 
221  x = ufb[i];
222  break;
225  x = lfb[i];
226  break;
227 
228  case (SPxBasis::Desc::P_FIXED) :
229  assert(EQ(lfb[i], ufb[i]));
230  //lint -fallthrough
232  x = lfb[i];
233  break;
234 
235  default:
236  MSG_ERROR( std::cerr << "ESVECS03 ERROR: "
237  << "inconsistent basis must not happen!"
238  << std::endl; )
239  throw SPxInternalCodeException("XSVECS04 This should never happen.");
240  }
241  assert(x < infinity);
242  assert(x > -infinity);
243 
244  if (x != 0.0)
245  theFrhs->multAdd(-x, vector(i));
246  }
247  }
248 }
249 
250 /** This methods subtracts \f$A_N x_N\f$ or \f$\pi_N^T A_N\f$ from |theFrhs| as
251  specified by the |Status| of all nonbasic variables. The values of
252  \f$x_N\f$ or \f$\pi_N\f$ are taken from the passed arrays.
253  */
255  Vector& coufb, ///< upper feasibility bound for covariables
256  Vector& colfb) ///< lower feasibility bound for covariables
257 {
258  const SPxBasis::Desc& ds = desc();
259 
260  for(int i = 0; i < dim(); ++i)
261  {
262  SPxBasis::Desc::Status stat = ds.coStatus(i);
263 
264  if (!isBasic(stat))
265  {
266  Real x;
267 
268  switch (stat)
269  {
273  continue;
274 
275  case SPxBasis::Desc::P_ON_LOWER : // negative slack bounds!
277  x = coufb[i];
278  break;
279  case SPxBasis::Desc::P_ON_UPPER : // negative slack bounds!
281  x = colfb[i];
282  break;
285 
286  if (colfb[i] != coufb[i])
287  {
288  MSG_WARNING( (*spxout), (*spxout) << "WSVECS04 Frhs2[" << i << "]: " << stat << " "
289  << colfb[i] << " " << coufb[i]
290  << " shouldn't be" << std::endl; )
291  if( isZero(colfb[i]) || isZero(coufb[i]) )
292  colfb[i] = coufb[i] = 0.0;
293  else
294  {
295  Real mid = (colfb[i] + coufb[i]) / 2.0;
296  colfb[i] = coufb[i] = mid;
297  }
298  }
299  assert(EQ(colfb[i], coufb[i]));
300  x = colfb[i];
301  break;
302 
303  default:
304  MSG_ERROR( std::cerr << "ESVECS05 ERROR: "
305  << "inconsistent basis must not happen!"
306  << std::endl; )
307  throw SPxInternalCodeException("XSVECS05 This should never happen.");
308  }
309  assert(x < infinity);
310  assert(x > -infinity);
311 
312  (*theFrhs)[i] -= x; // This is a slack, so no need to multiply a vector.
313  }
314  }
315 }
316 
317 /** Computing the right hand side vector for |theCoPvec| depends on
318  the type of the simplex algorithm. In entering algorithms, the
319  values are taken from the inequality's right handside or the
320  column's objective value.
321 
322  In contrast to this leaving algorithms take the values from vectors
323  |theURbound| and so on.
324 
325  We reflect this difference by providing two pairs of methods
326  |computeEnterCoPrhs(n, stat)| and |computeLeaveCoPrhs(n, stat)|. The first
327  pair operates for entering algorithms, while the second one is intended for
328  leaving algorithms. The return value of these methods is the right hand
329  side value for the \f$n\f$-th row or column id, respectively, if it had the
330  passed |Status| for both.
331 
332  Both methods are again split up into two methods named |...4Row(i,n)| and
333  |...4Col(i,n)|, respectively. They do their job for the |i|-th basis
334  variable, being the |n|-th row or column.
335 */
337 {
338  assert(baseId(i).isSPxRowId());
339  assert(number(SPxRowId(baseId(i))) == n);
340 
341  switch (desc().rowStatus(n))
342  {
343  // rowwise representation:
345  assert(lhs(n) > -infinity);
346  assert(EQ(rhs(n), lhs(n)));
347  //lint -fallthrough
349  assert(rep() == ROW);
350  assert(rhs(n) < infinity);
351  (*theCoPrhs)[i] = rhs(n);
352  break;
354  assert(rep() == ROW);
355  assert(lhs(n) > -infinity);
356  (*theCoPrhs)[i] = lhs(n);
357  break;
358 
359  // columnwise representation:
360  // slacks must be left 0!
361  default:
362  (*theCoPrhs)[i] = maxRowObj(n);
363  break;
364  }
365 }
366 
368 {
369  assert(baseId(i).isSPxColId());
370  assert(number(SPxColId(baseId(i))) == n);
371  switch (desc().colStatus(n))
372  {
373  // rowwise representation:
375  assert(EQ(SPxLP::upper(n), SPxLP::lower(n)));
376  assert(SPxLP::lower(n) > -infinity);
377  //lint -fallthrough
379  assert(rep() == ROW);
380  assert(SPxLP::upper(n) < infinity);
381  (*theCoPrhs)[i] = SPxLP::upper(n);
382  break;
384  assert(rep() == ROW);
385  assert(SPxLP::lower(n) > -infinity);
386  (*theCoPrhs)[i] = SPxLP::lower(n);
387  break;
388 
389  // columnwise representation:
395  assert(rep() == COLUMN);
396  (*theCoPrhs)[i] = maxObj(n);
397  break;
398 
399  default: // variable left 0
400  (*theCoPrhs)[i] = 0;
401  break;
402  }
403 }
404 
406 {
407  assert(type() == ENTER);
408 
409  for (int i = dim() - 1; i >= 0; --i)
410  {
411  SPxId l_id = baseId(i);
412  if (l_id.isSPxRowId())
414  else
416  }
417 }
418 
420 {
421  assert(baseId(i).isSPxRowId());
422  assert(number(SPxRowId(baseId(i))) == n);
423  switch (desc().rowStatus(n))
424  {
427  assert(theLRbound[n] > -infinity);
428  assert(EQ(theURbound[n], theLRbound[n]));
429  //lint -fallthrough
432  assert(theURbound[n] < infinity);
433  (*theCoPrhs)[i] = theURbound[n];
434  break;
435 
438  assert(theLRbound[n] > -infinity);
439  (*theCoPrhs)[i] = theLRbound[n];
440  break;
441 
442  default:
443  (*theCoPrhs)[i] = maxRowObj(n);
444  break;
445  }
446 }
447 
449 {
450  assert(baseId(i).isSPxColId());
451  assert(number(SPxColId(baseId(i))) == n);
452  switch (desc().colStatus(n))
453  {
457  assert(theLCbound[n] > -infinity);
458  assert(EQ(theUCbound[n], theLCbound[n]));
459  //lint -fallthrough
462  assert(theUCbound[n] < infinity);
463  (*theCoPrhs)[i] = theUCbound[n];
464  break;
467  assert(theLCbound[n] > -infinity);
468  (*theCoPrhs)[i] = theLCbound[n];
469  break;
470 
471  default:
472  (*theCoPrhs)[i] = maxObj(n);
473  // (*theCoPrhs)[i] = 0;
474  break;
475  }
476 }
477 
479 {
480  assert(type() == LEAVE);
481 
482  for (int i = dim() - 1; i >= 0; --i)
483  {
484  SPxId l_id = baseId(i);
485  if (l_id.isSPxRowId())
487  else
489  }
490 }
491 
492 
493 /** When computing the copricing vector, we expect the pricing vector to be
494  setup correctly. Then computing the copricing vector is nothing but
495  computing all scalar products of the pricing vector with the vectors of the
496  LPs constraint matrix.
497  */
499 {
500  int i;
501 
502  for (i = coDim() - 1; i >= 0; --i)
503  (*thePvec)[i] = vector(i) * (*theCoPvec);
504 }
505 
507 {
508  SSVector& p = thePvec->delta();
509  SSVector& c = theCoPvec->delta();
510 
511  if (c.isSetup())
512  {
513  if (c.size() < 0.95 * theCoPvec->dim())
515  else
516  p.assign2product(c, *thevectors);
517  }
518  else
519  {
521  }
522 
523  p.setup();
524 }
525 
527 {
528  theCoPvec->update();
529  if (pricing() == FULL)
530  {
531  // thePvec->delta().setup();
532  thePvec->update();
533  }
534 }
535 } // namespace soplex
const VectorBase< Real > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
Status & coStatus(int i)
Definition: spxbasis.h:284
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:120
primal variable is fixed to both bounds
Definition: spxbasis.h:190
primal or dual variable is undefined
Definition: spxbasis.h:195
const VectorBase< Real > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:456
SPxOut * spxout
message handler
Definition: spxsolver.h:436
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
DVector * theUbound
Upper bound for vars.
Definition: spxsolver.h:357
Pricing pricing() const
return current Pricing.
Definition: spxsolver.h:490
DVector * theCoUbound
Upper bound for covars.
Definition: spxsolver.h:359
Exception classes for SoPlex.
Status & rowStatus(int i)
Definition: spxbasis.h:239
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:522
virtual void computeFrhsXtra()
Definition: spxvecs.cpp:147
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1056
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
virtual void doPupdate(void)
Definition: spxvecs.cpp:526
rowwise representation.
Definition: spxsolver.h:107
virtual void computeLeaveCoPrhs()
compute theCoPrhs for leaving Simplex.
Definition: spxvecs.cpp:478
dual variable is left free, but unset
Definition: spxbasis.h:191
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
Entering Simplex.
Definition: spxsolver.h:134
SSVectorBase< R > & assign2productAndSetup(const SVSetBase< S > &A, SSVectorBase< T > &x)
Assigns SSVectorBase to thereby setting up x.
Definition: basevectors.h:824
primal variable is set to its upper bound
Definition: spxbasis.h:188
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
Leaving Simplex.
Definition: spxsolver.h:143
double Real
Definition: spxdefines.h:218
DVector * theFrhs
Definition: spxsolver.h:342
SSVectorBase< R > & assign2product(const SSVectorBase< S > &x, const SVSetBase< T > &A)
Assigns to SSVectorBase.
Definition: basevectors.h:571
DVector * theLbound
Lower bound for vars.
Definition: spxsolver.h:358
UpdateVector * thePvec
Definition: spxsolver.h:350
void update()
Perform the update.
Definition: updatevector.h:147
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:114
const SVSet * thecovectors
the LP coVectors according to representation
Definition: spxsolver.h:320
void computeEnterCoPrhs4Col(int i, int n)
Definition: spxvecs.cpp:367
dual variable is set to its upper bound
Definition: spxbasis.h:192
main LP solver class
virtual void setupPupdate(void)
Definition: spxvecs.cpp:506
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1244
primal variable is left free, but unset
Definition: spxbasis.h:189
const VectorBase< Real > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:328
const VectorBase< Real > & maxRowObj() const
Definition: spxlpbase.h:297
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:503
DVector * theCoLbound
Lower bound for covars.
Definition: spxsolver.h:360
Debugging, floating point type and parameter definitions.
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
Definition: spxdefines.h:380
Full pricing.
Definition: spxsolver.h:160
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:329
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:330
void computeLeaveCoPrhs4Col(int i, int n)
Definition: spxvecs.cpp:448
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:410
void computeEnterCoPrhs4Row(int i, int n)
Definition: spxvecs.cpp:336
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:199
Everything should be within this namespace.
void computeLeaveCoPrhs4Row(int i, int n)
Definition: spxvecs.cpp:419
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:116
primal variable is set to its lower bound
Definition: spxbasis.h:187
const VectorBase< Real > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:429
void setup()
Initializes nonzero indices for elements with absolute values above epsilon and sets all other elemen...
Definition: ssvectorbase.h:132
DVector theLCbound
Lower Column Feasibility bound.
Definition: spxsolver.h:331
void computeFrhs()
compute feasibility vector from scratch.
Definition: spxvecs.cpp:42
void clear()
Set vector to 0.
Definition: vectorbase.h:260
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:160
dual variable is set to its lower bound
Definition: spxbasis.h:193
Type type() const
return current Type.
Definition: spxsolver.h:484
int coDim() const
codimension.
Definition: spxsolver.h:1061
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
const SVSet * thevectors
the LP vectors according to representation
Definition: spxsolver.h:319
dual variable has two bounds
Definition: spxbasis.h:194
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
virtual void computeEnterCoPrhs()
compute theCoPrhs for entering Simplex.
Definition: spxvecs.cpp:405
bool isZero(Real a, Real eps=Param::epsilon())
returns true iff |a| <= eps
Definition: spxdefines.h:416
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1138
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
Status & status(int i)
Definition: spxbasis.h:269
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:498
UpdateVector * theCoPvec
Definition: spxsolver.h:348
void computeFrhs2(Vector &, Vector &)
Definition: spxvecs.cpp:254
Status
Status of a variable.
Definition: spxbasis.h:185
const VectorBase< Real > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
virtual void computeFrhs1(const Vector &, const Vector &)
Definition: spxvecs.cpp:197
const Desc & desc() const
Definition: spxbasis.h:463
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:478
columnwise representation.
Definition: spxsolver.h:108
SSVectorBase< R > & assign2product4setup(const SVSetBase< S > &A, const SSVectorBase< T > &x)
Assigns SSVectorBase to for a setup x.
Definition: basevectors.h:602