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