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