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-2016 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  if (!isInitialized())
117  {
118  /*
119  if(SPxBasis::status() <= NO_PROBLEM)
120  SPxBasis::load(this);
121  */
122  /**@todo != REGULAR is not enough. Also OPTIMAL/DUAL/PRIMAL should
123  * be tested and acted accordingly.
124  */
125  if (thestarter != 0 && status() != REGULAR) // no basis and no starter.
126  thestarter->generate(*this); // generate start basis.
127 
128  init();
129 
130  // Inna/Tobi: init might fail, if the basis is singular
131  if( !isInitialized() )
132  {
134  m_status = UNKNOWN;
135  return status();
136  }
137  }
138 
139  //setType(type());
140 
141  if (!matrixIsSetup)
142  SPxBasis::load(this);
143 
144  //factorized = false;
145 
146  assert(thepricer->solver() == this);
147  assert(theratiotester->solver() == this);
148 
149  // maybe this should be done in init() ?
150  thepricer->setType(type());
152 
153  MSG_INFO3( (*spxout),
154  (*spxout) << "starting value = " << value() << std::endl
155  << "starting shift = " << shift() << std::endl;
156  )
157 
160 
161  m_status = RUNNING;
162  bool stop = terminate();
163  leaveCount = 0;
164  enterCount = 0;
165  primalCount = 0;
166  boundflips = 0;
167  totalboundflips = 0;
168 
169  stallNumRecovers = 0;
170 
171  /* if we run into a singular basis, we will retry from regulardesc with tighter tolerance in the ratio test */
172  SPxSolver::Type tightenedtype = type();
173  bool tightened = false;
174 
175  while (!stop)
176  {
177  const SPxBasis::Desc regulardesc = desc();
178 
179  // we need to reset these pointers to avoid unnecessary/wrong solves in leave() or enter()
180  solveVector2 = 0;
181  solveVector3 = 0;
182  coSolveVector2 = 0;
183  coSolveVector3 = 0;
184 
185  updateViols.clear();
187 
188  try
189  {
190 
191  if (type() == ENTER)
192  {
194 
195  int enterCycleCount = 0;
196  int enterFacPivotCount = 0;
197 
198  instableEnterVal = 0;
200  instableEnter = false;
201 
202  stallRefIter = iteration()-1;
203  stallRefShift = shift();
204  stallRefValue = value();
205 
206  /* in the entering algorithm, entertol() should be maintained by the ratio test and leavetol() should be
207  * reached by the pricer
208  */
209  Real maxpricertol = leavetol();
210  Real minpricertol = 0.01 * maxpricertol;
211 
212  thepricer->setEpsilon(maxpricertol);
213  priced = false;
214 
215  // to avoid shifts we restrict tolerances in the ratio test
216  if( loopCount > 0 )
217  {
218  lastDelta = (lastDelta < entertol()) ? lastDelta : entertol();
219  lastDelta *= 0.01;
220  theratiotester->setDelta(lastDelta);
221  assert(theratiotester->getDelta() > 0);
222  MSG_DEBUG( std::cout << "decreased delta for ratiotest to: " << theratiotester->getDelta() << std::endl; )
223  }
224  else
225  {
226  lastDelta = 1;
228  }
229 
230  printDisplayLine(true);
231  do
232  {
234 
235  enterId = thepricer->selectEnter();
236 
237  if (!enterId.isValid() && instableEnterId.isValid() && lastUpdate() == 0)
238  {
239  /* no entering variable was found, but because of valid instableEnterId we know
240  that this is due to the scaling of the test values. Thus, we use
241  instableEnterId and SPxFastRT::selectEnter shall accept even an instable
242  leaving variable. */
243  MSG_INFO3( (*spxout), (*spxout) << " --- trying instable enter iteration" << std::endl; )
244 
245  enterId = instableEnterId;
246  instableEnter = true;
247  // we also need to reset the test() or coTest() value for getEnterVals()
248  assert(instableEnterVal < 0);
249  if( enterId.isSPxColId() )
250  {
251  int idx = number(SPxColId(enterId));
252  if( rep() == COLUMN )
253  {
254  theTest[idx] = instableEnterVal;
256  {
259  }
260  if( hyperPricingEnter )
261  updateViolsCo.addIdx(idx);
262  }
263  else
264  {
267  {
268  infeasibilities.addIdx(idx);
270  }
271  if( hyperPricingEnter )
272  updateViols.addIdx(idx);
273  }
274  }
275  else
276  {
277  int idx = number(SPxRowId(enterId));
278  if( rep() == COLUMN )
279  {
282  {
283  infeasibilities.addIdx(idx);
285  }
286  if( hyperPricingEnter )
287  updateViols.addIdx(idx);
288  }
289  else
290  {
291  theTest[idx] = instableEnterVal;
293  {
296  }
297  if( hyperPricingEnter )
298  updateViolsCo.addIdx(idx);
299  }
300  }
301  }
302  else
303  {
304  instableEnter = false;
305  }
306 
307  if (!enterId.isValid())
308  {
309  // we are not infeasible and have no shift
310  if ( shift() <= epsilon()
314  {
315  Real newpricertol = minpricertol;
316 
317  MSG_INFO2( (*spxout), (*spxout) << " --- checking feasibility and optimality\n")
318  computeTest();
319  computeCoTest();
320 
321  // is the solution good enough ?
322  // max three times reduced
323  if ((thepricer->epsilon() > minpricertol) && !precisionReached(newpricertol))
324  { // no!
325  // we reduce the pricer tolerance. Note that if the pricer does not find a candiate
326  // with the reduced tolerance, we quit, regardless of the violations.
327  if (newpricertol < minpricertol)
328  newpricertol = minpricertol;
329 
330  thepricer->setEpsilon(newpricertol);
331 
332  MSG_INFO2( (*spxout), (*spxout) << " --- setting pricer tolerance to "
333  << thepricer->epsilon()
334  << std::endl; )
335  }
336  // solution seems good, no check whether we are precise enough
337  else if (lastUpdate() == 0)
338  {
339  priced = true;
340  break;
341  }
342  // We have an iterationlimit and everything looks good? Then stop!
343  // 6 is just a number picked.
344  else if (!(instableEnterId.isValid()) && maxIters > 0 && lastUpdate() < 6)
345  {
346  priced = true;
347  break;
348  }
349  }
350  MSG_INFO3( (*spxout), (*spxout) << " --- solve(enter) triggers refactorization" << std::endl; )
351 
352  // if the factorization is not fresh, we better refactorize and call the pricer again; however, this can
353  // create cycling, so it is performed only a limited number of times per ENTER round
354  if( lastUpdate() > 0 && enterFacPivotCount < MAXREFACPIVOTS )
355  {
356  factorize();
357 
358  // if the factorization was found out to be singular, we have to quit
360  {
361  MSG_ERROR( std::cerr << "Something wrong with factorization, Basis status: " << SPxBasis::status() << std::endl; )
362  stop = true;
363  break;
364  }
365 
366  // call pricer again
367  enterId = thepricer->selectEnter();
368 
369  // count how often the pricer has found something only after refactorizing
370  if( enterId.isValid() )
371  enterFacPivotCount++;
372  }
373 
374  if( !enterId.isValid() )
375  {
376  priced = true;
377  break;
378  }
379  }
380 
381  /* check if we have iterations left */
382  if (maxIters >= 0 && iterations() >= maxIters)
383  {
384  MSG_INFO2( (*spxout), (*spxout) << " --- maximum number of iterations (" << maxIters
385  << ") reached" << std::endl; )
387  stop = true;
388  break;
389  }
390 
391  enter(enterId);
392  assert((testBounds(), 1));
394  stop = terminate();
395  clearUpdateVecs();
396 
397  /* if a successful pivot was performed or a nonbasic variable was flipped to its other bound, we reset the
398  * cycle counter
399  */
400  if( lastEntered().isValid() )
401  enterCycleCount = 0;
402  else
403  {
404  enterCycleCount++;
405  if( enterCycleCount > MAXCYCLES )
406  {
407  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to cycling in "
408  << "entering algorithm" << std::endl; );
410  stop = true;
411  }
412  }
413 
414  /* only if the basis has really changed, we increase the iterations counter; this is not the case when only
415  * a nonbasic variable was flipped to its other bound
416  */
417  if( lastIndex() >= 0 )
418  {
419  enterCount++;
420  assert(lastEntered().isValid());
421  }
422 
423  /* check every MAXSTALLS iterations whether shift and objective value have not changed */
424  if( (iteration() - stallRefIter) % MAXSTALLS == 0 )
425  {
426  if( spxAbs(value() - stallRefValue) <= epsilon() && spxAbs(shift() - stallRefShift) <= epsilon() )
427  {
428  if( stallNumRecovers < MAXSTALLRECOVERS )
429  {
430  /* try to recover by unshifting/switching algorithm up to MAXSTALLRECOVERS times (just a number picked) */
431  MSG_INFO3( (*spxout), (*spxout) << " --- stalling detected - trying to recover by switching to LEAVING algorithm." << std::endl; )
432 
433  ++stallNumRecovers;
434  break;
435  }
436  else
437  {
438  /* giving up */
439  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to stalling in entering algorithm." << std::endl; );
440 
442  stop = true;
443  }
444  }
445  else
446  {
447  /* merely update reference values */
448  stallRefIter = iteration()-1;
449  stallRefShift = shift();
450  stallRefValue = value();
451  }
452  }
453 
454  //@ assert(isConsistent());
455  }
456  while (!stop);
457 
458  MSG_INFO3( (*spxout),
459  (*spxout) << " --- enter finished. iteration: " << iteration()
460  << ", value: " << value()
461  << ", shift: " << shift()
462  << ", epsilon: " << epsilon()
463  << ", feastol: " << feastol()
464  << ", opttol: " << opttol()
465  << std::endl
466  << "ISOLVE56 stop: " << stop
467  << ", basis status: " << SPxBasis::status() << " (" << int(SPxBasis::status()) << ")"
468  << ", solver status: " << m_status << " (" << int(m_status) << ")" << std::endl;
469  )
470 
471  if (!stop)
472  {
473  /**@todo technically it would be ok to finish already when (priced && maxinfeas + shift() <= entertol()) is
474  * satisfied; maybe at least in the case when SoPlex keeps jumping back between ENTER and LEAVE always
475  * shifting (looping), we may relax this condition here;
476  * note also that unShift may increase shift() slightly due to roundoff errors
477  */
478  if (shift() <= epsilon())
479  {
480  // factorize();
481  unShift();
482 
483  Real maxinfeas = maxInfeas();
484 
485  MSG_INFO3( (*spxout),
486  (*spxout) << " --- maxInfeas: " << maxinfeas
487  << ", shift: " << shift()
488  << ", entertol: " << entertol() << std::endl;
489  )
490 
491  if (priced && maxinfeas + shift() <= entertol())
492  {
494  m_status = OPTIMAL;
495  break;
496  }
497  }
498  setType(LEAVE);
499  init();
500  thepricer->setType(type());
502  }
503  }
504  else
505  {
506  assert(type() == LEAVE);
507 
509 
510  int leaveCycleCount = 0;
511  int leaveFacPivotCount = 0;
512 
513  instableLeaveNum = -1;
514  instableLeave = false;
515  instableLeaveVal = 0;
516 
517  stallRefIter = iteration()-1;
518  stallRefShift = shift();
519  stallRefValue = value();
520 
521  /* in the leaving algorithm, leavetol() should be maintained by the ratio test and entertol() should be reached
522  * by the pricer
523  */
524  Real maxpricertol = entertol();
525  Real minpricertol = 0.01 * maxpricertol;
526 
527  thepricer->setEpsilon(maxpricertol);
528  priced = false;
529 
530  // to avoid shifts we restrict tolerances in the ratio test
531  if( loopCount > 0 )
532  {
533  lastDelta = (lastDelta < leavetol()) ? lastDelta : leavetol();
534  lastDelta *= 0.01;
535  theratiotester->setDelta(lastDelta);
536  assert(theratiotester->getDelta() > 0);
537  MSG_DEBUG( std::cout << "decreased delta for ratiotest to: " << theratiotester->getDelta() << std::endl; )
538  }
539  else
540  {
541  lastDelta = 1;
543  }
544 
545  printDisplayLine(true);
546  do
547  {
549 
550  leaveNum = thepricer->selectLeave();
551 
552  if (leaveNum < 0 && instableLeaveNum >= 0 && lastUpdate() == 0)
553  {
554  /* no leaving variable was found, but because of instableLeaveNum >= 0 we know
555  that this is due to the scaling of theCoTest[...]. Thus, we use
556  instableLeaveNum and SPxFastRT::selectEnter shall accept even an instable
557  entering variable. */
558  MSG_INFO3( (*spxout),
559  (*spxout) << " --- trying instable leave iteration" << std::endl;
560  )
561 
562  leaveNum = instableLeaveNum;
563  instableLeave = true;
564  // we also need to reset the fTest() value for getLeaveVals()
565  assert(instableLeaveVal < 0);
567 
568  if ( sparsePricingLeave )
569  {
571  {
574  }
575  if( hyperPricingLeave )
577  }
578  }
579  else
580  {
581  instableLeave = false;
582  }
583 
584  if (leaveNum < 0)
585  {
586  // we are not infeasible and have no shift
587  if ( shift() <= epsilon()
591  {
592  Real newpricertol = minpricertol;
593 
594  MSG_INFO2( (*spxout), (*spxout) << " --- checking feasibility and optimality\n")
595  computeFtest();
596 
597  // is the solution good enough ?
598  // max three times reduced
599  if ((thepricer->epsilon() > minpricertol) && !precisionReached(newpricertol))
600  { // no
601  // we reduce the pricer tolerance. Note that if the pricer does not find a candiate
602  // with the reduced pricer tolerance, we quit, regardless of the violations.
603  if (newpricertol < minpricertol)
604  newpricertol = minpricertol;
605 
606  thepricer->setEpsilon(newpricertol);
607 
608  MSG_INFO2( (*spxout), (*spxout) << " --- setting pricer tolerance to "
609  << thepricer->epsilon()
610  << std::endl; );
611  }
612  // solution seems good, no check whether we are precise enough
613  else if (lastUpdate() == 0)
614  {
615  priced = true;
616  break;
617  }
618  // We have an iteration limit and everything looks good? Then stop!
619  // 6 is just a number picked.
620  else if (instableLeaveNum == -1 && maxIters > 0 && lastUpdate() < 6)
621  {
622  priced = true;
623  break;
624  }
625  }
626  MSG_INFO3( (*spxout), (*spxout) << " --- solve(leave) triggers refactorization" << std::endl; )
627 
628  // if the factorization is not fresh, we better refactorize and call the pricer again; however, this can
629  // create cycling, so it is performed only a limited number of times per LEAVE round
630  if( lastUpdate() > 0 && leaveFacPivotCount < MAXREFACPIVOTS )
631  {
632  factorize();
633 
634  // Inna/Tobi: if the factorization was found out to be singular, we have to quit
636  {
637  MSG_ERROR( std::cerr << "Something wrong with factorization, Basis status: " << SPxBasis::status() << std::endl; )
638  stop = true;
639  break;
640  }
641 
642  // call pricer again
643  leaveNum = thepricer->selectLeave();
644 
645  // count how often the pricer has found something only after refactorizing
646  if( leaveNum >= 0 )
647  leaveFacPivotCount++;
648  }
649 
650  if (leaveNum < 0)
651  {
652  priced = true;
653  break;
654  }
655  }
656 
657  /* check if we have iterations left */
658  if (maxIters >= 0 && iterations() >= maxIters)
659  {
660  MSG_INFO2( (*spxout), (*spxout) << " --- maximum number of iterations (" << maxIters
661  << ") reached" << std::endl; )
663  stop = true;
664  break;
665  }
666 
667  leave(leaveNum);
668  assert((testBounds(), 1));
670  stop = terminate();
671  clearUpdateVecs();
672 
673  /* if a successful pivot was performed or a nonbasic variable was flipped to its other bound, we reset the
674  * cycle counter
675  */
676  if( lastIndex() >= 0 )
677  leaveCycleCount = 0;
678  else
679  {
680  leaveCycleCount++;
681  if( leaveCycleCount > MAXCYCLES )
682  {
683  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to cycling in leaving algorithm" << std::endl; );
685  stop = true;
686  }
687  }
688 
689  /* only if the basis has really changed, we increase the iterations counter; this is not the case when only
690  * a nonbasic variable was flipped to its other bound
691  */
692  if( lastEntered().isValid() )
693  {
694  leaveCount++;
695  assert(lastIndex() >= 0);
696  }
697 
698  /* check every MAXSTALLS iterations whether shift and objective value have not changed */
699  if( (iteration() - stallRefIter) % MAXSTALLS == 0 )
700  {
701  if( spxAbs(value() - stallRefValue) <= epsilon() && spxAbs(shift() - stallRefShift) <= epsilon() )
702  {
703  if( stallNumRecovers < MAXSTALLRECOVERS )
704  {
705  /* try to recover by switching algorithm up to MAXSTALLRECOVERS times */
706  MSG_INFO3( (*spxout), (*spxout) << " --- stalling detected - trying to recover by switching to ENTERING algorithm." << std::endl; )
707 
708  ++stallNumRecovers;
709  break;
710  }
711  else
712  {
713  /* giving up */
714  MSG_INFO2( (*spxout), (*spxout) << " --- abort solving due to stalling in leaving algorithm" << std::endl; );
715 
717  stop = true;
718  }
719  }
720  else
721  {
722  /* merely update reference values */
723  stallRefIter = iteration()-1;
724  stallRefShift = shift();
725  stallRefValue = value();
726  }
727  }
728 
729  //@ assert(isConsistent());
730  }
731  while (!stop);
732 
733  MSG_INFO3( (*spxout),
734  (*spxout) << " --- leave finished. iteration: " << iteration()
735  << ", value: " << value()
736  << ", shift: " << shift()
737  << ", epsilon: " << epsilon()
738  << ", feastol: " << feastol()
739  << ", opttol: " << opttol()
740  << std::endl
741  << "ISOLVE57 stop: " << stop
742  << ", basis status: " << SPxBasis::status() << " (" << int(SPxBasis::status()) << ")"
743  << ", solver status: " << m_status << " (" << int(m_status) << ")" << std::endl;
744  )
745 
746  if (!stop)
747  {
748  if( shift() < minShift )
749  {
750  minShift = shift();
751  cycleCount = 0;
752  }
753  else
754  {
755  cycleCount++;
756  if( cycleCount > MAXCYCLES )
757  {
759  throw SPxStatusException("XSOLVE13 Abort solving due to cycling");
760  }
761  MSG_INFO3( (*spxout),
762  (*spxout) << " --- maxInfeas: " << maxInfeas()
763  << ", shift: " << shift()
764  << ", leavetol: " << leavetol()
765  << ", cycle count: " << cycleCount << std::endl;
766  )
767  }
768 
769  /**@todo technically it would be ok to finish already when (priced && maxinfeas + shift() <= entertol()) is
770  * satisfied; maybe at least in the case when SoPlex keeps jumping back between ENTER and LEAVE always
771  * shifting (looping), we may relax this condition here;
772  * note also that unShift may increase shift() slightly due to roundoff errors
773  */
774  if (shift() <= epsilon())
775  {
776  cycleCount = 0;
777  // factorize();
778  unShift();
779 
780  Real maxinfeas = maxInfeas();
781 
782  MSG_INFO3( (*spxout),
783  (*spxout) << " --- maxInfeas: " << maxinfeas
784  << ", shift: " << shift()
785  << ", leavetol: " << leavetol() << std::endl;
786  )
787 
788  // We stop if we are indeed optimal, or if we have already been
789  // two times at this place. In this case it seems futile to
790  // continue.
791  if (loopCount > 2)
792  {
794  throw SPxStatusException("XSOLVE14 Abort solving due to looping");
795  }
796  else if (priced && maxinfeas + shift() <= leavetol())
797  {
799  m_status = OPTIMAL;
800  break;
801  }
802  loopCount++;
803  }
804  setType(ENTER);
805  init();
806  thepricer->setType(type());
808  }
809  }
810  assert(m_status != SINGULAR);
811 
812  }
813  catch( const SPxException& E )
814  {
815  // if we stopped due to a singular basis, we reload the original basis and try again with tighter
816  // tolerance (only once)
817  if (m_status == SINGULAR && !tightened)
818  {
819  tightenedtype = type();
820 
821  if( tightenedtype == ENTER )
822  {
823  m_entertol = 0.01 * m_entertol;
824 
825  MSG_INFO2( (*spxout), (*spxout) << " --- basis singular: reloading basis and solving with tighter ratio test tolerance " << m_entertol << std::endl; )
826  }
827  else
828  {
829  m_leavetol = 0.01 * m_leavetol;
830 
831  MSG_INFO2( (*spxout), (*spxout) << " --- basis singular: reloading basis and solving with tighter ratio test tolerance " << m_leavetol << std::endl; )
832  }
833 
834  // load original basis
835  int niters = iterations();
836  loadBasis(regulardesc);
837 
838  // remember iteration count
839  iterCount = niters;
840 
841  // try initializing basis (might fail if starting basis was already singular)
842  try
843  {
844  init();
846  }
847  catch( const SPxException& Ex )
848  {
849  MSG_INFO2( (*spxout), (*spxout) << " --- reloaded basis singular, resetting original tolerances" << std::endl; )
850 
851  if( tightenedtype == ENTER )
852  m_entertol = 100.0 * m_entertol;
853  else
854  m_leavetol = 100.0 * m_leavetol;
855 
857 
858  throw Ex;
859  }
860 
861  // reset status and counters
862  m_status = RUNNING;
863  m_numCycle = 0;
864  leaveCount = 0;
865  enterCount = 0;
866  stallNumRecovers = 0;
867 
868  // continue
869  stop = false;
870  tightened = true;
871  }
872  // reset tolerance to its original value and pass on the exception
873  else if (tightened)
874  {
875  if( tightenedtype == ENTER )
876  m_entertol = 100.0 * m_entertol;
877  else
878  m_leavetol = 100.0 * m_leavetol;
879 
881 
882  throw E;
883  }
884  // pass on the exception
885  else
886  throw E;
887  }
888  }
889 
890  // reset tolerance to its original value
891  if (tightened)
892  {
893  if( tightenedtype == ENTER )
894  m_entertol = 100.0 * m_entertol;
895  else
896  m_leavetol = 100.0 * m_leavetol;
897 
899  }
900 
901  theTime->stop();
902  theCumulativeTime += time();
903 
904  if (m_status == RUNNING)
905  {
906  m_status = ERROR;
907  throw SPxStatusException("XSOLVE05 Status is still RUNNING when it shouldn't be");
908  }
909 
910  MSG_INFO3( (*spxout),
911  (*spxout) << "Finished solving (status=" << status()
912  << ", iters=" << iterCount
913  << ", leave=" << leaveCount
914  << ", enter=" << enterCount
915  << ", flips=" << totalboundflips;
916  if( status() == OPTIMAL )
917  (*spxout) << ", objValue=" << value();
918  (*spxout) << ")" << std::endl;
919  )
920 
921 #ifdef ENABLE_ADDITIONAL_CHECKS
922  /* check if solution is really feasible */
923  if( status() == OPTIMAL )
924  {
925  int c;
926  Real val;
927  DVector sol( nCols() );
928 
929  getPrimal( sol );
930 
931  for(int row = 0; row < nRows(); ++row )
932  {
933  const SVector& rowvec = rowVector( row );
934  val = 0.0;
935  for( c = 0; c < rowvec.size(); ++c )
936  val += rowvec.value( c ) * sol[rowvec.index( c )];
937 
938  if( LT( val, lhs( row ), feastol() ) ||
939  GT( val, rhs( row ), feastol() ) )
940  {
941  // Minor rhs violations happen frequently, so print these
942  // warnings only with verbose level INFO2 and higher.
943  MSG_INFO2( (*spxout), (*spxout) << "WSOLVE88 Warning! Constraint " << row
944  << " is violated by solution" << std::endl
945  << " lhs:" << lhs( row )
946  << " <= val:" << val
947  << " <= rhs:" << rhs( row ) << std::endl; )
948 
949  if( type() == LEAVE && isRowBasic( row ) )
950  {
951  // find basis variable
952  for( c = 0; c < nRows(); ++c )
953  if (basis().baseId(c).isSPxRowId()
954  && (number(basis().baseId(c)) == row))
955  break;
956 
957  assert( c < nRows() );
958 
959  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE90 basis idx:" << c
960  << " fVec:" << fVec()[c]
961  << " fRhs:" << fRhs()[c]
962  << " fTest:" << fTest()[c] << std::endl; )
963  }
964  }
965  }
966  for(int col = 0; col < nCols(); ++col )
967  {
968  if( LT( sol[col], lower( col ), feastol() ) ||
969  GT( sol[col], upper( col ), feastol() ) )
970  {
971  // Minor bound violations happen frequently, so print these
972  // warnings only with verbose level INFO2 and higher.
973  MSG_INFO2( (*spxout), (*spxout) << "WSOLVE91 Warning! Bound for column " << col
974  << " is violated by solution" << std::endl
975  << " lower:" << lower( col )
976  << " <= val:" << sol[col]
977  << " <= upper:" << upper( col ) << std::endl; )
978 
979  if( type() == LEAVE && isColBasic( col ) )
980  {
981  for( c = 0; c < nRows() ; ++c)
982  if ( basis().baseId( c ).isSPxColId()
983  && ( number( basis().baseId( c ) ) == col ))
984  break;
985 
986  assert( c < nRows() );
987  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE92 basis idx:" << c
988  << " fVec:" << fVec()[c]
989  << " fRhs:" << fRhs()[c]
990  << " fTest:" << fTest()[c] << std::endl; )
991  }
992  }
993  }
994  }
995 #endif // ENABLE_ADDITIONAL_CHECKS
996 
998  ? enterCount
999  : leaveCount;
1000 
1001  printDisplayLine(true);
1002  return status();
1003 }
1004 
1006 {
1007 
1009 
1010  DVector tmp(dim());
1011 
1012  tmp = *theCoPvec;
1013  multWithBase(tmp);
1014  tmp -= *theCoPrhs;
1015  if (tmp.length() > leavetol())
1016  {
1017  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE93 " << iteration() << ":\tcoP error = \t"
1018  << tmp.length() << std::endl; )
1019 
1020  tmp.clear();
1022  multWithBase(tmp);
1023  tmp -= *theCoPrhs;
1024  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE94\t\t" << tmp.length() << std::endl; )
1025 
1026  tmp.clear();
1028  tmp -= *theCoPvec;
1029  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE95\t\t" << tmp.length() << std::endl; )
1030  }
1031 
1032  tmp = *theFvec;
1033  multBaseWith(tmp);
1034  tmp -= *theFrhs;
1035  if (tmp.length() > entertol())
1036  {
1037  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE96 " << iteration() << ":\t F error = \t"
1038  << tmp.length() << std::endl; )
1039 
1040  tmp.clear();
1041  SPxBasis::solve(tmp, *theFrhs);
1042  tmp -= *theFvec;
1043  MSG_INFO3( (*spxout), (*spxout) << "ISOLVE97\t\t" << tmp.length() << std::endl; )
1044  }
1045 
1046  if (type() == ENTER)
1047  {
1048  for (int i = 0; i < dim(); ++i)
1049  {
1050  if (theCoTest[i] < -leavetol() && isCoBasic(i))
1051  {
1052  /// @todo Error message "this shalt not be": shalt this be an assert (also below)?
1053  MSG_ERROR( std::cerr << "ESOLVE98 testVecs: theCoTest: this shalt not be!"
1054  << std::endl
1055  << " i=" << i
1056  << ", theCoTest[i]=" << theCoTest[i]
1057  << ", leavetol()=" << leavetol() << std::endl; )
1058  }
1059  }
1060 
1061  for (int i = 0; i < coDim(); ++i)
1062  {
1063  if (theTest[i] < -leavetol() && isBasic(i))
1064  {
1065  MSG_ERROR( std::cerr << "ESOLVE99 testVecs: theTest: this shalt not be!"
1066  << std::endl
1067  << " i=" << i
1068  << ", theTest[i]=" << theTest[i]
1069  << ", leavetol()=" << leavetol() << std::endl; )
1070  }
1071  }
1072  }
1073 }
1074 
1075 
1076 /// print display line of flying table
1077 void SPxSolver::printDisplayLine(const bool force)
1078 {
1079  MSG_INFO1( (*spxout),
1080  if( displayLine % (displayFreq*30) == 0 )
1081  {
1082  (*spxout) << "type | time | iters | facts | shift |violation | value\n";
1083  }
1084  if( force || (displayLine % displayFreq == 0) )
1085  {
1086  (type() == LEAVE) ? (*spxout) << " L |" : (*spxout) << " E |";
1087  (*spxout) << std::fixed << std::setw(7) << std::setprecision(1) << time() << " |";
1088  (*spxout) << std::scientific << std::setprecision(2);
1089  (*spxout) << std::setw(8) << iteration() << " | "
1090  << std::setw(5) << slinSolver()->getFactorCount() << " | "
1091  << shift() << " | "
1092  << MAXIMUM(0.0, m_pricingViol + m_pricingViolCo) << " | "
1093  << std::setprecision(8) << value() + objOffset()
1094  << std::endl;
1095  }
1096  displayLine++;
1097  );
1098 }
1099 
1100 
1102 {
1103 #ifdef ENABLE_ADDITIONAL_CHECKS
1105  testVecs();
1106 #endif
1107 
1108  int redo = dim();
1109  if (redo < 1000)
1110  redo = 1000;
1111 
1112  if (iteration() > 10 && iteration() % redo == 0)
1113  {
1114 #ifdef ENABLE_ADDITIONAL_CHECKS
1115  DVector cr(*theCoPrhs);
1116  DVector fr(*theFrhs);
1117 #endif
1118 
1119  if (type() == ENTER)
1121  else
1123 
1124  computeFrhs();
1125 
1126 #ifdef ENABLE_ADDITIONAL_CHECKS
1127  cr -= *theCoPrhs;
1128  fr -= *theFrhs;
1129  if (cr.length() > leavetol())
1130  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE50 unexpected change of coPrhs "
1131  << cr.length() << std::endl; )
1132  if (fr.length() > entertol())
1133  MSG_WARNING( (*spxout), (*spxout) << "WSOLVE51 unexpected change of Frhs "
1134  << fr.length() << std::endl; )
1135 #endif
1136 
1137  if (updateCount > 1)
1138  {
1139  MSG_INFO3( (*spxout), (*spxout) << " --- terminate triggers refactorization"
1140  << std::endl; )
1141  factorize();
1142  }
1145 
1146  if (pricing() == FULL)
1147  {
1148  computePvec();
1149  if (type() == ENTER)
1150  computeTest();
1151  }
1152 
1153  if (shift() > 0.0)
1154  unShift();
1155  }
1156 
1157  // check time limit and objective limit only for non-terminal bases
1160  {
1161  m_status = UNKNOWN;
1162  return true;
1163  }
1164 
1165  if ( isTimeLimitReached() )
1166  {
1167  MSG_INFO2( (*spxout), (*spxout) << " --- timelimit (" << maxTime
1168  << ") reached" << std::endl; )
1169  m_status = ABORT_TIME;
1170  return true;
1171  }
1172 
1173  // objLimit is set and we are running DUAL:
1174  // - objLimit is set if objLimit < infinity
1175  // - DUAL is running if rep() * type() > 0 == DUAL (-1 == PRIMAL)
1176  //
1177  // In this case we have given a objective value limit, e.g, through a
1178  // MIP solver, and we want stop solving the LP if we figure out that the
1179  // optimal value of the current LP can not be better then this objective
1180  // limit. More precisely:
1181  // - MINIMIZATION Problem
1182  // We want stop the solving process if
1183  // objLimit <= current objective value of the DUAL LP
1184  // - MAXIMIZATION Problem
1185  // We want stop the solving process if
1186  // objLimit >= current objective value of the DUAL LP
1187  if (objLimit < infinity && type() * rep() > 0)
1188  {
1189  // We have no bound shifts; therefore, we can trust the current
1190  // objective value.
1191  // It might be even possible to use this termination value in case of
1192  // bound violations (shifting) but in this case it is quite difficult
1193  // to determine if we already reached the limit.
1194  if( shift() < epsilon() && noViols(opttol() - shift()) )
1195  {
1196  // SPxSense::MINIMIZE == -1, so we have sign = 1 on minimizing
1197  if( spxSense() * (value() + objOffset()) <= spxSense() * objLimit )
1198  {
1199  MSG_INFO2( (*spxout), (*spxout) << " --- objective value limit (" << objLimit
1200  << ") reached" << std::endl; )
1201  MSG_DEBUG(
1202  (*spxout) << " --- objective value limit reached" << std::endl
1203  << " (value: " << value()
1204  << ", limit: " << objLimit << ")" << std::endl
1205  << " (spxSense: " << int(spxSense())
1206  << ", rep: " << int(rep())
1207  << ", type: " << int(type()) << ")" << std::endl;
1208  )
1209 
1211  return true;
1212  }
1213  }
1214  }
1215 
1216  return false;
1217 }
1218 
1220 {
1221 
1222  if (!isInitialized())
1223  {
1224  /* exit if presolving/simplifier cleared the problem */
1225  if (status() == NO_PROBLEM)
1226  return status();
1227  throw SPxStatusException("XSOLVE06 Not Initialized");
1228  }
1229  if (rep() == ROW)
1230  p_vector = coPvec();
1231  else
1232  {
1233  const SPxBasis::Desc& ds = desc();
1234 
1235  for (int i = 0; i < nCols(); ++i)
1236  {
1237  switch (ds.colStatus(i))
1238  {
1240  p_vector[i] = SPxLP::lower(i);
1241  break;
1244  p_vector[i] = SPxLP::upper(i);
1245  break;
1246  case SPxBasis::Desc::P_FREE :
1247  p_vector[i] = 0;
1248  break;
1249  case SPxBasis::Desc::D_FREE :
1254  break;
1255  default:
1256  throw SPxInternalCodeException("XSOLVE07 This should never happen.");
1257  }
1258  }
1259  for (int j = 0; j < dim(); ++j)
1260  {
1261  if (baseId(j).isSPxColId())
1262  p_vector[ number(SPxColId(baseId(j))) ] = fVec()[j];
1263  }
1264  }
1265  return status();
1266 }
1267 
1269 {
1270 
1271  assert(isInitialized());
1272 
1273  if (!isInitialized())
1274  {
1275  /* exit if presolving/simplifier cleared the problem */
1276  if (status() == NO_PROBLEM)
1277  return status();
1278  throw SPxStatusException("XSOLVE08 No Problem loaded");
1279  }
1280 
1281  if (rep() == ROW)
1282  {
1283  int i;
1284  p_vector = maxRowObj();
1285  for (i = nCols() - 1; i >= 0; --i)
1286  {
1287  if (baseId(i).isSPxRowId())
1288  p_vector[ number(SPxRowId(baseId(i))) ] = fVec()[i];
1289  }
1290  }
1291  else
1292  p_vector = coPvec();
1293 
1294  p_vector *= Real(spxSense());
1295 
1296  return status();
1297 }
1298 
1300 {
1301 
1302  assert(isInitialized());
1303 
1304  if (!isInitialized())
1305  {
1306  throw SPxStatusException("XSOLVE09 No Problem loaded");
1307  // return NOT_INIT;
1308  }
1309 
1310  if (rep() == ROW)
1311  {
1312  int i;
1313  p_vector.clear();
1314  if (spxSense() == SPxLP::MINIMIZE)
1315  {
1316  for (i = dim() - 1; i >= 0; --i)
1317  {
1318  if (baseId(i).isSPxColId())
1319  p_vector[ number(SPxColId(baseId(i))) ] = -fVec()[i];
1320  }
1321  }
1322  else
1323  {
1324  for (i = dim() - 1; i >= 0; --i)
1325  {
1326  if (baseId(i).isSPxColId())
1327  p_vector[ number(SPxColId(baseId(i))) ] = fVec()[i];
1328  }
1329  }
1330  }
1331  else
1332  {
1333  p_vector = maxObj();
1334  p_vector -= pVec();
1335  if (spxSense() == SPxLP::MINIMIZE)
1336  p_vector *= -1.0;
1337  }
1338 
1339  return status();
1340 }
1341 
1343 {
1344 
1345  assert(isInitialized());
1346 
1347  if (!isInitialized())
1348  {
1349  throw SPxStatusException("XSOLVE10 No Problem loaded");
1350  // return NOT_INIT;
1351  }
1352 
1354  p_vector.clear();
1355  p_vector = primalRay;
1356 
1357  return status();
1358 }
1359 
1361 {
1362 
1363  assert(isInitialized());
1364 
1365  if (!isInitialized())
1366  {
1367  throw SPxStatusException("XSOLVE10 No Problem loaded");
1368  // return NOT_INIT;
1369  }
1370 
1372  p_vector.clear();
1373  p_vector = dualFarkas;
1374 
1375  return status();
1376 }
1377 
1379 {
1380 
1381  assert(isInitialized());
1382 
1383  if (!isInitialized())
1384  {
1385  throw SPxStatusException("XSOLVE11 No Problem loaded");
1386  // return NOT_INIT;
1387  }
1388 
1389  if (rep() == COLUMN)
1390  {
1391  int i;
1392  const SPxBasis::Desc& ds = desc();
1393  for (i = nRows() - 1; i >= 0; --i)
1394  {
1395  switch (ds.rowStatus(i))
1396  {
1398  p_vector[i] = lhs(i);
1399  break;
1402  p_vector[i] = rhs(i);
1403  break;
1404  case SPxBasis::Desc::P_FREE :
1405  p_vector[i] = 0;
1406  break;
1407  case SPxBasis::Desc::D_FREE :
1412  break;
1413  default:
1414  throw SPxInternalCodeException("XSOLVE12 This should never happen.");
1415  }
1416  }
1417  for (i = dim() - 1; i >= 0; --i)
1418  {
1419  if (baseId(i).isSPxRowId())
1420  p_vector[ number(SPxRowId(baseId(i))) ] = -(*theFvec)[i];
1421  }
1422  }
1423  else
1424  p_vector = pVec();
1425 
1426  return status();
1427 }
1428 
1430 {
1431 
1432  if (!isInitialized())
1433  {
1434  throw SPxStatusException("XSOLVE20 Not Initialized");
1435  }
1436 
1437  if (rep() == ROW)
1438  coPvec() = p_vector;
1439  else
1440  {
1441  for (int j = 0; j < dim(); ++j)
1442  {
1443  if (baseId(j).isSPxColId())
1444  fVec()[j] = p_vector[ number(SPxColId(baseId(j))) ];
1445  }
1446  }
1447 }
1448 
1450 {
1451 
1452  assert(isInitialized());
1453 
1454  if (!isInitialized())
1455  {
1456  throw SPxStatusException("XSOLVE21 Not Initialized");
1457  }
1458 
1459  if (rep() == ROW)
1460  {
1461  for (int i = nCols() - 1; i >= 0; --i)
1462  {
1463  if (baseId(i).isSPxRowId())
1464  {
1465  if (spxSense() == SPxLP::MAXIMIZE)
1466  fVec()[i] = p_vector[ number(SPxRowId(baseId(i))) ];
1467  else
1468  fVec()[i] = -p_vector[ number(SPxRowId(baseId(i))) ];
1469  }
1470  }
1471  }
1472  else
1473  {
1474  coPvec() = p_vector;
1475  if (spxSense() == SPxLP::MINIMIZE)
1476  coPvec() *= -1.0;
1477  }
1478 }
1479 
1481 {
1482 
1483  assert(isInitialized());
1484 
1485  if (!isInitialized())
1486  {
1487  throw SPxStatusException("XSOLVE22 Not Initialized");
1488  }
1489 
1490  if (rep() == ROW)
1491  {
1492  for (int i = dim() - 1; i >= 0; --i)
1493  {
1494  if (baseId(i).isSPxColId())
1495  {
1496  if (spxSense() == SPxLP::MINIMIZE)
1497  fVec()[i] = -p_vector[ number(SPxColId(baseId(i))) ];
1498  else
1499  fVec()[i] = p_vector[ number(SPxColId(baseId(i))) ];
1500  }
1501  }
1502  }
1503  else
1504  {
1505  pVec() = maxObj();
1506 
1507  if (spxSense() == SPxLP::MINIMIZE)
1508  pVec() += p_vector;
1509  else
1510  pVec() -= p_vector;
1511  }
1512 }
1513 
1515 {
1516 
1517  assert(isInitialized());
1518 
1519  if (!isInitialized())
1520  {
1521  throw SPxStatusException("XSOLVE23 Not Initialized");
1522  }
1523 
1524  if (rep() == COLUMN)
1525  {
1526  for (int i = dim() - 1; i >= 0; --i)
1527  {
1528  if (baseId(i).isSPxRowId())
1529  (*theFvec)[i] = -p_vector[ number(SPxRowId(baseId(i))) ];
1530  }
1531  }
1532  else
1533  pVec() = p_vector;
1534 }
1535 
1537 {
1538  switch( m_status )
1539  {
1540  case UNKNOWN :
1541  switch (SPxBasis::status())
1542  {
1543  case SPxBasis::NO_PROBLEM :
1544  return NO_PROBLEM;
1545  case SPxBasis::SINGULAR :
1546  return SINGULAR;
1547  case SPxBasis::REGULAR :
1548  case SPxBasis::DUAL :
1549  case SPxBasis::PRIMAL :
1550  return UNKNOWN;
1551  case SPxBasis::OPTIMAL :
1552  return OPTIMAL;
1553  case SPxBasis::UNBOUNDED :
1554  return UNBOUNDED;
1555  case SPxBasis::INFEASIBLE :
1556  return INFEASIBLE;
1557  default:
1558  return ERROR;
1559  }
1560  case SINGULAR :
1561  return m_status;
1562  case OPTIMAL :
1563  assert( SPxBasis::status() == SPxBasis::OPTIMAL );
1564  /*lint -fallthrough*/
1565  case ABORT_CYCLING :
1566  case ABORT_TIME :
1567  case ABORT_ITER :
1568  case ABORT_VALUE :
1569  case RUNNING :
1570  case REGULAR :
1571  case NOT_INIT :
1572  case NO_SOLVER :
1573  case NO_PRICER :
1574  case NO_RATIOTESTER :
1575  case ERROR:
1576  return m_status;
1577  default:
1578  return ERROR;
1579  }
1580 }
1581 
1583  Real* p_value,
1584  Vector* p_primal,
1585  Vector* p_slacks,
1586  Vector* p_dual,
1587  Vector* reduCosts)
1588 {
1589  if (p_value)
1590  *p_value = this->value();
1591  if (p_primal)
1592  getPrimal(*p_primal);
1593  if (p_slacks)
1594  getSlacks(*p_slacks);
1595  if (p_dual)
1596  getDual(*p_dual);
1597  if (reduCosts)
1598  getRedCost(*reduCosts);
1599  return status();
1600 }
1601 } // namespace soplex
virtual void unShift(void)
remove shift as much as possible.
Definition: spxshift.cpp:471
void computeFtest()
compute basis feasibility test vector.
Definition: leave.cpp:38
virtual void entered4(SPxId, int)
performs entering pivot.
Definition: spxpricer.h:214
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3925
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:936
virtual void setType(SPxSolver::Type)
sets Simplex type.
int coDim() const
codimension.
Definition: spxsolver.h:941
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:160
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
virtual Status getPrimal(Vector &vector) const
get solution vector for primal variables.
Definition: spxsolve.cpp:1219
SoPlex start basis generation base class.
Basis is dual feasible.
Definition: spxbasis.h:95
const SLinSolver * slinSolver() const
return loaded SLinSolver.
Definition: spxsolver.h:1631
not initialised error
Definition: spxsolver.h:196
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:406
virtual void load(SPxSolver *lp)
loads the LP lp to the basis.
Definition: spxbasis.cpp:305
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:678
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
const VectorBase< Real > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:384
int boundflips
number of performed bound flips
Definition: spxsolver.h:337
primal or dual variable has no status
Definition: spxbasis.h:195
#define MAXSTALLRECOVERS
Definition: spxsolve.cpp:30
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:363
SPxOut * spxout
message handler
Definition: spxsolver.h:384
bool sparsePricingLeave
These values enable or disable sparse pricing.
Definition: spxsolver.h:374
bool enter(SPxId &id)
Definition: enter.cpp:1091
Type
Algorithmic type.
Definition: spxsolver.h:124
virtual void qualRedCostViolation(Real &maxviol, Real &sumviol) const
get violation of optimality criterion.
Definition: spxquality.cpp:118
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:150
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:539
DVector theCoTest
Definition: spxsolver.h:327
const Vector & fTest() const
Violations of fVec.
Definition: spxsolver.h:1246
Abstract pricer base class.
SSVector * solveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:250
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:102
bool isSPxColId() const
is id a column id?
Definition: spxid.h:165
int updateCount
number of calls to change() since last factorize()
Definition: spxbasis.h:385
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:419
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
virtual Status getRedCost(Vector &vector) const
get vector of reduced costs.
Definition: spxsolve.cpp:1299
Status & rowStatus(int i)
Definition: spxbasis.h:239
bool sparsePricingEnterCo
true if sparsePricing is turned on in the entering Simplex
Definition: spxsolver.h:376
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:450
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
Definition: spxdefines.h:383
void setType(Type tp)
set LEAVE or ENTER algorithm.
Definition: spxsolver.cpp:169
bool isRowBasic(int i) const
is the i &#39;th row vector basic ?
Definition: spxsolver.h:1151
Abstract ratio test base class.
solve() aborted due to iteration limit.
Definition: spxsolver.h:199
DataArray< int > isInfeasible
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:370
No Problem has been loaded.
Definition: spxsolver.h:202
int size() const
Number of used indices.
Definition: svectorbase.h:152
bool isColBasic(int i) const
is the i &#39;th column vector basic ?
Definition: spxsolver.h:1157
void clear()
removes all indices.
Definition: idxset.h:184
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1184
const VectorBase< Real > & lower() const
Returns lower bound vector.
Definition: spxlpbase.h:420
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1339
Pricing pricing() const
return current Pricing.
Definition: spxsolver.h:418
LP has been proven to be primal infeasible.
Definition: spxsolver.h:208
R & value(int n)
Reference to value of n &#39;th nonzero.
Definition: svectorbase.h:254
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:1503
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
bool leave(int i)
Definition: leave.cpp:644
virtual Real shift() const
total current shift amount.
Definition: spxsolver.h:1482
void setPrimal(Vector &p_vector)
Definition: spxsolve.cpp:1429
const VectorBase< Real > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:402
virtual Real value()
current objective value.
Definition: spxsolver.cpp:863
rowwise representation.
Definition: spxsolver.h:107
virtual void computeLeaveCoPrhs()
compute theCoPrhs for leaving Simplex.
Definition: spxvecs.cpp:478
Real opttol() const
allowed optimality, i.e., dual feasibility tolerance.
Definition: spxsolver.h:697
Basis is singular.
Definition: spxbasis.h:93
Vector & multWithBase(Vector &x) const
Vector-basis product.
Definition: spxbasis.cpp:894
dual variable is left free, but unset
Definition: spxbasis.h:191
Wrapper for different output streams and verbosity levels.
No ratiotester loaded.
Definition: spxsolver.h:193
int iterations() const
get number of iterations of current solution.
Definition: spxsolver.h:1934
No pricer loaded.
Definition: spxsolver.h:194
const Vector & fRhs() const
right-hand side vector for fVec
Definition: spxsolver.h:1197
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.
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
int m_numCycle
actual number of degenerate steps so far.
Definition: spxsolver.h:245
int maxIters
maximum allowed iterations.
Definition: spxsolver.h:225
Leaving Simplex.
Definition: spxsolver.h:143
virtual void printDisplayLine(const bool force=false)
print display line of flying table
Definition: spxsolve.cpp:1077
Real m_entertol
feasibility tolerance maintained during entering algorithm
Definition: spxsolver.h:240
UpdateVector & coPvec() const
copricing vector.
Definition: spxsolver.h:1259
SPxStarter * thestarter
Definition: spxsolver.h:342
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:115
SSVector * coSolveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:254
virtual Status getDual(Vector &vector) const
get current solution vector for dual variables.
Definition: spxsolve.cpp:1268
void setSlacks(Vector &p_vector)
Definition: spxsolve.cpp:1514
DVector * theFrhs
Definition: spxsolver.h:309
#define MSG_DEBUG(x)
Definition: spxdefines.h:127
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
Definition: spxdefines.h:395
virtual void left4(int, SPxId)
performs leaving pivot.
Definition: spxpricer.h:186
int & index(int n)
Reference to index of n &#39;th nonzero.
Definition: svectorbase.h:236
Real m_pricingViol
maximal feasibility violation of current solution
Definition: spxsolver.h:235
SPxId lastLeft() const
returns SPxId of last vector that left the basis.
Definition: spxbasis.h:521
void testBounds() const
Definition: spxbounds.cpp:305
LP has been solved to optimality.
Definition: spxsolver.h:206
virtual Status getPrimalray(Vector &vector) const
get primal ray in case of unboundedness.
Definition: spxsolve.cpp:1342
SPxPricer * thepricer
Definition: spxsolver.h:340
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:133
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1616
Wrapper for GMP types.
SPxId instableEnterId
Definition: spxsolver.h:271
dual variable is set to its upper bound
Definition: spxbasis.h:192
solve() aborted due to time limit.
Definition: spxsolver.h:198
main LP solver class
an error occured.
Definition: spxsolver.h:192
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
primal variable is left free, but unset
Definition: spxbasis.h:189
bool isCoBasic(int i) const
is the i &#39;th covector basic ?
Definition: spxsolver.h:1169
void setDual(Vector &p_vector)
Definition: spxsolve.cpp:1449
int lastIndex() const
returns index in basis where last update was done.
Definition: spxbasis.h:527
virtual SPxSolver * solver() const
returns loaded SPxSolver object.
Definition: spxpricer.h:129
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:109
int primalCount
number of primal iterations
Definition: spxsolver.h:335
virtual void qualBoundViolation(Real &maxviol, Real &sumviol) const
get violations of bounds.
Definition: spxquality.cpp:60
Basis descriptor.
Definition: spxbasis.h:104
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:113
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:375
Type type() const
return current Type.
Definition: spxsolver.h:412
virtual void generate(SPxSolver &base)=0
generates start basis for loaded basis.
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:675
algorithm is running
Definition: spxsolver.h:204
Timer * theTime
time spent in last call to method solve()
Definition: spxsolver.h:222
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:241
SPxId & baseId(int i)
Definition: spxbasis.h:497
Real m_pricingViolCo
maximal feasibility violation of current solution in coDim
Definition: spxsolver.h:237
Real length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: vectorbase.h:356
Debugging, floating point type and parameter definitions.
virtual void loadBasis(const SPxBasis::Desc &)
set a start basis.
Definition: spxsolver.cpp:92
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:127
virtual void setEpsilon(Real eps)
sets violation bound.
Definition: spxpricer.h:143
#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:1582
int totalboundflips
total number of bound flips
Definition: spxsolver.h:338
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:248
DIdxSet infeasibilities
Definition: spxsolver.h:357
virtual int getFactorCount() const =0
get number of factorizations
virtual bool precisionReached(Real &newpricertol) const
is the solution precise enough, or should we increase delta() ?
Definition: spxsolve.cpp:37
Status m_status
status of algorithm.
Definition: spxsolver.h:230
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
const VectorBase< Real > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:242
Everything should be within this namespace.
virtual void setType(SPxSolver::Type)
sets pricing type.
Definition: spxpricer.h:154
virtual bool terminate()
Termination criterion.
Definition: spxsolve.cpp:1101
Real theCumulativeTime
cumulative time spent in all calls to method solve()
Definition: spxsolver.h:224
UpdateVector * theFvec
Definition: spxsolver.h:310
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:533
solve() aborted due to detection of cycling.
Definition: spxsolver.h:197
virtual Real epsilon() const
returns violation bound theeps.
Definition: spxpricer.h:135
virtual Real maxInfeas() const
maximal infeasibility of basis
Definition: spxsolver.cpp:630
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:111
primal variable is set to its lower bound
Definition: spxbasis.h:187
Real feastol() const
allowed primal feasibility tolerance.
Definition: spxsolver.h:689
virtual void clearUpdateVecs(void)
Definition: spxsolver.cpp:510
int leaveCount
number of LEAVE iterations
Definition: spxsolver.h:333
nothing known on loaded problem.
Definition: spxsolver.h:205
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:931
virtual Status getSlacks(Vector &vector) const
get vector of slack variables.
Definition: spxsolve.cpp:1378
void computeFrhs()
compute feasibility vector from scratch.
Definition: spxvecs.cpp:42
void clear()
Set vector to 0.
Definition: vectorbase.h:219
Status status() const
Status of solution process.
Definition: spxsolve.cpp:1536
SPxRatioTester * theratiotester
Definition: spxsolver.h:341
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:670
DVector * theCoPrhs
Definition: spxsolver.h:312
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:438
dual variable is set to its lower bound
Definition: spxbasis.h:193
virtual bool noViols(Real tol) const
check for violations above tol and immediately return false w/o checking the remaining values ...
Definition: spxsolver.cpp:675
DSVector primalRay
stores primal ray in case of unboundedness
Definition: spxsolver.h:330
#define MAXREFACPIVOTS
Definition: spxsolve.cpp:31
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:371
const Real infinity
Definition: spxdefines.cpp:26
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:378
const VectorBase< Real > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:224
bool isInitialized() const
has the internal data been initialized?
Definition: spxsolver.h:1705
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1124
DSVector dualFarkas
stores dual farkas proof in case of infeasibility
Definition: spxsolver.h:331
int enterCount
number of ENTER iterations
Definition: spxsolver.h:334
dual variable has two bounds
Definition: spxbasis.h:194
const SVectorBase< Real > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:212
Real maxTime
maximum allowed time.
Definition: spxsolver.h:226
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 Status getDualfarkas(Vector &vector) const
get dual farkas proof of infeasibility.
Definition: spxsolve.cpp:1360
const Real & objOffset() const
Returns the objective function value offset.
Definition: spxlpbase.h:444
virtual void init()
intialize data structures.
Definition: spxsolver.cpp:317
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
const Desc & desc() const
Definition: spxbasis.h:457
void forceRecompNonbasicValue()
Definition: spxsolver.h:545
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:605
DIdxSet updateViolsCo
Definition: spxsolver.h:364
Textbook ratio test for SoPlex.
virtual void reset()=0
initialize timer, set timing accounts to zero.
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:117
Real objLimit
< the number of calls to the method isTimeLimitReached()
Definition: spxsolver.h:229
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:498
UpdateVector * theCoPvec
Definition: spxsolver.h:313
int iterCount
number of calls to change() since last manipulation
Definition: spxbasis.h:384
SSVector * coSolveVector2
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:252
Real time() const
time spent in last call to method solve().
Definition: spxsolver.h:1953
virtual Status solve()
solve loaded LP.
Definition: spxsolve.cpp:73
virtual void qualConstraintViolation(Real &maxviol, Real &sumviol) const
get violation of constraints.
Definition: spxquality.cpp:25
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:360
bool hyperPricingLeave
true if hyper sparse pricing is turned on in the leaving Simplex
Definition: spxsolver.h:377
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:682
SPxId lastEntered() const
returns SPxId of last vector included to the basis.
Definition: spxbasis.h:515
solve() aborted due to objective limit.
Definition: spxsolver.h:200
columnwise representation.
Definition: spxsolver.h:108
void setRedCost(Vector &p_vector)
Definition: spxsolve.cpp:1480
const VectorBase< Real > & maxRowObj() const
Definition: spxlpbase.h:286
#define MAXCYCLES
Definition: spxsolve.cpp:28
Basis is singular, numerical troubles?
Definition: spxsolver.h:201
virtual void factorize()
Factorize basis matrix.
Definition: spxsolver.cpp:525
Basis is primal feasible.
Definition: spxbasis.h:96
virtual SPxSolver * solver() const
returns loaded LP solver.
LP has a usable Basis (maybe LP is changed).
Definition: spxsolver.h:203
bool matrixIsSetup
true iff the pointers in matrix are set up correctly.
Definition: spxbasis.h:349
void setBasisStatus(SPxBasis::SPxStatus stat)
set the lp solver&#39;s basis status.
Definition: spxsolver.h:1905
LP has been proven to be primal unbounded.
Definition: spxsolver.h:207
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:195
void computeCoTest()
compute coTest vector.
Definition: enter.cpp:228
#define MAXIMUM(x, y)
Definition: spxdefines.h:228