Scippy

SoPlex

Sequential object-oriented simPlex

spxequilisc.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 /**@file spxequilisc.cpp
17  * @brief Equilibrium row/column scaling.
18  */
19 #include <assert.h>
20 
21 #include "soplex/spxequilisc.h"
22 #include "soplex/spxout.h"
23 #include "soplex/spxlpbase.h"
24 #include "soplex/spxlp.h"
25 #include "soplex.h"
26 
27 namespace soplex
28 {
29 static const char* makename(bool doBoth)
30 {
31  return doBoth ? "bi-Equilibrium" : "uni-Equilibrium";
32 }
33 
34 /// maximum ratio between absolute biggest and smallest element in any scaled row/column.
35 static Real maxPrescaledRatio(const SPxLP& lp, const std::vector<Real>& coScaleval, bool rowRatio)
36 {
37  Real pmax = 0.0;
38  const int n = rowRatio ? lp.nRows() : lp.nCols();
39 
40  for(int i = 0; i < n; ++i)
41  {
42  const SVector& vec = rowRatio ? lp.rowVector(i) : lp.colVector(i);
43  Real mini = infinity;
44  Real maxi = 0.0;
45 
46  for(int j = 0; j < vec.size(); ++j)
47  {
48  assert(vec.index(j) >= 0);
49  const Real x = spxAbs(vec.value(j)) * coScaleval[unsigned(vec.index(j))];
50 
51  if(isZero(x))
52  continue;
53 
54  if(x < mini)
55  mini = x;
56 
57  if(x > maxi)
58  maxi = x;
59  }
60 
61  if(mini == infinity)
62  continue;
63 
64  const Real p = maxi / mini;
65 
66  if(p > pmax)
67  pmax = p;
68  }
69 
70  return pmax;
71 }
72 
73 
74 void SPxEquiliSC::computeEquiExpVec(const SVSet* vecset, const DataArray<int>& coScaleExp,
75  DataArray<int>& scaleExp)
76 {
77  assert(vecset != nullptr);
78 
79  for(int i = 0; i < vecset->num(); ++i)
80  {
81  const SVector& vec = (*vecset)[i];
82 
83  Real maxi = 0.0;
84 
85  for(int j = 0; j < vec.size(); ++j)
86  {
87  const Real x = spxAbs(spxLdexp(vec.value(j), coScaleExp[vec.index(j)]));
88 
89  if(GT(x, maxi))
90  maxi = x;
91  }
92 
93  // empty rows/cols are possible
94  if(maxi == 0.0)
95  maxi = 1.0;
96 
97  assert(maxi > 0.0);
98 
99  spxFrexp(1.0 / maxi, &(scaleExp[i]));
100 
101  scaleExp[i] -= 1;
102  }
103 }
104 
105 void SPxEquiliSC::computeEquiExpVec(const SVSet* vecset, const std::vector<Real>& coScaleVal,
106  DataArray<int>& scaleExp)
107 {
108  assert(vecset != nullptr);
109 
110  for(int i = 0; i < vecset->num(); ++i)
111  {
112  const SVector& vec = (*vecset)[i];
113 
114  Real maxi = 0.0;
115 
116  for(int j = 0; j < vec.size(); ++j)
117  {
118  assert(vec.index(j) >= 0);
119  const Real x = spxAbs(vec.value(j) * coScaleVal[unsigned(vec.index(j))]);
120 
121  if(GT(x, maxi))
122  maxi = x;
123  }
124 
125  // empty rows/cols are possible
126  if(maxi == 0.0)
127  maxi = 1.0;
128 
129  assert(maxi > 0.0);
130 
131  spxFrexp(1.0 / maxi, &(scaleExp[i]));
132 
133  scaleExp[i] -= 1;
134  }
135 }
136 
138  const std::vector<Real>& preRowscale, const std::vector<Real>& preColscale,
139  DataArray<int>& rowscaleExp, DataArray<int>& colscaleExp)
140 {
141  const Real colratio = maxPrescaledRatio(lp, preRowscale, false);
142  const Real rowratio = maxPrescaledRatio(lp, preColscale, true);
143 
144  const bool colFirst = colratio < rowratio;
145 
146  // see SPxEquiliSC::scale for reason behind this branch
147  if(colFirst)
148  {
149  computeEquiExpVec(lp.colSet(), preRowscale, colscaleExp);
150  computeEquiExpVec(lp.rowSet(), colscaleExp, rowscaleExp);
151  }
152  else
153  {
154  computeEquiExpVec(lp.rowSet(), preColscale, rowscaleExp);
155  computeEquiExpVec(lp.colSet(), rowscaleExp, colscaleExp);
156  }
157 }
158 
159 
161  : SPxScaler(makename(doBoth), false, doBoth)
162 {}
163 
165  : SPxScaler(old)
166 {}
167 
169 {
170  if(this != &rhs)
171  {
173  }
174 
175  return *this;
176 }
177 
178 
179 void SPxEquiliSC::scale(SPxLP& lp, bool persistent)
180 {
181 
182  MSG_INFO1((*spxout), (*spxout) << "Equilibrium scaling LP" << (persistent ? " (persistent)" : "") <<
183  std::endl;)
184 
185  setup(lp);
186 
187  /* We want to do the direction first, which has a lower maximal ratio,
188  * since the lowest value in the scaled matrix is bounded from below by
189  * the inverse of the maximum ratio of the direction that is done first
190  * Example:
191  *
192  * Rowratio
193  * 0.1 1 10
194  * 10 1 10
195  *
196  * Colratio 100 1
197  *
198  * Row first => Col next =>
199  * 0.1 1 0.1 1
200  * 1 0.1 1 0.1
201  *
202  * Col first => Row next =>
203  * 0.01 1 0.01 1
204  * 1 1 1 1
205  *
206  */
207  Real colratio = maxColRatio(lp);
208  Real rowratio = maxRowRatio(lp);
209 
210  bool colFirst = colratio < rowratio;
211 
212  MSG_INFO2((*spxout), (*spxout) << "before scaling:"
213  << " min= " << lp.minAbsNzo()
214  << " max= " << lp.maxAbsNzo()
215  << " col-ratio= " << colratio
216  << " row-ratio= " << rowratio
217  << std::endl;)
218 
219  if(colFirst)
220  {
222 
223  if(m_doBoth)
225  }
226  else
227  {
229 
230  if(m_doBoth)
232  }
233 
234  /* scale */
235  applyScaling(lp);
236 
237  MSG_INFO3((*spxout), (*spxout) << "Row scaling min= " << minAbsRowscale()
238  << " max= " << maxAbsRowscale()
239  << std::endl
240  << "Col scaling min= " << minAbsColscale()
241  << " max= " << maxAbsColscale()
242  << std::endl;)
243 
244  MSG_INFO2((*spxout), (*spxout) << "after scaling: "
245  << " min= " << lp.minAbsNzo(false)
246  << " max= " << lp.maxAbsNzo(false)
247  << " col-ratio= " << maxColRatio(lp)
248  << " row-ratio= " << maxRowRatio(lp)
249  << std::endl;)
250 
251 }
252 
253 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:4102
virtual void setup(SPxLPBase< Real > &lp)
clear and setup scaling arrays in the LP
Definition: spxscaler.cpp:129
virtual R minAbsNzo(bool unscaled=true) const
Absolute smallest non-zero element in (possibly scaled) LP.
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
static const char * makename(bool doBoth)
Definition: spxequilisc.cpp:29
int size() const
Number of used indices.
Definition: svectorbase.h:153
virtual Real maxRowRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any row.
Definition: spxscaler.cpp:866
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:253
SPxEquiliSC(bool doBoth=true)
default constructor (this scaler makes no use of inherited member m_colFirst)
Saving LPs in a form suitable for SoPlex.
Real spxFrexp(Real y, int *exp)
Definition: spxdefines.h:354
Wrapper for different output streams and verbosity levels.
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:152
DataArray< int > * m_activeColscaleExp
pointer to currently active column scaling factors
Definition: spxscaler.h:84
virtual void applyScaling(SPxLPBase< Real > &lp)
applies m_colscale and m_rowscale to the lp.
Definition: spxscaler.cpp:177
Real spxLdexp(Real x, int exp)
returns x * 2^exp
Definition: spxdefines.h:348
double Real
Definition: spxdefines.h:218
SPxOut * spxout
message handler
Definition: spxscaler.h:88
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:400
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:235
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:120
virtual Real maxAbsColscale() const
absolute biggest column scaling factor
Definition: spxscaler.cpp:781
virtual Real minAbsColscale() const
absolute smallest column scaling factor
Definition: spxscaler.cpp:768
Preconfigured SoPlex LP solver.
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:122
DataArray< int > * m_activeRowscaleExp
pointer to currently active row scaling factors
Definition: spxscaler.h:85
virtual Real minAbsRowscale() const
absolute smallest row scaling factor
Definition: spxscaler.cpp:795
static Real maxPrescaledRatio(const SPxLP &lp, const std::vector< Real > &coScaleval, bool rowRatio)
maximum ratio between absolute biggest and smallest element in any scaled row/column.
Definition: spxequilisc.cpp:35
static void computePostequiExpVecs(const SPxLPBase< Real > &lp, const std::vector< Real > &preRowscale, const std::vector< Real > &preColscale, DataArray< int > &rowscaleExp, DataArray< int > &colscaleExp)
compute equilibrium scaling rounded to power of 2 for existing Real scaling factors (preRowscale...
Everything should be within this namespace.
Saving LPs in a form suitable for SoPlex.Class SPxLPBase provides the data structures required for sa...
Definition: spxlpbase.h:80
static void computeEquiExpVec(const SVSet *vecset, const DataArray< int > &coScaleExp, DataArray< int > &scaleExp)
compute equilibrium scaling vector rounded to power of two
Definition: spxequilisc.cpp:74
virtual void scale(SPxLPBase< Real > &lp, bool persistent=false) override
Scale the loaded SPxLP.
Saving LPs in a form suitable for SoPlex.
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:206
LP scaler abstract base class.Instances of classes derived from SPxScaler may be loaded to SoPlex in ...
Definition: spxscaler.h:76
virtual Real maxAbsRowscale() const
absolute biggest row scaling factor
Definition: spxscaler.cpp:808
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:118
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Definition: spxlpbase.h:377
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:158
SPxEquiliSC & operator=(const SPxEquiliSC &)
assignment operator
const SVSetBase< R > * colSet() const
Returns the complete SVSetBase.
Definition: lpcolsetbase.h:68
bool isZero(Real a, Real eps=Param::epsilon())
returns true iff |a| <= eps
Definition: spxdefines.h:412
bool m_doBoth
do columns and rows
Definition: spxscaler.h:87
virtual Real maxColRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any column.
Definition: spxscaler.cpp:825
LP equilibrium scaling.
const SVSetBase< R > * rowSet() const
Returns the complete SVSet.
Definition: lprowsetbase.h:69
Equilibrium row/column scaling.This SPxScaler implementation performs equilibrium scaling of the LPs ...
Definition: spxequilisc.h:35
int num() const
Current number of SVectorBases.
Definition: svsetbase.h:759
virtual R maxAbsNzo(bool unscaled=true) const
Absolute biggest non-zero element in (in rational case possibly scaled) LP.
SPxScaler & operator=(const SPxScaler &)
assignment operator
Definition: spxscaler.cpp:88