Scippy

SoPlex

Sequential object-oriented simPlex

spxgeometsc.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 /**@file spxgeometsc.cpp
17  * @brief Geometric mean row/column scaling.
18  */
19 #include <assert.h>
20 
21 #include "spxgeometsc.h"
22 #include "spxout.h"
23 #include "spxlpbase.h"
24 
25 namespace soplex
26 {
27 
29  const SVSet* vecset,
30  const DataArray<Real>& coScaleval,
31  DataArray<Real>& scaleval)
32  {
33 
34  Real pmax = 0.0;
35 
36  for( int i = 0; i < vecset->num(); ++i )
37  {
38  const SVector& vec = (*vecset)[i];
39 
40  Real maxi = 0.0;
41  Real mini = infinity;
42 
43  for( int j = 0; j < vec.size(); ++j )
44  {
45  Real x = spxAbs(vec.value(j) * coScaleval[vec.index(j)]);
46 
47  if (!isZero(x))
48  {
49  if (x > maxi)
50  maxi = x;
51  if (x < mini)
52  mini = x;
53  }
54  }
55  // empty rows/cols are possible
56  if (mini == infinity || maxi == 0.0)
57  {
58  mini = 1.0;
59  maxi = 1.0;
60  }
61  assert(mini < infinity);
62  assert(maxi > 0.0);
63 
64  scaleval[i] = 1.0 / spxSqrt(mini * maxi);
65 
66  Real p = maxi / mini;
67 
68  if (p > pmax)
69  pmax = p;
70  }
71  return pmax;
72  }
73 
74 
75 SPxGeometSC::SPxGeometSC(int maxIters, Real minImpr, Real goodEnough)
76  : SPxScaler("Geometric")
77  , m_maxIterations(maxIters)
78  , m_minImprovement(minImpr)
79  , m_goodEnoughRatio(goodEnough)
80 {}
81 
83  : SPxScaler(old)
87 {}
88 
90 {
91  if (this != &rhs)
92  {
94  }
95 
96  return *this;
97 }
98 
99 void SPxGeometSC::scale(SPxLPBase<Real>& lp, bool persistent)
100 {
101 
102  MSG_INFO1( (*spxout), (*spxout) << "Geometric scaling LP" << (persistent ? " (persistent)" : "") << std::endl; )
103 
104  Real pstart = 0.0;
105  Real p0 = 0.0;
106  Real p1 = 0.0;
107 
108  setup(lp);
109 
110  /* We want to do that direction first, with the lower ratio.
111  * See SPxEquiliSC::scale() for a reasoning.
112  */
113  Real colratio = maxColRatio(lp);
114  Real rowratio = maxRowRatio(lp);
115 
116  DataArray < Real > rowscale(lp.nRows(), lp.nRows(), 1.2);
117  DataArray < Real > colscale(lp.nCols(), lp.nCols(), 1.2);
118 
119  bool colFirst = colratio < rowratio;
120 
121  MSG_INFO2( (*spxout), (*spxout) << "before scaling:"
122  << " min= " << lp.minAbsNzo()
123  << " max= " << lp.maxAbsNzo()
124  << " col-ratio= " << colratio
125  << " row-ratio= " << rowratio
126  << std::endl; )
127 
128  // We make at most maxIterations.
129  for( int count = 0; count < m_maxIterations; count++ )
130  {
131  if (colFirst)
132  {
133  p0 = computeScalingVec(lp.colSet(), rowscale, colscale);
134  p1 = computeScalingVec(lp.rowSet(), colscale, rowscale);
135  }
136  else
137  {
138  p0 = computeScalingVec(lp.rowSet(), colscale, rowscale);
139  p1 = computeScalingVec(lp.colSet(), rowscale, colscale);
140  }
141  MSG_INFO3( (*spxout), (*spxout) << "Geometric scaling round " << count
142  << " col-ratio= " << (colFirst ? p0 : p1)
143  << " row-ratio= " << (colFirst ? p1 : p0)
144  << std::endl; )
145 
146  // record start value, this is done with m_col/rowscale = 1.0, so it is the
147  // value from the "original" (as passed to the scaler) LP.
148  if (count == 0)
149  {
150  pstart = p0;
151  // are we already good enough ?
152  if (pstart < m_goodEnoughRatio)
153  break;
154  }
155  else // do not test at the first iteration, then abort if no improvement.
156  if (p1 > m_minImprovement * p0)
157  break;
158  }
159 
160  // we scale only if either:
161  // - we had at the beginning a ratio worse than 1000/1
162  // - we have at least a 15% improvement.
163  if( pstart < m_goodEnoughRatio || p1 > pstart * m_minImprovement )
164  {
165  MSG_INFO2( (*spxout), (*spxout) << "No scaling done." << std::endl; )
166  }
167  else
168  {
169  DataArray < int > colscaleExp = *m_activeColscaleExp;
170  DataArray < int > rowscaleExp = *m_activeRowscaleExp;
171 
172  int i;
173  for( i = 0; i < lp.nCols(); ++i )
174  {
175  frexp(double(colscale[i]), &(colscaleExp[i]));
176  colscaleExp[i] -= 1;
177  }
178 
179  for( i = 0; i < lp.nRows(); ++i )
180  {
181  frexp(double(rowscale[i]), &(rowscaleExp[i]));
182  rowscaleExp[i] -= 1;
183  }
184 
185  applyScaling(lp);
186 
187  MSG_INFO3( (*spxout), (*spxout) << "Row scaling min= " << minAbsRowscale()
188  << " max= " << maxAbsRowscale()
189  << std::endl
190  << "IGEOSC06 Col scaling min= " << minAbsColscale()
191  << " max= " << maxAbsColscale()
192  << std::endl; )
193 
194  MSG_INFO2( (*spxout), (*spxout) << "after scaling: "
195  << " min= " << lp.minAbsNzo(false)
196  << " max= " << lp.maxAbsNzo(false)
197  << " col-ratio= " << maxColRatio(lp)
198  << " row-ratio= " << maxRowRatio(lp)
199  << std::endl; )
200  }
201 }
202 
203 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3909
virtual void setup(SPxLPBase< Real > &lp)
clear and setup scaling arrays in the LP
Definition: spxscaler.cpp:124
const Real m_goodEnoughRatio
no scaling needed if ratio is less than this.
Definition: spxgeometsc.h:44
const int m_maxIterations
maximum number of scaling iterations.
Definition: spxgeometsc.h:42
virtual R minAbsNzo(bool unscaled=true) const
Absolute smallest non-zero element in (possibly scaled) LP.
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
Geometric mean row/column scaling.This SPxScaler implementation performs geometric mean scaling of th...
Definition: spxgeometsc.h:35
int size() const
Number of used indices.
Definition: svectorbase.h:152
LP geometric mean scaling.
SPxGeometSC(int maxIters=8, Real minImpr=0.85, Real goodEnough=1e3)
default constructor (this scaler makes no use of inherited members m_colFirst and m_doBoth) ...
Definition: spxgeometsc.cpp:75
virtual void scale(SPxLPBase< Real > &lp, bool persistent=true)
Scale the loaded SPxLP.
Definition: spxgeometsc.cpp:99
virtual Real maxRowRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any row.
Definition: spxscaler.cpp:854
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:254
static Real computeScalingVec(const SVSet *vecset, const DataArray< Real > &coScaleval, DataArray< Real > &scaleval)
Definition: spxgeometsc.cpp:28
Saving LPs in a form suitable for SoPlex.
Wrapper for different output streams and verbosity levels.
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
DataArray< int > * m_activeColscaleExp
pointer to currently active column scaling factors
Definition: spxscaler.h:83
virtual void applyScaling(SPxLPBase< Real > &lp)
applies m_colscale and m_rowscale to the lp.
Definition: spxscaler.cpp:171
double Real
Definition: spxdefines.h:215
SPxOut * spxout
message handler
Definition: spxscaler.h:87
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:236
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:117
SPxGeometSC & operator=(const SPxGeometSC &)
assignment operator
Definition: spxgeometsc.cpp:89
Real spxSqrt(Real a)
returns square root
Definition: spxdefines.h:329
virtual Real maxAbsColscale() const
absolute biggest column scaling factor
Definition: spxscaler.cpp:776
virtual Real minAbsColscale() const
absolute smallest column scaling factor
Definition: spxscaler.cpp:763
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:119
DataArray< int > * m_activeRowscaleExp
pointer to currently active row scaling factors
Definition: spxscaler.h:84
virtual Real minAbsRowscale() const
absolute smallest row scaling factor
Definition: spxscaler.cpp:790
Everything should be within this namespace.
LP scaler abstract base class.Instances of classes derived from SPxScaler may be loaded to SoPlex in ...
Definition: spxscaler.h:75
virtual Real maxAbsRowscale() const
absolute biggest row scaling factor
Definition: spxscaler.cpp:803
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:115
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
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:411
virtual Real maxColRatio(const SPxLPBase< Real > &lp) const
maximum ratio between absolute biggest and smallest element in any column.
Definition: spxscaler.cpp:820
const SVSetBase< R > * rowSet() const
Returns the complete SVSet.
Definition: lprowsetbase.h:69
int num() const
Current number of SVectorBases.
Definition: svsetbase.h:746
virtual R maxAbsNzo(bool unscaled=true) const
Absolute biggest non-zero element in (in rational case possibly scaled) LP.
const Real m_minImprovement
improvement necessary to carry on. (Bixby said Fourer said in MP 23, 274 ff. that 0...
Definition: spxgeometsc.h:43
SPxScaler & operator=(const SPxScaler &)
assignment operator
Definition: spxscaler.cpp:84