Scippy

SoPlex

Sequential object-oriented simPlex

spxsolve.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-2018 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/rational.h"
21 #include "soplex/spxsolver.h"
22 #include "soplex/spxpricer.h"
23 #include "soplex/spxratiotester.h"
24 #include "soplex/spxdefaultrt.h"
25 #include "soplex/spxstarter.h"
26 #include "soplex/spxout.h"
27 
28 #define MAXCYCLES 400
29 #define MAXSTALLS 10000
30 #define MAXSTALLRECOVERS 10
31 #define MAXREFACPIVOTS 10
32 
33 namespace soplex
34 {
35 
36 /**@todo check separately for ENTER and LEAVE algorithm */
37 bool SPxSolver::precisionReached(Real& newpricertol) const
38 {
39  Real maxViolRedCost;
40  Real sumViolRedCost;
41  Real maxViolBounds;
42  Real sumViolBounds;
43  Real maxViolConst;
44  Real sumViolConst;
45 
46  qualRedCostViolation(maxViolRedCost, sumViolRedCost);
47  qualBoundViolation(maxViolBounds, sumViolBounds);
48  qualConstraintViolation(maxViolConst, sumViolConst);
49 
50  // is the solution good enough ?
51  bool reached = maxViolRedCost < opttol() && maxViolBounds < feastol() && maxViolConst < feastol();
52 
53  if (!reached)
54  {
55  newpricertol = thepricer->epsilon() / 10.0;
56 
57  MSG_INFO3( (*spxout), (*spxout) << "Precision not reached: Pricer tolerance = "
58  << thepricer->epsilon()
59  << " new tolerance = " << newpricertol
60  << std::endl
61  << " maxViolRedCost= " << maxViolRedCost
62  << " maxViolBounds= " << maxViolBounds
63  << " maxViolConst= " << maxViolConst
64  << std::endl
65  << " sumViolRedCost= " << sumViolRedCost
66  << " sumViolBounds= " << sumViolBounds
67  << " sumViolConst= " << sumViolConst
68  << std::endl; );
69  }
70  return reached;
71 }
72 
74 {
75  // only collect absolute values
76  Real minobj = infinity;
77  Real maxobj = 0.0;
78  Real minbound = infinity;
79  Real maxbound = 0.0;
80  Real minside = infinity;
81  Real maxside = 0.0;
82 
83  // get min and max absolute values of bounds and objective
84  for( int j = 0; j < nCols(); ++j )
85  {
86  Real abslow = spxAbs(lower(j));
87  Real absupp = spxAbs(lower(j));
88  Real absobj = spxAbs(obj(j));
89 
90  if( abslow < infinity )
91  {
92  minbound = MINIMUM(minbound, abslow);
93  maxbound = MAXIMUM(maxbound, abslow);
94  }
95 
96  if( absupp < infinity)
97  {
98  minbound = MINIMUM(minbound, absupp);
99  maxbound = MAXIMUM(maxbound, absupp);
100  }
101 
102  minobj = MINIMUM(minobj, absobj);
103  maxobj = MAXIMUM(maxobj, absobj);
104  }
105 
106  // get min and max absoute values of sides
107  for( int i = 0; i < nRows(); ++i )
108  {
109  Real abslhs = spxAbs(lhs(i));
110  Real absrhs = spxAbs(rhs(i));
111 
112  if( abslhs > infinity )
113  {
114  minside = MINIMUM(minside, abslhs);
115  maxside = MAXIMUM(maxside, abslhs);
116  }
117 
118  if( absrhs < infinity )
119  {
120  minside = MINIMUM(minside, absrhs);
121  maxside = MAXIMUM(maxside, absrhs);
122  }
123  }
124 
125  boundrange = maxbound - minbound;
126  siderange = maxside - minside;
127  objrange = maxobj - minobj;
128 }
129 
131 {
132 
133  SPxId enterId;
134  int leaveNum;
135  int loopCount = 0;
136  Real minShift = infinity;
137  int cycleCount = 0;
138  bool priced = false;
139  Real lastDelta = 1;
140 
141  /* allow clean up step only once */
142  recomputedVectors = false;
143 
144  /* store the last (primal or dual) feasible objective value to recover/abort in case of stalling */
145  Real stallRefValue;
146  Real stallRefShift;
147  int stallRefIter;
148  int stallNumRecovers;
149 
150  if (dim() <= 0 && coDim() <= 0) // no problem loaded
151  {
153  throw SPxStatusException("XSOLVE01 No Problem loaded");
154  }
155 
156  if (slinSolver() == 0) // linear system solver is required.
157  {
159  throw SPxStatusException("XSOLVE02 No Solver loaded");
160  }
161  if (thepricer == 0) // pricer is required.
162  {
164  throw SPxStatusException("XSOLVE03 No Pricer loaded");
165  }
166  if (theratiotester == 0) // ratiotester is required.
167  {
169  throw SPxStatusException("XSOLVE04 No RatioTester loaded");
170  }
171  theTime->reset();
172  theTime->start();
173 
174  m_numCycle = 0;
175  iterCount = 0;
176  lastIterCount = 0;
177  iterDegenCheck = 0;
178  if (!isInitialized())
179  {
180  /*
181  if(SPxBasis::status() <= NO_PROBLEM)
182  SPxBasis::load(this);
183  */
184  /**@todo != REGULAR is not enough. Also OPTIMAL/DUAL/PRIMAL should
185  * be tested and acted accordingly.
186  */
187  if (thestarter != 0 && status() != REGULAR) // no basis and no starter.
188  thestarter->generate(*this); // generate start basis.
189 
190  init();
191 
192  // Inna/Tobi: init might fail, if the basis is singular
193  if( !isInitialized() )
194  {
196  m_status = UNKNOWN;
197  return status();
198  }
199  }
200 
201  //setType(type());
202 
203  if (!matrixIsSetup)
204  SPxBasis::load(this);
205 
206  //factorized = false;
207 
208  assert(thepricer->solver() == this);
209  assert(theratiotester->solver() == this);
210 
211  // maybe this should be done in init() ?
212  thepricer->setType(type());
214 
215  MSG_INFO3( (*spxout),
216  (*spxout) << "starting value = " << value() << std::endl
217  << "starting shift = " << shift() << std::endl;
218  )
219 
222 
223  m_status = RUNNING;
224  bool stop = terminate();
225  leaveCount = 0;
226  enterCount = 0;
227  primalCount = 0;
228  polishCount = 0;
229  boundflips = 0;
230  totalboundflips = 0;
231  enterCycles = 0;
232  leaveCycles = 0;
233  primalDegenSum = 0;
234  dualDegenSum = 0;
235 
236  stallNumRecovers = 0;
237 
238  /* if we run into a singular basis, we will retry from regulardesc with tighter tolerance in the ratio test */
239  SPxSolver::Type tightenedtype = type();
240  bool tightened = false;
241 
242  while (!stop)
243  {
244  const SPxBasis::Desc regulardesc = desc();
245 
246  // we need to reset these pointers to avoid unnecessary/wrong solves in leave() or enter()
247  solveVector2 = 0;
248  solveVector3 = 0;
249  coSolveVector2 = 0;
250  coSolveVector3 = 0;
251 
252  updateViols.clear();
254 
255  try
256  {
257 
258  if (type() == ENTER)
259  {
261 
262  int enterCycleCount = 0;
263  int enterFacPivotCount = 0;
264 
265  instableEnterVal = 0;
267  instableEnter = false;
268 
269  stallRefIter = iteration()-1;
270  stallRefShift = shift();
271  stallRefValue = value();
272 
273  /* in the entering algorithm, entertol() should be maintained by the ratio test and leavetol() should be
274  * reached by the pricer
275  */
276  Real maxpricertol = leavetol();
277  Real minpricertol = 0.01 * maxpricertol;
278 
279  thepricer->setEpsilon(maxpricertol);
280  priced = false;
281 
282  // to avoid shifts we restrict tolerances in the ratio test
283  if( loopCount > 0 )
284  {
285  lastDelta = (lastDelta < entertol()) ? lastDelta : entertol();
286  lastDelta *= 0.01;
287  theratiotester->setDelta(lastDelta);
288  assert(theratiotester->getDelta() > 0);
289  MSG_DEBUG( std::cout << "decreased delta for ratiotest to: " << theratiotester->getDelta() << std::endl; )
290  }
291  else
292  {
293  lastDelta = 1;
295  }
296 
297  printDisplayLine(true);
298  do
299  {
301 
302  enterId = thepricer->selectEnter();
303 
304  if (!enterId.isValid() && instableEnterId.isValid() && lastUpdate() == 0)
305  {
306  /* no entering variable was found, but because of valid instableEnterId we know
307  that this is due to the scaling of the test values. Thus, we use
308  instableEnterId and SPxFastRT::selectEnter shall accept even an instable
309  leaving variable. */
310  MSG_INFO3( (*spxout), (*spxout) << " --- trying instable enter iteration" << std::endl; )
311 
312  enterId = instableEnterId;
313  instableEnter = true;
314  // we also need to reset the test() or coTest() value for getEnterVals()
315  assert(instableEnterVal < 0);
316  if( enterId.isSPxColId() )
317  {
318  int idx = number(SPxColId(enterId));
319  if( rep() == COLUMN )
320  {
321  theTest[idx] = instableEnterVal;
323  {
326  }
327  if( hyperPricingEnter )
328  updateViolsCo.addIdx(idx);
329  }
330  else
331  {
334  {
335  infeasibilities.addIdx(idx);
337  }
338  if( hyperPricingEnter )
339  updateViols.addIdx(idx);
340  }
341  }
342  else
343  {
344  int idx = number(SPxRowId(enterId));
345  if( rep() == COLUMN )
346  {
349  {
350  infeasibilities.addIdx(idx);
352  }
353  if( hyperPricingEnter )
354  updateViols.addIdx(idx);
355  }
356  else
357  {
358  theTest[idx] = instableEnterVal;
360  {
363  }
364  if( hyperPricingEnter )
365  updateViolsCo.addIdx(idx);
366  }
367  }
368  }
369  else
370  {
371  instableEnter = false;
372  }
373 
374  if (!enterId.isValid())
375  {
376  // we are not infeasible and have no shift
377  if ( shift() <= epsilon()
381  {
382  Real newpricertol = minpricertol;
383 
384  // refactorize to eliminate accumulated errors from LU updates
385  if( lastUpdate() > 0 )
386  factorize();
387 
388  // recompute Fvec, Pvec and CoPvec to get a more precise solution and obj value
389  computeFrhs();
391 
394  computePvec();
395 
397 
398  MSG_INFO2( (*spxout), (*spxout) << " --- checking feasibility and optimality\n")
399  computeTest();
400  computeCoTest();
401 
402  // is the solution good enough ?
403  // max three times reduced
404  if ((thepricer->epsilon() > minpricertol) && !precisionReached(newpricertol))
405  { // no!
406  // we reduce the pricer tolerance. Note that if the pricer does not find a candiate
407  // with the reduced tolerance, we quit, regardless of the violations.
408  if (newpricertol < minpricertol)
409  newpricertol = minpricertol;
410 
411  thepricer->setEpsilon(newpricertol);
412 
413  MSG_INFO2( (*spxout), (*spxout) << " --- setting pricer tolerance to "
414  << thepricer->epsilon()
415  << std::endl; )
416  }
417  }
418  MSG_INFO3( (*spxout), (*spxout) << " --- solve(enter) triggers refactorization" << std::endl; )
419 
420  // if the factorization is not fresh, we better refactorize and call the pricer again; however, this can
421  // create cycling, so it is performed only a limited number of times per ENTER round
422  if( lastUpdate() > 0 && enterFacPivotCount < MAXREFACPIVOTS )
423  {
424  factorize();
425 
426  // if the factorization was found out to be singular, we have to quit
428  {
429  MSG_INFO1( (*spxout), (*spxout) << "Something wrong with factorization, Basis status: " << SPxBasis::status() << std::endl; )
430  stop = true;
431  break;
432  }
433 
434  // call pricer again
435  enterId = thepricer->selectEnter();
436 
437  // count how often the pricer has found something only after refactorizing
438  if( enterId.isValid() )
439  enterFacPivotCount++;
440  }
441 
442  if( !enterId.isValid() )
443  {
444  priced = true;
445  break;
446  }
447  }
448 
449  /* check if we have iterations left */
450  if (maxIters >= 0 && iterations() >= maxIters)
451  {
452  MSG_INFO2( (*spxout), (*spxout) << " --- maximum number of iterations (" << maxIters
453  << ") reached" << std::endl; )
455  stop = true;
456  break;
457  }
458 
459  enter(enterId);
460  assert((testBounds(), 1));
462  stop = terminate();
463  clearUpdateVecs();
464 
465  /* if a successful pivot was performed or a nonbasic variable was flipped to its other bound, we reset the
466  * cycle counter
467  */
468  if( lastEntered().isValid() )
469  enterCycleCount = 0;
471  {
472  enterCycleCount++;
473  if( enterCycleCount > MAXCYCLES )
474  {
475  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to cycling in "
476  << "entering algorithm" << std::endl; );
478  stop = true;
479  }
480  }
481 
482  /* only if the basis has really changed, we increase the iterations counter; this is not the case when only
483  * a nonbasic variable was flipped to its other bound
484  */
485  if( lastIndex() >= 0 )
486  {
487  enterCount++;
488  assert(lastEntered().isValid());
489  }
490 
491  /* check every MAXSTALLS iterations whether shift and objective value have not changed */
492  if( (iteration() - stallRefIter) % MAXSTALLS == 0 && basis().status() != SPxBasis::INFEASIBLE )
493  {
494  if( spxAbs(value() - stallRefValue) <= epsilon() && spxAbs(shift() - stallRefShift) <= epsilon() )
495  {
496  if( stallNumRecovers < MAXSTALLRECOVERS )
497  {
498  /* try to recover by unshifting/switching algorithm up to MAXSTALLRECOVERS times (just a number picked) */
499  MSG_INFO3( (*spxout), (*spxout) << " --- stalling detected - trying to recover by switching to LEAVING algorithm." << std::endl; )
500 
501  ++stallNumRecovers;
502  break;
503  }
504  else
505  {
506  /* giving up */
507  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to stalling in entering algorithm." << std::endl; );
508 
510  stop = true;
511  }
512  }
513  else
514  {
515  /* merely update reference values */
516  stallRefIter = iteration()-1;
517  stallRefShift = shift();
518  stallRefValue = value();
519  }
520  }
521 
522  //@ assert(isConsistent());
523  }
524  while (!stop);
525 
526  MSG_INFO3( (*spxout),
527  (*spxout) << " --- enter finished. iteration: " << iteration()
528  << ", value: " << value()
529  << ", shift: " << shift()
530  << ", epsilon: " << epsilon()
531  << ", feastol: " << feastol()
532  << ", opttol: " << opttol()
533  << std::endl
534  << "ISOLVE56 stop: " << stop
535  << ", basis status: " << SPxBasis::status() << " (" << int(SPxBasis::status()) << ")"
536  << ", solver status: " << m_status << " (" << int(m_status) << ")" << std::endl;
537  )
538 
539  if (!stop)
540  {
541  /**@todo technically it would be ok to finish already when (priced && maxinfeas + shift() <= entertol()) is
542  * satisfied; maybe at least in the case when SoPlex keeps jumping back between ENTER and LEAVE always
543  * shifting (looping), we may relax this condition here;
544  * note also that unShift may increase shift() slightly due to roundoff errors
545  */
546  if (shift() <= epsilon())
547  {
548  // factorize();
549  unShift();
550 
551  Real maxinfeas = maxInfeas();
552 
553  MSG_INFO3( (*spxout),
554  (*spxout) << " --- maxInfeas: " << maxinfeas
555  << ", shift: " << shift()
556  << ", entertol: " << entertol() << std::endl;
557  )
558 
559  if (priced && maxinfeas + shift() <= entertol())
560  {
562  m_status = OPTIMAL;
563  break;
564  }
565  else if( loopCount > 2 )
566  {
567  // calculate problem ranges if not done already
568  if( boundrange == 0.0 || siderange == 0.0 || objrange == 0.0 )
570 
571  if( MAXIMUM(MAXIMUM(boundrange, siderange), objrange) >= 1e9 )
572  {
574  MSG_INFO1( (*spxout), (*spxout) << " --- termination despite violations (numerical difficulties,"
575  << " bound range = " << boundrange
576  << ", side range = " << siderange
577  << ", obj range = " << objrange
578  << ")" << std::endl; )
580  m_status = OPTIMAL;
581  break;
582  }
583  else
584  {
586  throw SPxStatusException("XSOLVE14 Abort solving due to looping");
587  }
588  }
589  loopCount++;
590  }
591  setType(LEAVE);
592  init();
593  thepricer->setType(type());
595  }
596  }
597  else
598  {
599  assert(type() == LEAVE);
600 
602 
603  int leaveCycleCount = 0;
604  int leaveFacPivotCount = 0;
605 
606  instableLeaveNum = -1;
607  instableLeave = false;
608  instableLeaveVal = 0;
609 
610  stallRefIter = iteration()-1;
611  stallRefShift = shift();
612  stallRefValue = value();
613 
614  /* in the leaving algorithm, leavetol() should be maintained by the ratio test and entertol() should be reached
615  * by the pricer
616  */
617  Real maxpricertol = entertol();
618  Real minpricertol = 0.01 * maxpricertol;
619 
620  thepricer->setEpsilon(maxpricertol);
621  priced = false;
622 
623  // to avoid shifts we restrict tolerances in the ratio test
624  if( loopCount > 0 )
625  {
626  lastDelta = (lastDelta < leavetol()) ? lastDelta : leavetol();
627  lastDelta *= 0.01;
628  theratiotester->setDelta(lastDelta);
629  assert(theratiotester->getDelta() > 0);
630  MSG_DEBUG( std::cout << "decreased delta for ratiotest to: " << theratiotester->getDelta() << std::endl; )
631  }
632  else
633  {
634  lastDelta = 1;
636  }
637 
638  printDisplayLine(true);
639  do
640  {
642 
643  leaveNum = thepricer->selectLeave();
644 
645  if (leaveNum < 0 && instableLeaveNum >= 0 && lastUpdate() == 0)
646  {
647  /* no leaving variable was found, but because of instableLeaveNum >= 0 we know
648  that this is due to the scaling of theCoTest[...]. Thus, we use
649  instableLeaveNum and SPxFastRT::selectEnter shall accept even an instable
650  entering variable. */
651  MSG_INFO3( (*spxout),
652  (*spxout) << " --- trying instable leave iteration" << std::endl;
653  )
654 
655  leaveNum = instableLeaveNum;
656  instableLeave = true;
657  // we also need to reset the fTest() value for getLeaveVals()
658  assert(instableLeaveVal < 0);
660 
661  if ( sparsePricingLeave )
662  {
664  {
667  }
668  if( hyperPricingLeave )
670  }
671  }
672  else
673  {
674  instableLeave = false;
675  }
676 
677  if (leaveNum < 0)
678  {
679  // we are not infeasible and have no shift
680  if ( shift() <= epsilon()
684  {
685  Real newpricertol = minpricertol;
686 
687  // refactorize to eliminate accumulated errors from LU updates
688  if( lastUpdate() > 0 )
689  factorize();
690 
691  // recompute Fvec, Pvec and CoPvec to get a more precise solution and obj value
692  computeFrhs();
694 
697  computePvec();
698 
700 
701  MSG_INFO2( (*spxout), (*spxout) << " --- checking feasibility and optimality\n")
702  computeFtest();
703 
704  // is the solution good enough ?
705  // max three times reduced
706  if ((thepricer->epsilon() > minpricertol) && !precisionReached(newpricertol))
707  { // no
708  // we reduce the pricer tolerance. Note that if the pricer does not find a candiate
709  // with the reduced pricer tolerance, we quit, regardless of the violations.
710  if (newpricertol < minpricertol)
711  newpricertol = minpricertol;
712 
713  thepricer->setEpsilon(newpricertol);
714 
715  MSG_INFO2( (*spxout), (*spxout) << " --- setting pricer tolerance to "
716  << thepricer->epsilon()
717  << std::endl; );
718  }
719  }
720  MSG_INFO3( (*spxout), (*spxout) << " --- solve(leave) triggers refactorization" << std::endl; )
721 
722  // if the factorization is not fresh, we better refactorize and call the pricer again; however, this can
723  // create cycling, so it is performed only a limited number of times per LEAVE round
724  if( lastUpdate() > 0 && leaveFacPivotCount < MAXREFACPIVOTS )
725  {
726  factorize();
727 
728  // Inna/Tobi: if the factorization was found out to be singular, we have to quit
730  {
731  MSG_INFO1( (*spxout), (*spxout) << "Something wrong with factorization, Basis status: " << SPxBasis::status() << std::endl; )
732  stop = true;
733  break;
734  }
735 
736  // call pricer again
737  leaveNum = thepricer->selectLeave();
738 
739  // count how often the pricer has found something only after refactorizing
740  if( leaveNum >= 0 )
741  leaveFacPivotCount++;
742  }
743 
744  if (leaveNum < 0)
745  {
746  priced = true;
747  break;
748  }
749  }
750 
751  /* check if we have iterations left */
752  if (maxIters >= 0 && iterations() >= maxIters)
753  {
754  MSG_INFO2( (*spxout), (*spxout) << " --- maximum number of iterations (" << maxIters
755  << ") reached" << std::endl; )
757  stop = true;
758  break;
759  }
760 
761  leave(leaveNum);
762  assert((testBounds(), 1));
764  stop = terminate();
765  clearUpdateVecs();
766 
767  /* if a successful pivot was performed or a nonbasic variable was flipped to its other bound, we reset the
768  * cycle counter
769  */
770  if( lastIndex() >= 0 )
771  leaveCycleCount = 0;
773  {
774  leaveCycleCount++;
775  if( leaveCycleCount > MAXCYCLES )
776  {
777  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to cycling in leaving algorithm" << std::endl; );
779  stop = true;
780  }
781  }
782 
783  /* only if the basis has really changed, we increase the iterations counter; this is not the case when only
784  * a nonbasic variable was flipped to its other bound
785  */
786  if( lastEntered().isValid() )
787  {
788  leaveCount++;
789  assert(lastIndex() >= 0);
790  }
791 
792  /* check every MAXSTALLS iterations whether shift and objective value have not changed */
793  if( (iteration() - stallRefIter) % MAXSTALLS == 0 && basis().status() != SPxBasis::INFEASIBLE )
794  {
795  if( spxAbs(value() - stallRefValue) <= epsilon() && spxAbs(shift() - stallRefShift) <= epsilon() )
796  {
797  if( stallNumRecovers < MAXSTALLRECOVERS )
798  {
799  /* try to recover by switching algorithm up to MAXSTALLRECOVERS times */
800  MSG_INFO3( (*spxout), (*spxout) << " --- stalling detected - trying to recover by switching to ENTERING algorithm." << std::endl; )
801 
802  ++stallNumRecovers;
803  break;
804  }
805  else
806  {
807  /* giving up */
808  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to stalling in leaving algorithm" << std::endl; );
809 
811  stop = true;
812  }
813  }
814  else
815  {
816  /* merely update reference values */
817  stallRefIter = iteration()-1;
818  stallRefShift = shift();
819  stallRefValue = value();
820  }
821  }
822 
823  //@ assert(isConsistent());
824  }
825  while (!stop);
826 
827  MSG_INFO3( (*spxout),
828  (*spxout) << " --- leave finished. iteration: " << iteration()
829  << ", value: " << value()
830  << ", shift: " << shift()
831  << ", epsilon: " << epsilon()
832  << ", feastol: " << feastol()
833  << ", opttol: " << opttol()
834  << std::endl
835  << "ISOLVE57 stop: " << stop
836  << ", basis status: " << SPxBasis::status() << " (" << int(SPxBasis::status()) << ")"
837  << ", solver status: " << m_status << " (" << int(m_status) << ")" << std::endl;
838  )
839 
840  if (!stop)
841  {
842  if( shift() < minShift )
843  {
844  minShift = shift();
845  cycleCount = 0;
846  }
847  else
848  {
849  cycleCount++;
850  if( cycleCount > MAXCYCLES )
851  {
853  throw SPxStatusException("XSOLVE13 Abort solving due to cycling");
854  }
855  MSG_INFO3( (*spxout),
856  (*spxout) << " --- maxInfeas: " << maxInfeas()
857  << ", shift: " << shift()
858  << ", leavetol: " << leavetol()
859  << ", cycle count: " << cycleCount << std::endl;
860  )
861  }
862 
863  /**@todo technically it would be ok to finish already when (priced && maxinfeas + shift() <= entertol()) is
864  * satisfied; maybe at least in the case when SoPlex keeps jumping back between ENTER and LEAVE always
865  * shifting (looping), we may relax this condition here;
866  * note also that unShift may increase shift() slightly due to roundoff errors
867  */
868  if (shift() <= epsilon())
869  {
870  cycleCount = 0;
871  // factorize();
872  unShift();
873 
874  Real maxinfeas = maxInfeas();
875 
876  MSG_INFO3( (*spxout),
877  (*spxout) << " --- maxInfeas: " << maxinfeas
878  << ", shift: " << shift()
879  << ", leavetol: " << leavetol() << std::endl;
880  )
881 
882  // We stop if we are indeed optimal, or if we have already been
883  // two times at this place. In this case it seems futile to
884  // continue.
885  if (priced && maxinfeas + shift() <= leavetol())
886  {
888  m_status = OPTIMAL;
889  break;
890  }
891  else if (loopCount > 2)
892  {
893  // calculate problem ranges if not done already
894  if( boundrange == 0.0 || siderange == 0.0 || objrange == 0.0 )
896 
897  if( MAXIMUM(MAXIMUM(boundrange, siderange), objrange) >= 1e9 )
898  {
900  MSG_INFO1( (*spxout), (*spxout) << " --- termination despite violations (numerical difficulties,"
901  << " bound range = " << boundrange
902  << ", side range = " << siderange
903  << ", obj range = " << objrange
904  << ")" << std::endl; )
906  m_status = OPTIMAL;
907  break;
908  }
909  else
910  {
912  throw SPxStatusException("XSOLVE14 Abort solving due to looping");
913  }
914  }
915  loopCount++;
916  }
917  setType(ENTER);
918  init();
919  thepricer->setType(type());
921  }
922  }
923  assert(m_status != SINGULAR);
924 
925  }
926  catch( const SPxException& E )
927  {
928  // if we stopped due to a singular basis, we reload the original basis and try again with tighter
929  // tolerance (only once)
930  if (m_status == SINGULAR && !tightened)
931  {
932  tightenedtype = type();
933 
934  if( tightenedtype == ENTER )
935  {
936  m_entertol = 0.01 * m_entertol;
937 
938  MSG_INFO2( (*spxout), (*spxout) << " --- basis singular: reloading basis and solving with tighter ratio test tolerance " << m_entertol << std::endl; )
939  }
940  else
941  {
942  m_leavetol = 0.01 * m_leavetol;
943 
944  MSG_INFO2( (*spxout), (*spxout) << " --- basis singular: reloading basis and solving with tighter ratio test tolerance " << m_leavetol << std::endl; )
945  }
946 
947  // load original basis
948  int niters = iterations();
949  loadBasis(regulardesc);
950 
951  // remember iteration count
952  iterCount = niters;
953 
954  // try initializing basis (might fail if starting basis was already singular)
955  try
956  {
957  init();
959  }
960  catch( const SPxException& Ex )
961  {
962  MSG_INFO2( (*spxout), (*spxout) << " --- reloaded basis singular, resetting original tolerances" << std::endl; )
963 
964  if( tightenedtype == ENTER )
965  m_entertol = 100.0 * m_entertol;
966  else
967  m_leavetol = 100.0 * m_leavetol;
968 
970 
971  throw Ex;
972  }
973 
974  // reset status and counters
975  m_status = RUNNING;
976  m_numCycle = 0;
977  leaveCount = 0;
978  enterCount = 0;
979  stallNumRecovers = 0;
980 
981  // continue
982  stop = false;
983  tightened = true;
984  }
985  // reset tolerance to its original value and pass on the exception
986  else if (tightened)
987  {
988  if( tightenedtype == ENTER )
989  m_entertol = 100.0 * m_entertol;
990  else
991  m_leavetol = 100.0 * m_leavetol;
992 
994 
995  throw E;
996  }
997  // pass on the exception
998  else
999  throw E;
1000  }
1001  }
1002 
1003  // reset tolerance to its original value
1004  if (tightened)
1005  {
1006  if( tightenedtype == ENTER )
1007  m_entertol = 100.0 * m_entertol;
1008  else
1009  m_leavetol = 100.0 * m_leavetol;
1010 
1012  }
1013 
1014  theTime->stop();
1015  theCumulativeTime += time();
1016 
1017  if (m_status == RUNNING)
1018  {
1019  m_status = ERROR;
1020  throw SPxStatusException("XSOLVE05 Status is still RUNNING when it shouldn't be");
1021  }
1022 
1023  MSG_INFO3( (*spxout),
1024  (*spxout) << "Finished solving (status=" << status()
1025  << ", iters=" << iterCount
1026  << ", leave=" << leaveCount
1027  << ", enter=" << enterCount
1028  << ", flips=" << totalboundflips;
1029  if( status() == OPTIMAL )
1030  (*spxout) << ", objValue=" << value();
1031  (*spxout) << ")" << std::endl;
1032  )
1033 
1034 #ifdef ENABLE_ADDITIONAL_CHECKS
1035  /* check if solution is really feasible */
1036  if( status() == OPTIMAL )
1037  {
1038  int c;
1039  Real val;
1040  DVector sol( nCols() );
1041 
1042  getPrimal( sol );
1043 
1044  for(int row = 0; row < nRows(); ++row )
1045  {
1046  const SVector& rowvec = rowVector( row );
1047  val = 0.0;
1048  for( c = 0; c < rowvec.size(); ++c )
1049  val += rowvec.value( c ) * sol[rowvec.index( c )];
1050 
1051  if( LT( val, lhs( row ), feastol() ) ||
1052  GT( val, rhs( row ), feastol() ) )
1053  {
1054  // Minor rhs violations happen frequently, so print these
1055  // warnings only with verbose level INFO2 and higher.
1056  MSG_INFO2( (*spxout), (*spxout) << "WSOLVE88 Warning! Constraint " << row
1057  << " is violated by solution" << std::endl
1058  << " lhs:" << lhs( row )
1059  << " <= val:" << val
1060  << " <= rhs:" << rhs( row ) << std::endl; )
1061 
1062  if( type() == LEAVE && isRowBasic( row ) )
1063  {
1064  // find basis variable
1065  for( c = 0; c < nRows(); ++c )
1066  if (basis().baseId(c).isSPxRowId()
1067  && (number(basis().baseId(c)) == row))
1068  break;
1069 
1070  assert( c < nRows() );
1071 
1072  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE90 basis idx:" << c
1073  << " fVec:" << fVec()[c]
1074  << " fRhs:" << fRhs()[c]
1075  << " fTest:" << fTest()[c] << std::endl; )
1076  }
1077  }
1078  }
1079  for(int col = 0; col < nCols(); ++col )
1080  {
1081  if( LT( sol[col], lower( col ), feastol() ) ||
1082  GT( sol[col], upper( col ), feastol() ) )
1083  {
1084  // Minor bound violations happen frequently, so print these
1085  // warnings only with verbose level INFO2 and higher.
1086  MSG_INFO2( (*spxout), (*spxout) << "WSOLVE91 Warning! Bound for column " << col
1087  << " is violated by solution" << std::endl
1088  << " lower:" << lower( col )
1089  << " <= val:" << sol[col]
1090  << " <= upper:" << upper( col ) << std::endl; )
1091 
1092  if( type() == LEAVE && isColBasic( col ) )
1093  {
1094  for( c = 0; c < nRows() ; ++c)
1095  if ( basis().baseId( c ).isSPxColId()
1096  && ( number( basis().baseId( c ) ) == col ))
1097  break;
1098 
1099  assert( c < nRows() );
1100  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE92 basis idx:" << c
1101  << " fVec:" << fVec()[c]
1102  << " fRhs:" << fRhs()[c]
1103  << " fTest:" << fTest()[c] << std::endl; )
1104  }
1105  }
1106  }
1107  }
1108 #endif // ENABLE_ADDITIONAL_CHECKS
1109 
1110  primalCount = ( rep() == SPxSolver::COLUMN )
1111  ? enterCount
1112  : leaveCount;
1113 
1114  printDisplayLine(true);
1116 
1117  return status();
1118 }
1119 
1121 {
1122  // catch rare case that the iteration limit is exactly reached at optimality
1123  bool stop = (maxIters >= 0 && iterations() >= maxIters && !isTimeLimitReached());
1124 
1125  // only polish an already optimal basis
1126  if( stop || polishObj == POLISH_OFF || status() != OPTIMAL )
1127  return;
1128 
1129  int nSuccessfulPivots;
1130  const SPxBasis::Desc& ds = desc();
1131  const SPxBasis::Desc::Status* rowstatus = ds.rowStatus();
1132  const SPxBasis::Desc::Status* colstatus = ds.colStatus();
1134  SPxId polishId;
1135  bool success = false;
1136 
1137  MSG_INFO2( (*spxout), (*spxout) << " --- perform solution polishing" << std::endl; )
1138 
1139  if( rep() == COLUMN )
1140  {
1141  setType(ENTER); // use primal simplex to preserve feasibility
1142  init();
1143 #ifndef NDEBUG
1144  // allow a small relative deviation from the original values
1145  Real alloweddeviation = entertol();
1146  Real origval = value();
1147  Real origshift = shift();
1148 #endif
1149  instableEnter = false;
1151  if( polishObj == POLISH_INTEGRALITY )
1152  {
1153  DIdxSet slackcandidates(nRows());
1154  DIdxSet continuousvars(nCols());
1155 
1156  // collect nonbasic slack variables that could be made basic
1157  for( int i = 0; i < nRows(); ++i )
1158  {
1159  // only check nonbasic rows, skip equations
1160  if( rowstatus[i] == SPxBasis::Desc::P_ON_LOWER || rowstatus[i] == SPxBasis::Desc::P_ON_UPPER )
1161  {
1162  // only consider rows with zero dual multiplier to preserve optimality
1163  if( EQrel((*theCoPvec)[i], 0) )
1164  slackcandidates.addIdx(i);
1165  }
1166  }
1167 
1168  // collect continuous variables that could be made basic
1169  if( integerVariables.size() == nCols() )
1170  {
1171  for( int i = 0; i < nCols(); ++i )
1172  {
1173  // skip fixed variables
1174  if( colstatus[i] == SPxBasis::Desc::P_ON_LOWER || colstatus[i] == SPxBasis::Desc::P_ON_UPPER )
1175  {
1176  // only consider continuous variables with zero dual multiplier to preserve optimality
1177  if( EQrel(maxObj(i) - (*thePvec)[i], 0) && integerVariables[i] == 0 )
1178  continuousvars.addIdx(i);
1179  }
1180  }
1181  }
1182 
1183  while( !stop )
1184  {
1185  nSuccessfulPivots = 0;
1186  // identify nonbasic slack variables, i.e. rows, that may be moved into the basis
1187  for( int i = slackcandidates.size() - 1; i >= 0 && !stop; --i )
1188  {
1189  polishId = coId(slackcandidates.index(i));
1190  MSG_DEBUG( std::cout << "try pivoting: " << polishId << " stat: " << rowstatus[slackcandidates.index(i)]; )
1191  success = enter(polishId, true);
1192  clearUpdateVecs();
1193 #ifndef NDEBUG
1194  assert(EQrel(value(), origval, alloweddeviation));
1195  assert(LErel(shift(), origshift, alloweddeviation));
1196 #endif
1197  if( success )
1198  {
1199  MSG_DEBUG( std::cout << " -> success!"; )
1200  ++nSuccessfulPivots;
1201  slackcandidates.remove(i);
1202  if( maxIters >= 0 && iterations() >= maxIters )
1203  stop = true;
1204  }
1205  MSG_DEBUG( std::cout << std::endl; )
1206  if( isTimeLimitReached() )
1207  stop = true;
1208  }
1209 
1210  // identify nonbasic variables that may be moved into the basis
1211  for( int i = continuousvars.size() - 1; i >= 0 && !stop; --i )
1212  {
1213  polishId = id(continuousvars.index(i));
1214  MSG_DEBUG( std::cout << "try pivoting: " << polishId << " stat: " << colstatus[continuousvars.index(i)]; )
1215  success = enter(polishId, true);
1216  clearUpdateVecs();
1217 #ifndef NDEBUG
1218  assert(EQrel(value(), origval, alloweddeviation));
1219  assert(LErel(shift(), origshift, alloweddeviation));
1220 #endif
1221  if( success )
1222  {
1223  MSG_DEBUG( std::cout << " -> success!"; )
1224  ++nSuccessfulPivots;
1225  continuousvars.remove(i);
1226  if( maxIters >= 0 && iterations() >= maxIters )
1227  stop = true;
1228  }
1229  MSG_DEBUG( std::cout << std::endl; )
1230  if( isTimeLimitReached() )
1231  stop = true;
1232  }
1233 
1234  // terminate if in the last round no more polishing steps were performed
1235  if( nSuccessfulPivots == 0 )
1236  stop = true;
1237  polishCount += nSuccessfulPivots;
1238  }
1239  }
1240  else
1241  {
1242  assert(polishObj == POLISH_FRACTIONALITY);
1243  DIdxSet candidates(dim());
1244 
1245  // identify nonbasic variables, i.e. columns, that may be moved into the basis
1246  for( int i = 0; i < nCols() && !stop; ++i )
1247  {
1248  if( colstatus[i] == SPxBasis::Desc::P_ON_LOWER || colstatus[i] == SPxBasis::Desc::P_ON_UPPER )
1249  {
1250  // only consider variables with zero reduced costs to preserve optimality
1251  if( EQrel(maxObj(i) - (*thePvec)[i], 0) )
1252  candidates.addIdx(i);
1253  }
1254  }
1255 
1256  while( !stop )
1257  {
1258  nSuccessfulPivots = 0;
1259  for( int i = candidates.size() - 1; i >= 0 && !stop; --i )
1260  {
1261  polishId = id(candidates.index(i));
1262  MSG_DEBUG( std::cout << "try pivoting: " << polishId << " stat: " << colstatus[candidates.index(i)]; )
1263  success = enter(polishId, true);
1264  clearUpdateVecs();
1265 #ifndef NDEBUG
1266  assert(EQrel(value(), origval, alloweddeviation));
1267  assert(LErel(shift(), origshift, alloweddeviation));
1268 #endif
1269  if( success )
1270  {
1271  MSG_DEBUG( std::cout << " -> success!"; )
1272  ++nSuccessfulPivots;
1273  candidates.remove(i);
1274  if( maxIters >= 0 && iterations() >= maxIters )
1275  stop = true;
1276  }
1277  MSG_DEBUG( std::cout << std::endl; )
1278  if( isTimeLimitReached() )
1279  stop = true;
1280  }
1281  // terminate if in the last round no more polishing steps were performed
1282  if( nSuccessfulPivots == 0 )
1283  stop = true;
1284  polishCount += nSuccessfulPivots;
1285  }
1286  }
1287  }
1288  else
1289  {
1290  setType(LEAVE); // use primal simplex to preserve feasibility
1291  init();
1292 #ifndef NDEBUG
1293  // allow a small relative deviation from the original values
1294  Real alloweddeviation = leavetol();
1295  Real origval = value();
1296  Real origshift = shift();
1297 #endif
1298  instableLeave = false;
1300  bool useIntegrality = false;
1301 
1302  if( integerVariables.size() == nCols() )
1303  useIntegrality = true;
1304 
1305  // in ROW rep: pivot slack out of the basis
1306  if( polishObj == POLISH_INTEGRALITY )
1307  {
1308  DIdxSet basiccandidates(dim());
1309 
1310  // collect basic candidates that may be moved out of the basis
1311  for( int i = 0; i < dim(); ++i )
1312  {
1313  polishId = baseId(i);
1314 
1315  if( polishId.isSPxRowId() )
1316  stat = ds.rowStatus(number(polishId));
1317  else
1318  {
1319  // skip (integer) variables
1320  if( !useIntegrality || integerVariables[number(SPxColId(polishId))] == 1 )
1321  continue;
1322  stat = ds.colStatus(number(polishId));
1323  }
1324 
1326  {
1327  if( EQrel((*theFvec)[i], 0) )
1328  basiccandidates.addIdx(i);
1329  }
1330  }
1331 
1332  while( !stop )
1333  {
1334  nSuccessfulPivots = 0;
1335  for( int i = basiccandidates.size() - 1; i >= 0 && !stop; --i)
1336  {
1337 
1338  MSG_DEBUG( std::cout << "try pivoting: " << baseId(basiccandidates.index(i)); )
1339  success = leave(basiccandidates.index(i), true);
1340  clearUpdateVecs();
1341 #ifndef NDEBUG
1342  assert(EQrel(value(), origval, alloweddeviation));
1343  assert(LErel(shift(), origshift, alloweddeviation));
1344 #endif
1345  if( success )
1346  {
1347  MSG_DEBUG( std::cout << " -> success!"; )
1348  ++nSuccessfulPivots;
1349  basiccandidates.remove(i);
1350  if( maxIters >= 0 && iterations() >= maxIters )
1351  stop = true;
1352  }
1353  MSG_DEBUG( std::cout << std::endl; )
1354  if( isTimeLimitReached() )
1355  stop = true;
1356  }
1357  // terminate if in the last round no more polishing steps were performed
1358  if( nSuccessfulPivots == 0 )
1359  stop = true;
1360  polishCount += nSuccessfulPivots;
1361  }
1362  }
1363  else
1364  {
1365  assert(polishObj == POLISH_FRACTIONALITY);
1366  DIdxSet basiccandidates(dim());
1367 
1368  // collect basic (integer) variables, that may be moved out of the basis
1369  for( int i = 0; i < dim(); ++i )
1370  {
1371  polishId = baseId(i);
1372 
1373  if( polishId.isSPxRowId() )
1374  continue;
1375  else
1376  {
1377  if( useIntegrality && integerVariables[number(SPxColId(polishId))] == 0 )
1378  continue;
1379  stat = ds.colStatus(i);
1380  }
1381 
1383  {
1384  if( EQrel((*theFvec)[i], 0) )
1385  basiccandidates.addIdx(i);
1386  }
1387  }
1388 
1389  while( !stop )
1390  {
1391  nSuccessfulPivots = 0;
1392  for( int i = basiccandidates.size() - 1; i >= 0 && !stop; --i )
1393  {
1394  MSG_DEBUG( std::cout << "try pivoting: " << baseId(basiccandidates.index(i)); )
1395  success = leave(basiccandidates.index(i), true);
1396  clearUpdateVecs();
1397 #ifndef NDEBUG
1398  assert(EQrel(value(), origval, alloweddeviation));
1399  assert(LErel(shift(), origshift, alloweddeviation));
1400 #endif
1401  if( success )
1402  {
1403  MSG_DEBUG( std::cout << " -> success!"; )
1404  ++nSuccessfulPivots;
1405  basiccandidates.remove(i);
1406  if( maxIters >= 0 && iterations() >= maxIters )
1407  stop = true;
1408  }
1409  MSG_DEBUG( std::cout << std::endl; )
1410  if( isTimeLimitReached() )
1411  stop = true;
1412  }
1413  // terminate if in the last round no more polishing steps were performed
1414  if( nSuccessfulPivots == 0 )
1415  stop = true;
1416  polishCount += nSuccessfulPivots;
1417  }
1418  }
1419  }
1420 
1421  MSG_INFO1( (*spxout),
1422  (*spxout) << " --- finished solution polishing (" << polishCount << " pivots)" << std::endl; )
1423 
1425 }
1426 
1427 
1429 {
1430 
1432 
1433  DVector tmp(dim());
1434 
1435  tmp = *theCoPvec;
1436  multWithBase(tmp);
1437  tmp -= *theCoPrhs;
1438  if (tmp.length() > leavetol())
1439  {
1440  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE93 " << iteration() << ":\tcoP error = \t"
1441  << tmp.length() << std::endl; )
1442 
1443  tmp.clear();
1445  multWithBase(tmp);
1446  tmp -= *theCoPrhs;
1447  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE94\t\t" << tmp.length() << std::endl; )
1448 
1449  tmp.clear();
1451  tmp -= *theCoPvec;
1452  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE95\t\t" << tmp.length() << std::endl; )
1453  }
1454 
1455  tmp = *theFvec;
1456  multBaseWith(tmp);
1457  tmp -= *theFrhs;
1458  if (tmp.length() > entertol())
1459  {
1460  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE96 " << iteration() << ":\t F error = \t"
1461  << tmp.length() << std::endl; )
1462 
1463  tmp.clear();
1464  SPxBasis::solve(tmp, *theFrhs);
1465  tmp -= *theFvec;
1466  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE97\t\t" << tmp.length() << std::endl; )
1467  }
1468 
1469  if (type() == ENTER)
1470  {
1471  for (int i = 0; i < dim(); ++i)
1472  {
1473  if (theCoTest[i] < -leavetol() && isCoBasic(i))
1474  {
1475  /// @todo Error message "this shalt not be": shalt this be an assert (also below)?
1476  MSG_INFO1( (*spxout), (*spxout) << "ESOLVE98 testVecs: theCoTest: this shalt not be!"
1477  << std::endl
1478  << " i=" << i
1479  << ", theCoTest[i]=" << theCoTest[i]
1480  << ", leavetol()=" << leavetol() << std::endl; )
1481  }
1482  }
1483 
1484  for (int i = 0; i < coDim(); ++i)
1485  {
1486  if (theTest[i] < -leavetol() && isBasic(i))
1487  {
1488  MSG_INFO1( (*spxout), (*spxout) << "ESOLVE99 testVecs: theTest: this shalt not be!"
1489  << std::endl
1490  << " i=" << i
1491  << ", theTest[i]=" << theTest[i]
1492  << ", leavetol()=" << leavetol() << std::endl; )
1493  }
1494  }
1495  }
1496 }
1497 
1498 
1499 /// print display line of flying table
1500 void SPxSolver::printDisplayLine(const bool force, const bool forceHead)
1501 {
1502  MSG_INFO1( (*spxout),
1503  if( forceHead || displayLine % (displayFreq*30) == 0 )
1504  {
1505  (*spxout) << "type | time | iters | facts | shift | violation | obj value ";
1506  if( printCondition > 0 )
1507  (*spxout) << " | condition";
1508  (*spxout) << std::endl;
1509  }
1510  if( (force || (displayLine % displayFreq == 0)) && !forceHead )
1511  {
1512  (type() == LEAVE) ? (*spxout) << " L |" : (*spxout) << " E |";
1513  (*spxout) << std::fixed << std::setw(7) << std::setprecision(1) << time() << " |";
1514  (*spxout) << std::scientific << std::setprecision(2);
1515  (*spxout) << std::setw(8) << iteration() << " | "
1516  << std::setw(5) << slinSolver()->getFactorCount() << " | "
1517  << shift() << " | "
1518  << MAXIMUM(0.0, m_pricingViol + m_pricingViolCo) << " | "
1519  << std::setprecision(8) << value();
1521  (*spxout) << " (" << std::fixed << std::setprecision(2) << getDegeneracyLevel(fVec()) <<")";
1522  if( printCondition == 1 )
1523  (*spxout) << " | " << std::scientific << std::setprecision(2) << basis().getFastCondition(0);
1524  if( printCondition == 2 )
1525  (*spxout) << " | " << std::scientific << std::setprecision(2) << basis().getFastCondition(1);
1526  if( printCondition == 3 )
1527  (*spxout) << " | " << std::scientific << std::setprecision(2) << basis().getFastCondition(2);
1528  if( printCondition == 4 )
1529  (*spxout) << " | " << std::scientific << std::setprecision(2) << basis().getEstimatedCondition();
1530  (*spxout) << std::endl;
1531  }
1532  displayLine++;
1533  );
1534 }
1535 
1536 
1538 {
1539 #ifdef ENABLE_ADDITIONAL_CHECKS
1541  testVecs();
1542 #endif
1543 
1544  int redo = dim();
1545  if (redo < 1000)
1546  redo = 1000;
1547 
1548  if (iteration() > 10 && iteration() % redo == 0)
1549  {
1550 #ifdef ENABLE_ADDITIONAL_CHECKS
1551  DVector cr(*theCoPrhs);
1552  DVector fr(*theFrhs);
1553 #endif
1554 
1555  if (type() == ENTER)
1557  else
1559 
1560  computeFrhs();
1561 
1562 #ifdef ENABLE_ADDITIONAL_CHECKS
1563  cr -= *theCoPrhs;
1564  fr -= *theFrhs;
1565  if (cr.length() > leavetol())
1566  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE50 unexpected change of coPrhs "
1567  << cr.length() << std::endl; )
1568  if (fr.length() > entertol())
1569  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE51 unexpected change of Frhs "
1570  << fr.length() << std::endl; )
1571 #endif
1572 
1573  if (updateCount > 1)
1574  {
1575  MSG_INFO3( (*spxout), (*spxout) << " --- terminate triggers refactorization"
1576  << std::endl; )
1577  factorize();
1578  }
1581 
1582  if (pricing() == FULL)
1583  {
1584  computePvec();
1585  if (type() == ENTER)
1586  computeTest();
1587  }
1588 
1589  if (shift() > 0.0)
1590  unShift();
1591  }
1592 
1593  // check time limit and objective limit only for non-terminal bases
1596  {
1597  m_status = UNKNOWN;
1598  return true;
1599  }
1600 
1601  if ( isTimeLimitReached() )
1602  {
1603  MSG_INFO2( (*spxout), (*spxout) << " --- timelimit (" << maxTime
1604  << ") reached" << std::endl; )
1605  m_status = ABORT_TIME;
1606  return true;
1607  }
1608 
1609  // objLimit is set and we are running DUAL:
1610  // - objLimit is set if objLimit < infinity
1611  // - DUAL is running if rep() * type() > 0 == DUAL (-1 == PRIMAL)
1612  //
1613  // In this case we have given a objective value limit, e.g, through a
1614  // MIP solver, and we want stop solving the LP if we figure out that the
1615  // optimal value of the current LP can not be better then this objective
1616  // limit. More precisely:
1617  // - MINIMIZATION Problem
1618  // We want stop the solving process if
1619  // objLimit <= current objective value of the DUAL LP
1620  // - MAXIMIZATION Problem
1621  // We want stop the solving process if
1622  // objLimit >= current objective value of the DUAL LP
1623  if( objLimit < infinity && type() * rep() > 0 )
1624  {
1625  // We have no bound shifts; therefore, we can trust the current
1626  // objective value.
1627  // It might be even possible to use this termination value in case of
1628  // bound violations (shifting) but in this case it is quite difficult
1629  // to determine if we already reached the limit.
1630  if( shift() < epsilon() && noViols(opttol() - shift()) )
1631  {
1632  // SPxSense::MINIMIZE == -1, so we have sign = 1 on minimizing
1633  if( spxSense() * value() <= spxSense() * objLimit )
1634  {
1635  MSG_INFO2( (*spxout), (*spxout) << " --- objective value limit (" << objLimit
1636  << ") reached" << std::endl; )
1637  MSG_DEBUG(
1638  (*spxout) << " --- objective value limit reached" << std::endl
1639  << " (value: " << value()
1640  << ", limit: " << objLimit << ")" << std::endl
1641  << " (spxSense: " << int(spxSense())
1642  << ", rep: " << int(rep())
1643  << ", type: " << int(type()) << ")" << std::endl;
1644  )
1645 
1647  return true;
1648  }
1649  }
1650  }
1651 
1652 
1653 
1655  {
1656  DVector degenvec(nCols());
1657  if( rep() == ROW )
1658  {
1659  if( type() == ENTER ) // dual simplex
1661  else // primal simplex
1662  {
1663  getPrimal(degenvec);
1664  primalDegenSum += getDegeneracyLevel(degenvec);
1665  }
1666  }
1667  else
1668  {
1669  assert(rep() == COLUMN);
1670  if( type() == LEAVE ) // dual simplex
1672  else
1673  {
1674  getPrimal(degenvec);
1675  primalDegenSum += getDegeneracyLevel(degenvec);
1676  }
1677  }
1678  }
1679 
1680 
1681  // the improved dual simplex requires a starting basis
1682  // if the flag getStartingDecompBasis is set to true the simplex will terminate when a dual basis is found
1684  {
1685  Real iterationFrac = 0.6;
1686  if( type() == ENTER && SPxBasis::status() == SPxBasis::DUAL &&
1687  iteration() - lastDegenCheck() > getDegenCompOffset()/*iteration() % 10 == 0*/ )
1688  {
1690 
1692  {
1693  m_status = RUNNING;
1694  return true;
1695  }
1696 
1697  Real degeneracyLevel = 0;
1698  Real degeneracyLB = 0.1;
1699  Real degeneracyUB = 0.9;
1700  degeneracyLevel = getDegeneracyLevel(fVec());
1701  if( (degeneracyLevel < degeneracyUB && degeneracyLevel > degeneracyLB) && iteration() > nRows()*0.2 )
1702  {
1704  return true;
1705  }
1706 
1707  if( degeneracyLevel < degeneracyLB && iteration() > MINIMUM(getDecompIterationLimit(), int(nCols()*iterationFrac)) )
1708  {
1710  setDegenCompOffset(0);
1712  return true;
1713  }
1714  }
1715  else if( type() == LEAVE && iteration() > MINIMUM(getDecompIterationLimit(), int(nCols()*iterationFrac)) )
1716  {
1718  setDegenCompOffset(0);
1720  return true;
1721  }
1722  }
1723 
1725 
1726  return false;
1727 }
1728 
1730 {
1731 
1732  if (!isInitialized())
1733  {
1734  /* exit if presolving/simplifier cleared the problem */
1735  if (status() == NO_PROBLEM)
1736  return status();
1737  throw SPxStatusException("XSOLVE06 Not Initialized");
1738  }
1739  if (rep() == ROW)
1740  p_vector = coPvec();
1741  else
1742  {
1743  const SPxBasis::Desc& ds = desc();
1744 
1745  for (int i = 0; i < nCols(); ++i)
1746  {
1747  switch (ds.colStatus(i))
1748  {
1750  p_vector[i] = SPxLP::lower(i);
1751  break;
1754  p_vector[i] = SPxLP::upper(i);
1755  break;
1756  case SPxBasis::Desc::P_FREE :
1757  p_vector[i] = 0;
1758  break;
1759  case SPxBasis::Desc::D_FREE :
1764  break;
1765  default:
1766  throw SPxInternalCodeException("XSOLVE07 This should never happen.");
1767  }
1768  }
1769  for (int j = 0; j < dim(); ++j)
1770  {
1771  if (baseId(j).isSPxColId())
1772  p_vector[ number(SPxColId(baseId(j))) ] = fVec()[j];
1773  }
1774  }
1775  return status();
1776 }
1777 
1779 {
1780 
1781  assert(isInitialized());
1782 
1783  if (!isInitialized())
1784  {
1785  /* exit if presolving/simplifier cleared the problem */
1786  if (status() == NO_PROBLEM)
1787  return status();
1788  throw SPxStatusException("XSOLVE08 No Problem loaded");
1789  }
1790 
1791  if (rep() == ROW)
1792  {
1793  int i;
1794  p_vector = maxRowObj();
1795  for (i = nCols() - 1; i >= 0; --i)
1796  {
1797  if (baseId(i).isSPxRowId())
1798  p_vector[ number(SPxRowId(baseId(i))) ] = fVec()[i];
1799  }
1800  }
1801  else
1802  p_vector = coPvec();
1803 
1804  p_vector *= Real(spxSense());
1805 
1806  return status();
1807 }
1808 
1810 {
1811 
1812  assert(isInitialized());
1813 
1814  if (!isInitialized())
1815  {
1816  throw SPxStatusException("XSOLVE09 No Problem loaded");
1817  // return NOT_INIT;
1818  }
1819 
1820  if (rep() == ROW)
1821  {
1822  int i;
1823  p_vector.clear();
1824  if (spxSense() == SPxLP::MINIMIZE)
1825  {
1826  for (i = dim() - 1; i >= 0; --i)
1827  {
1828  if (baseId(i).isSPxColId())
1829  p_vector[ number(SPxColId(baseId(i))) ] = -fVec()[i];
1830  }
1831  }
1832  else
1833  {
1834  for (i = dim() - 1; i >= 0; --i)
1835  {
1836  if (baseId(i).isSPxColId())
1837  p_vector[ number(SPxColId(baseId(i))) ] = fVec()[i];
1838  }
1839  }
1840  }
1841  else
1842  {
1843  p_vector = maxObj();
1844  p_vector -= pVec();
1845  if (spxSense() == SPxLP::MINIMIZE)
1846  p_vector *= -1.0;
1847  }
1848 
1849  return status();
1850 }
1851 
1853 {
1854 
1855  assert(isInitialized());
1856 
1857  if (!isInitialized())
1858  {
1859  throw SPxStatusException("XSOLVE10 No Problem loaded");
1860  // return NOT_INIT;
1861  }
1862 
1864  p_vector.clear();
1865  p_vector = primalRay;
1866 
1867  return status();
1868 }
1869 
1871 {
1872 
1873  assert(isInitialized());
1874 
1875  if (!isInitialized())
1876  {
1877  throw SPxStatusException("XSOLVE10 No Problem loaded");
1878  // return NOT_INIT;
1879  }
1880 
1882  p_vector.clear();
1883  p_vector = dualFarkas;
1884 
1885  return status();
1886 }
1887 
1889 {
1890 
1891  assert(isInitialized());
1892 
1893  if (!isInitialized())
1894  {
1895  throw SPxStatusException("XSOLVE11 No Problem loaded");
1896  // return NOT_INIT;
1897  }
1898 
1899  if (rep() == COLUMN)
1900  {
1901  int i;
1902  const SPxBasis::Desc& ds = desc();
1903  for (i = nRows() - 1; i >= 0; --i)
1904  {
1905  switch (ds.rowStatus(i))
1906  {
1908  p_vector[i] = lhs(i);
1909  break;
1912  p_vector[i] = rhs(i);
1913  break;
1914  case SPxBasis::Desc::P_FREE :
1915  p_vector[i] = 0;
1916  break;
1917  case SPxBasis::Desc::D_FREE :
1922  break;
1923  default:
1924  throw SPxInternalCodeException("XSOLVE12 This should never happen.");
1925  }
1926  }
1927  for (i = dim() - 1; i >= 0; --i)
1928  {
1929  if (baseId(i).isSPxRowId())
1930  p_vector[ number(SPxRowId(baseId(i))) ] = -(*theFvec)[i];
1931  }
1932  }
1933  else
1934  p_vector = pVec();
1935 
1936  return status();
1937 }
1938 
1940 {
1941 
1942  if (!isInitialized())
1943  {
1944  throw SPxStatusException("XSOLVE20 Not Initialized");
1945  }
1946 
1947  if (rep() == ROW)
1948  coPvec() = p_vector;
1949  else
1950  {
1951  for (int j = 0; j < dim(); ++j)
1952  {
1953  if (baseId(j).isSPxColId())
1954  fVec()[j] = p_vector[ number(SPxColId(baseId(j))) ];
1955  }
1956  }
1957 }
1958 
1960 {
1961 
1962  assert(isInitialized());
1963 
1964  if (!isInitialized())
1965  {
1966  throw SPxStatusException("XSOLVE21 Not Initialized");
1967  }
1968 
1969  if (rep() == ROW)
1970  {
1971  for (int i = nCols() - 1; i >= 0; --i)
1972  {
1973  if (baseId(i).isSPxRowId())
1974  {
1975  if (spxSense() == SPxLP::MAXIMIZE)
1976  fVec()[i] = p_vector[ number(SPxRowId(baseId(i))) ];
1977  else
1978  fVec()[i] = -p_vector[ number(SPxRowId(baseId(i))) ];
1979  }
1980  }
1981  }
1982  else
1983  {
1984  coPvec() = p_vector;
1985  if (spxSense() == SPxLP::MINIMIZE)
1986  coPvec() *= -1.0;
1987  }
1988 }
1989 
1991 {
1992 
1993  assert(isInitialized());
1994 
1995  if (!isInitialized())
1996  {
1997  throw SPxStatusException("XSOLVE22 Not Initialized");
1998  }
1999 
2000  if (rep() == ROW)
2001  {
2002  for (int i = dim() - 1; i >= 0; --i)
2003  {
2004  if (baseId(i).isSPxColId())
2005  {
2006  if (spxSense() == SPxLP::MINIMIZE)
2007  fVec()[i] = -p_vector[ number(SPxColId(baseId(i))) ];
2008  else
2009  fVec()[i] = p_vector[ number(SPxColId(baseId(i))) ];
2010  }
2011  }
2012  }
2013  else
2014  {
2015  pVec() = maxObj();
2016 
2017  if (spxSense() == SPxLP::MINIMIZE)
2018  pVec() += p_vector;
2019  else
2020  pVec() -= p_vector;
2021  }
2022 }
2023 
2025 {
2026 
2027  assert(isInitialized());
2028 
2029  if (!isInitialized())
2030  {
2031  throw SPxStatusException("XSOLVE23 Not Initialized");
2032  }
2033 
2034  if (rep() == COLUMN)
2035  {
2036  for (int i = dim() - 1; i >= 0; --i)
2037  {
2038  if (baseId(i).isSPxRowId())
2039  (*theFvec)[i] = -p_vector[ number(SPxRowId(baseId(i))) ];
2040  }
2041  }
2042  else
2043  pVec() = p_vector;
2044 }
2045 
2047 {
2048  switch( m_status )
2049  {
2050  case UNKNOWN :
2051  switch (SPxBasis::status())
2052  {
2053  case SPxBasis::NO_PROBLEM :
2054  return NO_PROBLEM;
2055  case SPxBasis::SINGULAR :
2056  return SINGULAR;
2057  case SPxBasis::REGULAR :
2058  case SPxBasis::DUAL :
2059  case SPxBasis::PRIMAL :
2060  return UNKNOWN;
2061  case SPxBasis::OPTIMAL :
2062  return OPTIMAL;
2063  case SPxBasis::UNBOUNDED :
2064  return UNBOUNDED;
2065  case SPxBasis::INFEASIBLE :
2066  return INFEASIBLE;
2067  default:
2068  return ERROR;
2069  }
2070  case SINGULAR :
2071  return m_status;
2072  case OPTIMAL :
2073  assert( SPxBasis::status() == SPxBasis::OPTIMAL );
2074  /*lint -fallthrough*/
2075  case ABORT_EXDECOMP :
2076  case ABORT_DECOMP :
2077  case ABORT_CYCLING :
2078  case ABORT_TIME :
2079  case ABORT_ITER :
2080  case ABORT_VALUE :
2081  case RUNNING :
2082  case REGULAR :
2083  case NOT_INIT :
2084  case NO_SOLVER :
2085  case NO_PRICER :
2086  case NO_RATIOTESTER :
2087  case ERROR:
2088  return m_status;
2089  default:
2090  return ERROR;
2091  }
2092 }
2093 
2095  Real* p_value,
2096  Vector* p_primal,
2097  Vector* p_slacks,
2098  Vector* p_dual,
2099  Vector* reduCosts)
2100 {
2101  if (p_value)
2102  *p_value = this->value();
2103  if (p_primal)
2104  getPrimal(*p_primal);
2105  if (p_slacks)
2106  getSlacks(*p_slacks);
2107  if (p_dual)
2108  getDual(*p_dual);
2109  if (reduCosts)
2110  getRedCost(*reduCosts);
2111  return status();
2112 }
2113 } // namespace soplex
virtual void unShift(void)
remove shift as much as possible.
Definition: spxshift.cpp:496
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
void computeFtest()
compute basis feasibility test vector.
Definition: leave.cpp:38
virtual void entered4(SPxId, int)
performs entering pivot.
Definition: spxpricer.h:213
int iterDegenCheck
number of calls to change() since last degeneracy check
Definition: spxbasis.h:390
Real boundrange
absolute range of all bounds in the problem
Definition: spxsolver.h:390
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3908
virtual void setType(SPxSolver::Type)
sets Simplex type.
SPxId coId(int i) const
id of i &#39;th covector.
Definition: spxsolver.h:1096
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:545
bool enter(SPxId &id, bool polish=false)
Definition: enter.cpp:1091
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
Vector & multWithBase(Vector &x) const
Vector-basis product.
Definition: spxbasis.cpp:940
SoPlex start basis generation base class.
virtual Real shift() const
total current shift amount.
Definition: spxsolver.h:1606
int iterations() const
get number of iterations of current solution.
Definition: spxsolver.h:2095
Basis is dual feasible.
Definition: spxbasis.h:95
not initialised error
Definition: spxsolver.h:207
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:719
virtual SPxId selectEnter()=0
selects Id to enter basis.
primal variable is fixed to both bounds
Definition: spxbasis.h:190
virtual Real getDelta()
get allowed bound violation
int boundflips
number of performed bound flips
Definition: spxsolver.h:376
primal or dual variable is undefined
Definition: spxbasis.h:195
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:456
#define MAXSTALLRECOVERS
Definition: spxsolve.cpp:30
const Vector & fTest() const
Violations of fVec.
Definition: spxsolver.h:1364
virtual Status getPrimal(Vector &vector) const
get solution vector for primal variables.
Definition: spxsolve.cpp:1729
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:419
SPxOut * spxout
message handler
Definition: spxsolver.h:445
bool sparsePricingLeave
These values enable or disable sparse pricing.
Definition: spxsolver.h:430
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
Type
Algorithmic type.
Definition: spxsolver.h:123
bool leave(int i, bool polish=false)
Definition: leave.cpp:644
Pricing pricing() const
return current Pricing.
Definition: spxsolver.h:499
Real objrange
absolute range of all objective coefficients in the problem
Definition: spxsolver.h:392
void testBounds() const
Definition: spxbounds.cpp:311
DVector theCoTest
Definition: spxsolver.h:365
virtual void qualRedCostViolation(Real &maxviol, Real &sumviol) const
get violation of optimality criterion.
Definition: spxquality.cpp:118
Abstract pricer base class.
int size() const
Number of used indices.
Definition: svectorbase.h:152
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:777
SSVector * solveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:274
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:102
int updateCount
number of calls to change() since last factorize()
Definition: spxbasis.h:391
minimize number of basic slack variables, i.e. more variables in between bounds
Definition: spxsolver.h:231
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
Real feastol() const
allowed primal feasibility tolerance.
Definition: spxsolver.h:784
Status & rowStatus(int i)
Definition: spxbasis.h:239
int lastIndex() const
returns index in basis where last update was done.
Definition: spxbasis.h:533
bool sparsePricingEnterCo
true if sparsePricing is turned on in the entering Simplex
Definition: spxsolver.h:432
virtual void qualBoundViolation(Real &maxviol, Real &sumviol) const
get violations of bounds.
Definition: spxquality.cpp:60
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
Definition: spxdefines.h:388
void setType(Type tp)
set LEAVE or ENTER algorithm.
Definition: spxsolver.cpp:169
Abstract ratio test base class.
solve() aborted due to iteration limit.
Definition: spxsolver.h:212
DataArray< int > isInfeasible
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:426
No Problem has been loaded.
Definition: spxsolver.h:215
Real length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: vectorbase.h:397
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:522
void clear()
removes all indices.
Definition: idxset.h:184
virtual bool noViols(Real tol) const
check for violations above tol and immediately return false w/o checking the remaining values ...
Definition: spxsolver.cpp:686
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:539
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1054
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:979
Real getFastCondition(int type=0)
Definition: spxbasis.cpp:1123
LP has been proven to be primal infeasible.
Definition: spxsolver.h:221
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:252
bool isTimeLimitReached(const bool forceCheck=false)
returns whether current time limit is reached; call to time() may be skipped unless forceCheck is tru...
Definition: spxsolver.cpp:1578
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
Real time() const
time spent in last call to method solve().
Definition: spxsolver.h:2120
int getDecompIterationLimit() const
returns the iteration limit for the decomposition simplex initialisation
Definition: spxsolver.h:2242
static void setScientific(std::ostream &stream, int precision=8)
Sets the precision of the stream to 16 and the floatfield to scientifix.
Definition: spxout.h:171
void setDegenCompOffset(int iterOffset)
sets the offset for the number of iterations before the degeneracy is computed
Definition: spxsolver.h:2223
void setPrimal(Vector &p_vector)
Definition: spxsolve.cpp:1939
virtual Real value()
current objective value.
Definition: spxsolver.cpp:876
rowwise representation.
Definition: spxsolver.h:106
virtual void computeLeaveCoPrhs()
compute theCoPrhs for leaving Simplex.
Definition: spxvecs.cpp:478
Basis is singular.
Definition: spxbasis.h:93
int lastIterCount
number of calls to change() before halting the simplex
Definition: spxbasis.h:389
maximize number of basic slack variables, i.e. more variables on bounds
Definition: spxsolver.h:230
dual variable is left free, but unset
Definition: spxbasis.h:191
Real getDegeneracyLevel(Vector degenvec)
get level of dual degeneracy
Definition: spxsolver.cpp:1892
Wrapper for different output streams and verbosity levels.
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
No ratiotester loaded.
Definition: spxsolver.h:204
No pricer loaded.
Definition: spxsolver.h:205
virtual void start()=0
start timer, resume accounting user, system and real time.
Entering Simplex.
Definition: spxsolver.h:133
virtual Real stop()=0
stop timer, return accounted user time.
std::ostream & getCurrentStream() const
Returns the stream for the current verbosity.
Definition: spxout.h:164
const Vector & fRhs() const
right-hand side vector for fVec
Definition: spxsolver.h:1315
virtual int getFactorCount() const =0
get number of factorizations
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
UpdateVector & coPvec() const
copricing vector.
Definition: spxsolver.h:1377
void remove(int n, int m)
removes indices at position numbers n through m.
Definition: idxset.cpp:49
virtual Status getDualfarkas(Vector &vector) const
get dual farkas proof of infeasibility.
Definition: spxsolve.cpp:1870
int m_numCycle
actual number of degenerate steps so far.
Definition: spxsolver.h:269
int maxIters
maximum allowed iterations.
Definition: spxsolver.h:249
Leaving Simplex.
Definition: spxsolver.h:142
Real m_entertol
feasibility tolerance maintained during entering algorithm
Definition: spxsolver.h:264
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
SPxStarter * thestarter
Definition: spxsolver.h:388
double Real
Definition: spxdefines.h:218
SSVector * coSolveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:278
bool isColBasic(int i) const
is the i &#39;th column vector basic ?
Definition: spxsolver.h:1275
#define MAXIMUM(x, y)
Definition: spxdefines.h:246
void setSlacks(Vector &p_vector)
Definition: spxsolve.cpp:2024
void setStatus(SPxStatus stat)
sets basis SPxStatus to stat.
Definition: spxbasis.h:431
DVector * theFrhs
Definition: spxsolver.h:344
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
Status status() const
Status of solution process.
Definition: spxsolve.cpp:2046
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:400
virtual void left4(int, SPxId)
performs leaving pivot.
Definition: spxpricer.h:185
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:510
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:234
Real m_pricingViol
maximal feasibility violation of current solution
Definition: spxsolver.h:259
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:770
UpdateVector * thePvec
Definition: spxsolver.h:352
void performSolutionPolishing()
Definition: spxsolve.cpp:1120
int size() const
returns the number of used indices.
Definition: idxset.h:124
LP has been solved to optimality.
Definition: spxsolver.h:219
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:120
virtual bool precisionReached(Real &newpricertol) const
is the solution precise enough, or should we increase delta() ?
Definition: spxsolve.cpp:37
SPxPricer * thepricer
Definition: spxsolver.h:386
SPxId id(int i) const
id of i &#39;th vector.
Definition: spxsolver.h:1077
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1302
Wrapper for GMP types.
SPxId instableEnterId
Definition: spxsolver.h:295
bool isSPxColId() const
is id a column id?
Definition: spxid.h:165
dual variable is set to its upper bound
Definition: spxbasis.h:192
solve() aborted due to commence decomposition simplex
Definition: spxsolver.h:209
solve() aborted due to time limit.
Definition: spxsolver.h:211
main LP solver class
an error occured.
Definition: spxsolver.h:203
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1242
primal variable is left free, but unset
Definition: spxbasis.h:189
Real siderange
absolute range of all side in the problem
Definition: spxsolver.h:391
void setDual(Vector &p_vector)
Definition: spxsolve.cpp:1959
solve() aborted to exit decomposition simplex
Definition: spxsolver.h:208
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
bool getComputeDegeneracy() const
returns whether the degeneracy is computed in each iteration
Definition: spxsolver.h:2216
Real getEstimatedCondition()
Definition: spxbasis.h:607
#define MINIMUM(x, y)
Definition: spxdefines.h:247
int primalCount
number of primal iterations
Definition: spxsolver.h:373
Basis descriptor.
Definition: spxbasis.h:104
Dynamic index set.Class DIdxSet provides dynamic IdxSet in the sense, that no restrictions are posed ...
Definition: didxset.h:42
int getDegenCompOffset() const
gets the offset for the number of iterations before the degeneracy is computed
Definition: spxsolver.h:2230
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:431
int leaveCycles
the number of degenerate steps during the leaving algorithm
Definition: spxsolver.h:380
virtual void generate(SPxSolver &base)=0
generates start basis for loaded basis.
algorithm is running
Definition: spxsolver.h:217
const VectorBase< R > & maxRowObj() const
Definition: spxlpbase.h:297
Timer * theTime
time spent in last call to method solve()
Definition: spxsolver.h:246
virtual void setDelta(Real newDelta)
set allowed bound violation
Status & colStatus(int i)
Definition: spxbasis.h:254
Real m_leavetol
feasibility tolerance maintained during leaving algorithm
Definition: spxsolver.h:265
SPxId & baseId(int i)
Definition: spxbasis.h:503
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:122
Real m_pricingViolCo
maximal feasibility violation of current solution in coDim
Definition: spxsolver.h:261
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:765
Debugging, floating point type and parameter definitions.
virtual void loadBasis(const SPxBasis::Desc &)
set a start basis.
Definition: spxsolver.cpp:92
virtual void setEpsilon(Real eps)
sets violation bound.
Definition: spxpricer.h:138
#define MAXSTALLS
Definition: spxsolve.cpp:29
Status getResult(Real *value=0, Vector *primal=0, Vector *slacks=0, Vector *dual=0, Vector *reduCost=0)
get all results of last solve.
Definition: spxsolve.cpp:2094
int totalboundflips
total number of bound flips
Definition: spxsolver.h:377
int polishCount
number of solution polishing iterations
Definition: spxsolver.h:374
SolutionPolish polishObj
objective of solution polishing
Definition: spxsolver.h:245
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1457
Full pricing.
Definition: spxsolver.h:159
SSVector * solveVector2
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:272
DIdxSet infeasibilities
Definition: spxsolver.h:413
bool isInitialized() const
has the internal data been initialized?
Definition: spxsolver.h:1829
Status m_status
status of algorithm.
Definition: spxsolver.h:254
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
Everything should be within this namespace.
virtual void setType(SPxSolver::Type)
sets pricing type.
Definition: spxpricer.h:149
virtual bool terminate()
Termination criterion.
Definition: spxsolve.cpp:1537
bool EQrel(Real a, Real b, Real eps=Param::epsilon())
returns true iff |relDiff(a,b)| <= eps
Definition: spxdefines.h:424
Real theCumulativeTime
cumulative time spent in all calls to method solve()
Definition: spxsolver.h:248
UpdateVector * theFvec
Definition: spxsolver.h:346
Real dualDegenSum
the sum of the dual degeneracy percentage
Definition: spxsolver.h:384
SPxId lastLeft() const
returns SPxId of last vector that left the basis.
Definition: spxbasis.h:527
virtual void printDisplayLine(const bool force=false, const bool forceHead=false)
print display line of flying table
Definition: spxsolve.cpp:1500
solve() aborted due to detection of cycling.
Definition: spxsolver.h:210
int prevIteration() const
returns the number of iterations prior to the last break in execution
Definition: spxbasis.h:551
virtual SPxSolver * solver() const
returns loaded LP solver.
#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< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:429
virtual void clearUpdateVecs(void)
Definition: spxsolver.cpp:521
int leaveCount
number of LEAVE iterations
Definition: spxsolver.h:371
nothing known on loaded problem.
Definition: spxsolver.h:218
don&#39;t perform modifications on optimal basis
Definition: spxsolver.h:229
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:204
void computeFrhs()
compute feasibility vector from scratch.
Definition: spxvecs.cpp:42
virtual Real epsilon() const
returns violation bound theeps.
Definition: spxpricer.h:130
void clear()
Set vector to 0.
Definition: vectorbase.h:260
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:160
SPxRatioTester * theratiotester
Definition: spxsolver.h:387
DVector * theCoPrhs
Definition: spxsolver.h:349
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:150
dual variable is set to its lower bound
Definition: spxbasis.h:193
int enterCycles
the number of degenerate steps during the entering algorithm
Definition: spxsolver.h:379
DSVector primalRay
stores primal ray in case of unboundedness
Definition: spxsolver.h:368
int size() const
return nr. of elements.
Definition: dataarray.h:211
#define MAXREFACPIVOTS
Definition: spxsolve.cpp:31
Type type() const
return current Type.
Definition: spxsolver.h:493
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:427
virtual SPxSolver * solver() const
returns loaded SPxSolver object.
Definition: spxpricer.h:124
int coDim() const
codimension.
Definition: spxsolver.h:1059
virtual Status getRedCost(Vector &vector) const
get vector of reduced costs.
Definition: spxsolve.cpp:1809
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:434
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:118
DSVector dualFarkas
stores dual farkas proof in case of infeasibility
Definition: spxsolver.h:369
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
int enterCount
number of ENTER iterations
Definition: spxsolver.h:372
const SLinSolver * slinSolver() const
return loaded SLinSolver.
Definition: spxsolver.h:1755
int printCondition
printing the current condition number in the log (0 - off, 1 - estimate,exact, 2 - exact)";ratio esti...
Definition: spxsolver.h:311
bool LErel(Real a, Real b, Real eps=Param::epsilon())
returns true iff relDiff(a,b) <= eps
Definition: spxdefines.h:442
bool isCoBasic(int i) const
is the i &#39;th covector basic ?
Definition: spxsolver.h:1287
DataArray< int > integerVariables
supplementary variable information, 0: continous variable, 1: integer variable
Definition: spxsolver.h:447
dual variable has two bounds
Definition: spxbasis.h:194
Real maxTime
maximum allowed time.
Definition: spxsolver.h:250
virtual int selectLeave()=0
returns selected index to leave basis.
bool recomputedVectors
flag to perform clean up step to reduce numerical errors only once
Definition: spxsolver.h:299
Exception class for status exceptions during the computationsThis class is derived from the SoPlex ex...
Definition: exceptions.h:89
virtual void init()
intialize data structures.
Definition: spxsolver.cpp:305
SPxId lastEntered() const
returns SPxId of last vector included to the basis.
Definition: spxbasis.h:521
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
void forceRecompNonbasicValue()
Definition: spxsolver.h:651
virtual void qualConstraintViolation(Real &maxviol, Real &sumviol) const
get violation of constraints.
Definition: spxquality.cpp:25
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:631
DIdxSet updateViolsCo
Definition: spxsolver.h:420
Textbook ratio test for SoPlex.
Real opttol() const
allowed optimality, i.e., dual feasibility tolerance.
Definition: spxsolver.h:792
virtual void reset()=0
initialize timer, set timing accounts to zero.
bool isRowBasic(int i) const
is the i &#39;th row vector basic ?
Definition: spxsolver.h:1269
int index(int n) const
access n &#39;th index.
Definition: idxset.h:118
Real objLimit
< the number of calls to the method isTimeLimitReached()
Definition: spxsolver.h:253
void setDecompIterationLimit(int iterationLimit)
sets the iteration limit for the decomposition simplex initialisation
Definition: spxsolver.h:2236
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:498
virtual void load(SPxSolver *lp, bool initSlackBasis=true)
loads the LP lp to the basis.
Definition: spxbasis.cpp:326
bool getStartingDecompBasis
flag to indicate whether the simplex is solved to get the starting improved dual simplex basis ...
Definition: spxsolver.h:305
UpdateVector * theCoPvec
Definition: spxsolver.h:350
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1740
int iterCount
number of calls to change() since last manipulation
Definition: spxbasis.h:388
Status
Status of a variable.
Definition: spxbasis.h:185
SSVector * coSolveVector2
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:276
const VectorBase< R > & obj() const
Returns the vector of objective coefficients.
Definition: lprowsetbase.h:167
virtual Status solve()
solve loaded LP.
Definition: spxsolve.cpp:130
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
virtual Real maxInfeas() const
maximal infeasibility of basis
Definition: spxsolver.cpp:641
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:416
bool hyperPricingLeave
true if hyper sparse pricing is turned on in the leaving Simplex
Definition: spxsolver.h:433
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
const Desc & desc() const
Definition: spxbasis.h:463
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:487
solve() aborted due to objective limit.
Definition: spxsolver.h:213
columnwise representation.
Definition: spxsolver.h:107
void setRedCost(Vector &p_vector)
Definition: spxsolve.cpp:1990
#define MAXCYCLES
Definition: spxsolve.cpp:28
virtual Status getDual(Vector &vector) const
get current solution vector for dual variables.
Definition: spxsolve.cpp:1778
Basis is singular, numerical troubles?
Definition: spxsolver.h:214
virtual Status getPrimalray(Vector &vector) const
get primal ray in case of unboundedness.
Definition: spxsolve.cpp:1852
virtual void factorize()
Factorize basis matrix.
Definition: spxsolver.cpp:536
Basis is primal feasible.
Definition: spxbasis.h:96
int lastDegenCheck() const
returns the number of iterations since the last degeneracy check
Definition: spxbasis.h:557
LP has a usable Basis (maybe LP is changed).
Definition: spxsolver.h:216
bool matrixIsSetup
true iff the pointers in matrix are set up correctly.
Definition: spxbasis.h:349
virtual Status getSlacks(Vector &vector) const
get vector of slack variables.
Definition: spxsolve.cpp:1888
void setBasisStatus(SPxBasis::SPxStatus stat)
set the lp solver&#39;s basis status.
Definition: spxsolver.h:2029
LP has been proven to be primal unbounded.
Definition: spxsolver.h:220
LP has been proven to be primal infeasible.
Definition: spxbasis.h:99
No Problem has been loaded to the basis.
Definition: spxbasis.h:92
No linear solver loaded.
Definition: spxsolver.h:206
void computeCoTest()
compute coTest vector.
Definition: enter.cpp:228
void calculateProblemRanges()
determine ranges of problem values for bounds, sides and objective to assess numerical difficulties ...
Definition: spxsolve.cpp:73
Real primalDegenSum
the sum of the primal degeneracy percentage
Definition: spxsolver.h:383