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