Scippy

SoPlex

Sequential object-oriented simPlex

spxbounds.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-2019 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 "soplex/spxdefines.h"
20 #include "soplex/spxsolver.h"
21 
22 namespace soplex
23 {
24 /** Setting up the feasiblity bound for normal primal variables is
25  straightforward. However, slack variables need some more details
26  on how we treat them. This is slightly different from usual
27  textbook versions. Let \f$l_i \le A_i^T x \le u_i\f$. This can be
28  transformed to \f$A_i^Tx + s_i = 0\f$, with \f$-u_i \le s_i \le
29  -l_i\f$. Hence, with this definition of slack variables \f$s_i\f$, we
30  can directly use vectors \f$l\f$ and \f$u\f$ as feasibility bounds.
31  */
33 {
34 
37 
38  if(rep() == ROW)
39  {
40  theURbound = rhs();
41  theLRbound = lhs();
42  }
43  else
44  {
45  theURbound = lhs();
46  theLRbound = rhs();
47  theURbound *= -1.0;
48  theLRbound *= -1.0;
49  }
50 }
51 
52 /** Setting up the basis for dual simplex requires to install upper and lower
53  feasibility bounds for dual variables (|Lbound| and |Ubound|). Here is a
54  list of how these must be set for inequalities of type \f$l \le a^Tx \le u\f$:
55 
56  \f[
57  \begin{tabular}{cccc}
58  $l$ & $u$ & |Lbound| & |Ubound| \\
59  \hline
60  $-\infty=l$ & $u=\infty$ & 0 & 0 \\
61  $-\infty<l$ & $u=\infty$ & 0 & $\infty$ \\
62  $-\infty=l$ & $u<\infty$ & $-\infty$ & 0 \\
63  \multicolumn{2}{c}{
64  $-\infty<l \ne u<\infty$} & 0 & 0 \\
65  \multicolumn{2}{c}{
66  $-\infty<l = u<\infty$} & $-\infty$ & $\infty$ \\
67  \end{tabular}
68  \f]
69  The case \f$l = -\infty\f$, \f$u = \infty\f$ occurs for unbounded primal variables.
70  Such must be treated differently from the general case.
71 
72  Given possible upper and lower bounds to a dual variable with |Status stat|,
73  this function clears the bounds according to |stat| by setting them to
74  \f$\infty\f$ or \f$-\infty\f$, respectively.
75  */
78  Real& upp,
79  Real& lw) const
80 {
81 
82  switch(stat)
83  {
86  upp = infinity;
87  lw = -infinity;
88  break;
89 
92  upp = infinity;
93  break;
94 
97  lw = -infinity;
98  break;
99 
100  default:
101  break;
102  }
103 }
104 
106 {
107 
108  assert(rep() == COLUMN);
109 
110  const SPxBasis::Desc& ds = desc();
111 
112  int i;
113 
114  for(i = 0; i < nRows(); ++i)
115  {
116  theURbound[i] = maxRowObj(i);
117  theLRbound[i] = maxRowObj(i);
118 
120  }
121 
122  for(i = 0; i < nCols(); ++i)
123  {
124  theUCbound[i] = -maxObj(i);
125  theLCbound[i] = -maxObj(i);
126 
127  // exchanged ... due to definition of slacks!
129 
130  theUCbound[i] *= -1.0;
131  theLCbound[i] *= -1.0;
132  }
133 }
134 
136 {
137 
138  assert(rep() == ROW);
139 
140  int i;
141 
142  for(i = 0; i < nRows(); ++i)
143  {
144  theURbound[i] = 0.0;
145  theLRbound[i] = 0.0;
146 
148  }
149 
150  for(i = 0; i < nCols(); ++i)
151  {
152  theUCbound[i] = 0.0;
153  theLCbound[i] = 0.0;
154 
156  }
157 }
158 
159 
160 /** This sets up the bounds for basic variables for entering simplex algorithms.
161  It requires, that all upper lower feasibility bounds have allready been
162  setup. Method |setEnterBound4Row(i, n)| does so for the |i|-th basis
163  variable being row index |n|. Equivalently, method
164  |setEnterBound4Col(i, n)| does so for the |i|-th basis variable being
165  column index |n|.
166  */
168 {
169  assert(baseId(i).isSPxRowId());
170  assert(number(SPxRowId(baseId(i))) == n);
171 
172  switch(desc().rowStatus(n))
173  {
175  theLBbound[i] = -infinity;
176  theUBbound[i] = theURbound[n];
177  break;
178 
180  theLBbound[i] = theLRbound[n];
181  theUBbound[i] = infinity;
182  break;
183 
185  theLBbound[i] = -infinity;
186  theUBbound[i] = infinity;
187  break;
188 
189  default:
190  theUBbound[i] = theURbound[n];
191  theLBbound[i] = theLRbound[n];
192  break;
193  }
194 }
195 
197 {
198  assert(baseId(i).isSPxColId());
199  assert(number(SPxColId(baseId(i))) == n);
200 
201  switch(desc().colStatus(n))
202  {
204  theLBbound[i] = -infinity;
205  theUBbound[i] = theUCbound[n];
206  break;
207 
209  theLBbound[i] = theLCbound[n];
210  theUBbound[i] = infinity;
211  break;
212 
214  theLBbound[i] = -infinity;
215  theUBbound[i] = infinity;
216  break;
217 
218  default:
219  theUBbound[i] = theUCbound[n];
220  theLBbound[i] = theLCbound[n];
221  break;
222  }
223 }
224 
226 {
227 
228  for(int i = 0; i < dim(); ++i)
229  {
230  SPxId base_id = baseId(i);
231 
232  if(base_id.isSPxRowId())
233  setEnterBound4Row(i, number(SPxRowId(base_id)));
234  else
235  setEnterBound4Col(i, number(SPxColId(base_id)));
236  }
237 }
238 
239 
240 /** This sets up the bounds for basic variables for leaving simplex algorithms.
241  While method |setLeaveBound4Row(i,n)| does so for the |i|-th basic variable
242  being the |n|-th row, |setLeaveBound4Col(i,n)| does so for the |i|-th basic
243  variable being the |n|-th column.
244  */
246 {
247  assert(baseId(i).isSPxRowId());
248  assert(number(SPxRowId(baseId(i))) == n);
249 
250  switch(desc().rowStatus(n))
251  {
253  theLBbound[i] = -infinity;
254  theUBbound[i] = -maxRowObj(n);
255  break;
256 
258  theLBbound[i] = -maxRowObj(n);
259  theUBbound[i] = infinity;
260  break;
261 
263  theLBbound[i] = -infinity;
264  theUBbound[i] = infinity;
265  break;
266 
268  theLBbound[i] = -maxRowObj(n);
269  theUBbound[i] = -maxRowObj(n);
270  break;
271 
272  default:
273  assert(rep() == COLUMN);
274  theLBbound[i] = -rhs(n); // slacks !
275  theUBbound[i] = -lhs(n); // slacks !
276  break;
277  }
278 }
279 
281 {
282 
283  assert(baseId(i).isSPxColId());
284  assert(number(SPxColId(baseId(i))) == n);
285 
286  switch(desc().colStatus(n))
287  {
289  theLBbound[i] = -infinity;
290  theUBbound[i] = 0;
291  break;
292 
294  theLBbound[i] = 0;
295  theUBbound[i] = infinity;
296  break;
297 
299  theLBbound[i] = -infinity;
300  theUBbound[i] = infinity;
301  break;
302 
304  theLBbound[i] = theUBbound[i] = 0;
305  break;
306 
307  default:
308  theUBbound[i] = SPxLP::upper(n);
309  theLBbound[i] = SPxLP::lower(n);
310  break;
311  }
312 }
313 
315 {
316 
317  for(int i = 0; i < dim(); ++i)
318  {
319  SPxId base_id = baseId(i);
320 
321  if(base_id.isSPxRowId())
322  setLeaveBound4Row(i, number(SPxRowId(base_id)));
323  else
324  setLeaveBound4Col(i, number(SPxColId(base_id)));
325  }
326 }
327 
329 {
330 
331  if(type() == ENTER)
332  {
333  Real viol_max = (1 + iterCount) * entertol();
334  int nlinesprinted = 0;
335  int m = dim();
336 
337  for(int i = 0; i < m; ++i)
338  {
339  // Minor bound violations happen frequently, so print these
340  // warnings only with verbose level INFO2 and higher.
341  if((*theFvec)[i] > theUBbound[i] + viol_max) //@ && theUBbound[i] != theLBbound[i])
342  {
343  MSG_INFO2((*spxout), (*spxout) << "WBOUND01 Invalid upper enter bound " << i
344  << " Fvec: " << (*theFvec)[i]
345  << " UBbound: " << theUBbound[i]
346  << " tolerance: " << viol_max
347  << " violation: " << (*theFvec)[i] - theUBbound[i] << std::endl;)
348  nlinesprinted++;
349  }
350 
351  if((*theFvec)[i] < theLBbound[i] - viol_max) //@ && theUBbound[i] != theLBbound[i])
352  {
353  MSG_INFO2((*spxout), (*spxout) << "WBOUND02 Invalid lower enter bound " << i
354  << " Fvec: " << (*theFvec)[i]
355  << " LBbound: " << theLBbound[i]
356  << " tolerance: " << viol_max
357  << " violation: " << theLBbound[i] - (*theFvec)[i] << std::endl;)
358  nlinesprinted++;
359  }
360 
361  if(nlinesprinted >= 3)
362  {
363  MSG_INFO2((*spxout), (*spxout) <<
364  "WBOUND10 suppressing further warnings of type WBOUND{01,02} in this round" << std::endl);
365  break;
366  }
367  }
368  }
369  else
370  {
371  Real viol_max = (1 + iterCount) * leavetol();
372  int nlinesprinted = 0;
373  int m = dim();
374  int n = coDim();
375 
376  for(int i = 0; i < m; ++i)
377  {
378  if((*theCoPvec)[i] > (*theCoUbound)[i] + viol_max) // && (*theCoUbound)[i] != (*theCoLbound)[i])
379  {
380  MSG_INFO2((*spxout), (*spxout) << "WBOUND03 Invalid upper cobound " << i
381  << " CoPvec: " << (*theCoPvec)[i]
382  << " CoUbound: " << (*theCoUbound)[i]
383  << " tolerance: " << viol_max
384  << " violation: " << (*theCoPvec)[i] - (*theCoUbound)[i] << std::endl;)
385  nlinesprinted++;
386  }
387 
388  if((*theCoPvec)[i] < (*theCoLbound)[i] - viol_max) // && (*theCoUbound)[i] != (*theCoLbound)[i])
389  {
390  MSG_INFO2((*spxout), (*spxout) << "WBOUND04 Invalid lower cobound " << i
391  << " CoPvec: " << (*theCoPvec)[i]
392  << " CoLbound: " << (*theCoLbound)[i]
393  << " tolerance: " << viol_max
394  << " violation: " << (*theCoLbound)[i] - (*theCoPvec)[i] << std::endl;)
395  nlinesprinted++;
396  }
397 
398  if(nlinesprinted >= 3)
399  {
400  MSG_INFO2((*spxout), (*spxout) <<
401  "WBOUND11 suppressing further warnings of type WBOUND{03,04} in this round" << std::endl);
402  break;
403  }
404  }
405 
406  nlinesprinted = 0;
407 
408  for(int i = 0; i < n; ++i)
409  {
410  if((*thePvec)[i] > (*theUbound)[i] + viol_max) // && (*theUbound)[i] != (*theLbound)[i])
411  {
412  MSG_INFO2((*spxout), (*spxout) << "WBOUND05 Invalid upper bound " << i
413  << " Pvec: " << (*thePvec)[i]
414  << " Ubound: " << (*theUbound)[i]
415  << " tolerance: " << viol_max
416  << " violation: " << (*thePvec)[i] - (*theUbound)[i] << std::endl;)
417  nlinesprinted++;
418  }
419 
420  if((*thePvec)[i] < (*theLbound)[i] - viol_max) // && (*theUbound)[i] != (*theLbound)[i])
421  {
422  MSG_INFO2((*spxout), (*spxout) << "WBOUND06 Invalid lower bound " << i
423  << " Pvec: " << (*thePvec)[i]
424  << " Lbound: " << (*theLbound)[i]
425  << " tolerance: " << viol_max
426  << " violation: " << (*theLbound)[i] - (*thePvec)[i] << std::endl;)
427  nlinesprinted++;
428  }
429 
430  if(nlinesprinted >= 3)
431  {
432  MSG_INFO2((*spxout), (*spxout) <<
433  "WBOUND12 suppressing further warnings of type WBOUND{05,06} in this round" << std::endl);
434  break;
435  }
436  }
437  }
438 }
439 } // namespace soplex
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:221
void setEnterBound4Col(int, int)
Definition: spxbounds.cpp:196
primal variable is fixed to both bounds
Definition: spxbasis.h:190
const VectorBase< Real > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:461
Desc::Status dualColStatus(int i) const
dual Status for the i&#39;th column variable of the loaded LP.
Definition: spxbasis.cpp:69
SPxOut * spxout
message handler
Definition: spxsolver.h:463
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
DVector * theUbound
Upper bound for vars.
Definition: spxsolver.h:375
void testBounds() const
Definition: spxbounds.cpp:328
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:796
DVector * theCoUbound
Upper bound for covars.
Definition: spxsolver.h:377
Status & rowStatus(int i)
Definition: spxbasis.h:239
void clearDualBounds(SPxBasis::Desc::Status, Real &, Real &) const
Definition: spxbounds.cpp:76
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:527
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1075
void setPrimalBounds()
setup feasibility bounds for entering algorithm
Definition: spxbounds.cpp:32
void setLeaveBound4Col(int i, int n)
Definition: spxbounds.cpp:280
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
rowwise representation.
Definition: spxsolver.h:107
Desc::Status dualRowStatus(int i) const
dual Status for the i&#39;th row variable of the loaded LP.
Definition: spxbasis.cpp:46
dual variable is left free, but unset
Definition: spxbasis.h:191
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:152
Entering Simplex.
Definition: spxsolver.h:134
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
double Real
Definition: spxdefines.h:218
DVector * theLbound
Lower bound for vars.
Definition: spxsolver.h:376
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:789
UpdateVector * thePvec
Definition: spxsolver.h:368
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:120
virtual void setLeaveBounds()
Definition: spxbounds.cpp:314
dual variable is set to its upper bound
Definition: spxbasis.h:192
DVector theLBbound
Lower Basic Feasibility bound.
Definition: spxsolver.h:357
main LP solver class
primal variable is left free, but unset
Definition: spxbasis.h:189
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:255
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:346
const VectorBase< R > & maxRowObj() const
Definition: spxlpbase.h:300
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:504
DVector theUBbound
Upper Basic Feasibility bound.
Definition: spxsolver.h:356
DVector * theCoLbound
Lower bound for covars.
Definition: spxsolver.h:378
Debugging, floating point type and parameter definitions.
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:347
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:348
void setDualColBounds()
Definition: spxbounds.cpp:105
Everything should be within this namespace.
UpdateVector * theFvec
Definition: spxsolver.h:362
primal variable is set to its lower bound
Definition: spxbasis.h:187
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:434
void setEnterBound4Row(int, int)
Definition: spxbounds.cpp:167
DVector theLCbound
Lower Column Feasibility bound.
Definition: spxsolver.h:349
void setDualRowBounds()
Definition: spxbounds.cpp:135
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:161
dual variable is set to its lower bound
Definition: spxbasis.h:193
Type type() const
return current Type.
Definition: spxsolver.h:512
int coDim() const
codimension.
Definition: spxsolver.h:1080
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:158
virtual void setEnterBounds()
Definition: spxbounds.cpp:225
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
UpdateVector * theCoPvec
Definition: spxsolver.h:366
int iterCount
number of calls to change() since last manipulation
Definition: spxbasis.h:388
void setLeaveBound4Row(int i, int n)
Definition: spxbounds.cpp:245
const VectorBase< Real > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:488
const Desc & desc() const
Definition: spxbasis.h:464
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:506
columnwise representation.
Definition: spxsolver.h:108