Scippy

SoPlex

Sequential object-oriented simPlex

spxfastrt.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 <stdio.h>
18 
19 #include "soplex/spxdefines.h"
20 #include "soplex/spxfastrt.h"
21 
22 
23 /*
24  Here comes our implementation of the Harris procedure improved by shifting
25  bounds. The basic idea is to allow a slight infeasibility within |delta| to
26  allow for more freedom when selecting the leaving variable. This freedom
27  may then be used for selecting numerically stable variables yielding great
28  improvements.
29 
30  The algorithms operates in two phases. In a first phase, the maximum value
31  |val| is determined, when infeasibility within |delta| is allowed. In the second
32  phase, between all variables with value < |val| the one is selected which
33  has the largest update vector component. However, this may not
34  always yield an improvement. In that case, we shift the variable towards
35  infeasibility and retry. This avoids cycling in the shifted LP.
36  */
37 
38 namespace soplex
39 {
40 
41 #define MINSTAB 1e-5
42 #define LOWSTAB 1e-10
43 #define TRIES 2
44 #define SHORT 1e-5
45 #define DELTA_SHIFT 1e-5
46 #define EPSILON 1e-10
47 
49 {
50  // epsilon = thesolver->epsilon();
51  epsilon = EPSILON;
52  /*
53  if(thesolver->basis().stability() < 1e-4)
54  epsilon *= 1e-4 / thesolver->basis().stability();
55  */
56 }
57 
59 {
60  /*
61  if((delta > 1.99 * DELTA_SHIFT && thesolver->theShift < 1e-4) ||
62  (delta > 1e-4 && thesolver->theShift > 1e-4))
63  */
64  // if(delta > 1.99 * DELTA_SHIFT)
65  if(fastDelta >= delta + DELTA_SHIFT)
66  {
68 
69  if(fastDelta > 1e-4)
70  fastDelta -= 2 * DELTA_SHIFT;
71  }
72 
73  if(minStab < MINSTAB)
74  {
75  minStab /= 0.90;
76 
77  if(minStab < 1e-6)
78  minStab /= 0.90;
79  }
80 }
81 
83 {
84  minStab *= 0.95;
85  fastDelta += 3 * DELTA_SHIFT;
86  // delta += 2 * (thesolver->theShift > delta) * DELTA_SHIFT;
87 }
88 
90 {
91  if(maxabs < 1000.0)
92  return minStab;
93 
94  return maxabs * minStab / 1000.0;
95 }
96 
97 /* The code below implements phase 1 of the ratio test. It differs from the description in the
98  * Ph.D. thesis page 57 as follows: It uses \f$\delta_i = d_i - s_i - \delta\f$ if \f$d_i > s_i\f$.
99  *
100  * This change leads to the following behavior of the source code. Consider the first case (x >
101  * epsilon, u < infinity): If u - vec[i] <= 0, vec[i] violates the upper bound. In the Harris ratio
102  * test, we would compute (u - vec[i] + delta)/upd[i]. The code computes instead delta/upd[i].
103  */
105  Real& val, /* on return: maximum step length */
106  Real& maxabs, /* on return: maximum absolute value in upd vector */
107  UpdateVector& update,
108  const Vector& lowBound,
109  const Vector& upBound,
110  int start,
111  int incr) const
112 {
113  int i, sel;
114  Real x, y, max;
115  Real u, l;
116  bool leaving = m_type == SPxSolver::LEAVE;
117 
118  Real mabs = maxabs;
119 
120  const Real* up = upBound.get_const_ptr();
121  const Real* low = lowBound.get_const_ptr();
122  const Real* vec = update.get_const_ptr();
123  const Real* upd = update.delta().values();
124  const int* idx = update.delta().indexMem();
125 
126  sel = -1;
127  max = val;
128 
129  if(update.delta().isSetup())
130  {
131  const int* last = idx + update.delta().size();
132 
133  for(idx += start; idx < last; idx += incr)
134  {
135  i = *idx;
136 
137  /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
138  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
139  continue;
140 
141  x = upd[i];
142 
143  if(x > epsilon)
144  {
145  // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
146  mabs = (x > mabs) ? x : mabs;
147  u = up[i];
148 
149  if(u < infinity)
150  {
151  y = u - vec[i];
152 
153  if(y <= 0)
154  x = fastDelta / x;
155  else
156  x = (y + fastDelta) / x;
157 
158  if(x < max)
159  {
160  max = x;
161  sel = i;
162  }
163  }
164  }
165  else if(x < -epsilon)
166  {
167  // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
168  mabs = (-x > mabs) ? -x : mabs;
169  l = low[i];
170 
171  if(l > -infinity)
172  {
173  y = l - vec[i];
174 
175  if(y >= 0)
176  x = - fastDelta / x;
177  else
178  x = (y - fastDelta) / x;
179 
180  if(x < max)
181  {
182  max = x;
183  sel = i;
184  }
185  }
186  }
187  }
188  }
189  else
190  {
191  /* In this case, the indices of the semi-sparse vector update.delta() are not set up and are filled below. */
192  int* l_idx = update.delta().altIndexMem();
193  Real* uval = update.delta().altValues();
194  const Real* uend = uval + update.dim();
195  assert(uval == upd);
196 
197  for(i = 0; uval < uend; ++uval, ++i)
198  {
199  x = *uval;
200 
201  if(x != 0.0)
202  {
203  if(x >= -epsilon && x <= epsilon)
204  {
205  *uval = 0.0;
206  continue;
207  }
208  else
209  *l_idx++ = i;
210 
211  /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
212  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
213  continue;
214 
215  if(x > epsilon)
216  {
217  mabs = (x > mabs) ? x : mabs;
218  u = up[i];
219 
220  if(u < infinity)
221  {
222  y = u - vec[i];
223 
224  if(y <= 0)
225  x = fastDelta / x;
226  else
227  x = (y + fastDelta) / x;
228 
229  if(x < max)
230  {
231  max = x;
232  sel = i;
233  }
234  }
235  }
236  else if(x < -epsilon)
237  {
238  mabs = (-x > mabs) ? -x : mabs;
239  l = low[i];
240 
241  if(l > -infinity)
242  {
243  y = l - vec[i];
244 
245  if(y >= 0)
246  x = - fastDelta / x;
247  else
248  x = (y - fastDelta) / x;
249 
250  if(x < max)
251  {
252  max = x;
253  sel = i;
254  }
255  }
256  }
257  }
258  }
259 
260  update.delta().setSize(int(l_idx - update.delta().indexMem()));
261  update.delta().forceSetup();
262  }
263 
264  val = max;
265  maxabs = mabs;
266  return sel;
267 }
268 
269 /* See maxDelta() */
271  Real& val,
272  Real& maxabs,
273  UpdateVector& update,
274  const Vector& lowBound,
275  const Vector& upBound,
276  int start,
277  int incr) const
278 {
279  int i, sel;
280  Real x, y, max;
281  Real u, l;
282  bool leaving = m_type == SPxSolver::LEAVE;
283 
284  Real mabs = maxabs;
285 
286  const Real* up = upBound.get_const_ptr();
287  const Real* low = lowBound.get_const_ptr();
288  const Real* vec = update.get_const_ptr();
289  const Real* upd = update.delta().values();
290  const int* idx = update.delta().indexMem();
291 
292  sel = -1;
293  max = val;
294 
295  if(update.delta().isSetup())
296  {
297  const int* last = idx + update.delta().size();
298 
299  for(idx += start; idx < last; idx += incr)
300  {
301  i = *idx;
302  x = upd[i];
303 
304  /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
305  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
306  continue;
307 
308  if(x > epsilon)
309  {
310  // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
311  mabs = (x > mabs) ? x : mabs;
312  l = low[i];
313 
314  if(l > -infinity)
315  {
316  y = l - vec[i];
317 
318  if(y >= 0)
319  x = - fastDelta / x;
320  else
321  x = (y - fastDelta) / x;
322 
323  if(x > max)
324  {
325  max = x;
326  sel = i;
327  }
328  }
329  }
330  else if(x < -epsilon)
331  {
332  // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
333  mabs = (-x > mabs) ? -x : mabs;
334  u = up[i];
335 
336  if(u < infinity)
337  {
338  y = u - vec[i];
339 
340  if(y <= 0)
341  x = fastDelta / x;
342  else
343  x = (y + fastDelta) / x;
344 
345  if(x > max)
346  {
347  max = x;
348  sel = i;
349  }
350  }
351  }
352  }
353  }
354  else
355  {
356  /* In this case, the indices of the semi-sparse vector update.delta() are not set up and are filled below. */
357  int* l_idx = update.delta().altIndexMem();
358  Real* uval = update.delta().altValues();
359  const Real* uend = uval + update.dim();
360  assert(uval == upd);
361 
362  for(i = 0; uval < uend; ++uval, ++i)
363  {
364  x = *uval;
365 
366  if(x != 0.0)
367  {
368  if(x >= -epsilon && x <= epsilon)
369  {
370  *uval = 0.0;
371  continue;
372  }
373  else
374  *l_idx++ = i;
375 
376  /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
377  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
378  continue;
379 
380  if(x > epsilon)
381  {
382  mabs = (x > mabs) ? x : mabs;
383  l = low[i];
384 
385  if(l > -infinity)
386  {
387  y = l - vec[i];
388 
389  if(y >= 0)
390  x = - fastDelta / x;
391  else
392  x = (y - fastDelta) / x;
393 
394  if(x > max)
395  {
396  max = x;
397  sel = i;
398  }
399  }
400  }
401  else if(x < -epsilon)
402  {
403  mabs = (-x > mabs) ? -x : mabs;
404  u = up[i];
405 
406  if(u < infinity)
407  {
408  y = u - vec[i];
409 
410  if(y <= 0)
411  x = fastDelta / x;
412  else
413  x = (y + fastDelta) / x;
414 
415  if(x > max)
416  {
417  max = x;
418  sel = i;
419  }
420  }
421  }
422  }
423  }
424 
425  update.delta().setSize(int(l_idx - update.delta().indexMem()));
426  update.delta().forceSetup();
427  }
428 
429  val = max;
430  maxabs = mabs;
431 
432  return sel;
433 }
434 
436  Real& val,
437  Real& maxabs)
438 {
439  assert(m_type == SPxSolver::ENTER);
440  return maxDelta(val, maxabs,
441  thesolver->fVec(), thesolver->lbBound(), thesolver->ubBound(), 0, 1);
442 }
443 
445  Real& val,
446  Real& maxabs)
447 {
448  assert(m_type == SPxSolver::ENTER);
449  return minDelta(val, maxabs,
450  thesolver->fVec(), thesolver->lbBound(), thesolver->ubBound(), 0, 1);
451 }
452 
454  int& nr,
455  Real& max, /* on return: maximum step length */
456  Real& maxabs) /* on return: maximum absolute value in delta vector */
457 {
458  /* The following cause side effects on coPvec and pVec - both changes may be needed later in
459  maxSelect(). We can therefore not move the first function after the (indp >= 0) check. */
460  iscoid = true;
461  int indc = maxDelta(max, maxabs,
463  iscoid = false;
464  int indp = maxDelta(max, maxabs,
465  thesolver->pVec(), thesolver->lpBound(), thesolver->upBound(), 0, 1);
466 
467  if(indp >= 0)
468  {
469  nr = indp;
470  return thesolver->id(indp);
471  }
472 
473  if(indc >= 0)
474  {
475  nr = indc;
476  return thesolver->coId(indc);
477  }
478 
479  nr = -1;
480  return SPxId();
481 }
482 
484  int& nr,
485  Real& max,
486  Real& maxabs)
487 {
488  /* The following cause side effects on coPvec and pVec - both changes may be needed later in
489  minSelect(). We can therefore not move the first function after the (indp >= 0) check. */
490  iscoid = true;
491  const int indc = minDelta(max, maxabs,
493  iscoid = false;
494  const int indp = minDelta(max, maxabs,
495  thesolver->pVec(), thesolver->lpBound(), thesolver->upBound(), 0, 1);
496 
497  if(indp >= 0)
498  {
499  nr = indp;
500  return thesolver->id(indp);
501  }
502 
503  if(indc >= 0)
504  {
505  nr = indc;
506  return thesolver->coId(indc);
507  }
508 
509  nr = -1;
510  return SPxId();
511 }
512 
513 /* \p best returns the minimum update value such that the corresponding value of \p upd.delta() is
514  * at least \p stab and the update value is smaller than \p max. If no valid update value has been
515  * found \p bestDelta returns the slack to the bound corresponding to the index used for \p best. */
517  Real& val,
518  Real& stab,
519  Real& best,
520  Real& bestDelta,
521  Real max,
522  const UpdateVector& update,
523  const Vector& lowBound,
524  const Vector& upBound,
525  int start,
526  int incr) const
527 {
528  int i;
529  Real x, y;
530  bool leaving = m_type == SPxSolver::LEAVE;
531 
532  const Real* up = upBound.get_const_ptr();
533  const Real* low = lowBound.get_const_ptr();
534  const Real* vec = update.get_const_ptr();
535  const Real* upd = update.delta().values();
536  const int* idx = update.delta().indexMem();
537  const int* last = idx + update.delta().size();
538 
539  int nr = -1;
540  int bestNr = -1;
541 
542  for(idx += start; idx < last; idx += incr)
543  {
544  i = *idx;
545  x = upd[i];
546 
547  // in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables
548  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
549  continue;
550 
551  if(x > stab)
552  {
553  y = (low[i] - vec[i]) / x;
554 
555  if(y >= max)
556  {
557  val = y;
558  nr = i;
559  stab = x;
560  }
561  else if(y < best)
562  {
563  best = y;
564  bestNr = i;
565  }
566  }
567  else if(x < -stab)
568  {
569  y = (up[i] - vec[i]) / x;
570 
571  if(y >= max)
572  {
573  val = y;
574  nr = i;
575  stab = -x;
576  }
577  else if(y < best)
578  {
579  best = y;
580  bestNr = i;
581  }
582  }
583  }
584 
585  if(nr < 0 && bestNr > 0)
586  {
587  if(upd[bestNr] < 0)
588  bestDelta = up[bestNr] - vec[bestNr];
589  else
590  bestDelta = vec[bestNr] - low[bestNr];
591  }
592 
593  return nr;
594 }
595 
596 /* See minSelect() */
598  Real& val,
599  Real& stab,
600  Real& best,
601  Real& bestDelta,
602  Real max,
603  const UpdateVector& update,
604  const Vector& lowBound,
605  const Vector& upBound,
606  int start,
607  int incr) const
608 {
609  int i;
610  Real x, y;
611  bool leaving = m_type == SPxSolver::LEAVE;
612 
613  const Real* up = upBound.get_const_ptr();
614  const Real* low = lowBound.get_const_ptr();
615  const Real* vec = update.get_const_ptr();
616  const Real* upd = update.delta().values();
617  const int* idx = update.delta().indexMem();
618  const int* last = idx + update.delta().size();
619 
620  int nr = -1;
621  int bestNr = -1;
622 
623  for(idx += start; idx < last; idx += incr)
624  {
625  i = *idx;
626  x = upd[i];
627 
628  // in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables
629  if(leaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))))
630  continue;
631 
632  if(x > stab)
633  {
634  y = (up[i] - vec[i]) / x;
635 
636  if(y <= max)
637  {
638  val = y;
639  nr = i;
640  stab = x;
641  }
642  else if(y > best)
643  {
644  best = y;
645  bestNr = i;
646  }
647  }
648  else if(x < -stab)
649  {
650  y = (low[i] - vec[i]) / x;
651 
652  if(y <= max)
653  {
654  val = y;
655  nr = i;
656  stab = -x;
657  }
658  else if(y > best)
659  {
660  best = y;
661  bestNr = i;
662  }
663  }
664  }
665 
666  if(nr < 0 && bestNr > 0)
667  {
668  if(upd[bestNr] > 0)
669  bestDelta = up[bestNr] - vec[bestNr];
670  else
671  bestDelta = vec[bestNr] - low[bestNr];
672  }
673 
674  return nr;
675 }
676 
677 
679  Real& val,
680  Real& stab,
681  Real& bestDelta,
682  Real max)
683 {
684  Real best = -infinity;
685  bestDelta = 0.0;
686  assert(m_type == SPxSolver::ENTER);
687  return maxSelect(val, stab, best, bestDelta, max,
688  thesolver->fVec(), thesolver->lbBound(), thesolver->ubBound(), 0, 1);
689 }
690 
692  int& nr,
693  Real& val,
694  Real& stab,
695  Real& bestDelta,
696  Real max
697 )
698 {
699  int indp, indc;
700  Real best = -infinity;
701  bestDelta = 0.0;
702  iscoid = true;
703  indc = maxSelect(val, stab, best, bestDelta, max,
705  iscoid = false;
706  indp = maxSelect(val, stab, best, bestDelta, max,
707  thesolver->pVec(), thesolver->lpBound(), thesolver->upBound(), 0, 1);
708 
709  if(indp >= 0)
710  {
711  nr = indp;
712  return thesolver->id(indp);
713  }
714 
715  if(indc >= 0)
716  {
717  nr = indc;
718  return thesolver->coId(indc);
719  }
720 
721  nr = -1;
722  return SPxId();
723 }
724 
726  Real& val,
727  Real& stab,
728  Real& bestDelta,
729  Real max)
730 {
731  Real best = infinity;
732  bestDelta = 0.0;
733  assert(m_type == SPxSolver::ENTER);
734  return minSelect(val, stab, best, bestDelta, max,
735  thesolver->fVec(), thesolver->lbBound(), thesolver->ubBound(), 0, 1);
736 }
737 
739  int& nr,
740  Real& val,
741  Real& stab,
742  Real& bestDelta,
743  Real max)
744 {
745  Real best = infinity;
746  bestDelta = 0.0;
747  iscoid = true;
748  int indc = minSelect(val, stab, best, bestDelta, max,
750  iscoid = false;
751  int indp = minSelect(val, stab, best, bestDelta, max,
752  thesolver->pVec(), thesolver->lpBound(), thesolver->upBound(), 0, 1);
753 
754  if(indp >= 0)
755  {
756  nr = indp;
757  return thesolver->id(indp);
758  }
759 
760  if(indc >= 0)
761  {
762  nr = indc;
763  return thesolver->coId(indc);
764  }
765 
766  nr = -1;
767  return SPxId();
768 }
769 
770 
771 bool SPxFastRT::maxShortLeave(Real& sel, int leave, Real maxabs)
772 {
773  assert(leave >= 0);
774  assert(maxabs >= 0);
775 
776  sel = thesolver->fVec().delta()[leave];
777 
778  if(sel > maxabs * SHORT)
779  {
780  sel = (thesolver->ubBound()[leave] - thesolver->fVec()[leave]) / sel;
781  return true;
782  }
783 
784  if(sel < -maxabs * SHORT)
785  {
786  sel = (thesolver->lbBound()[leave] - thesolver->fVec()[leave]) / sel;
787  return true;
788  }
789 
790  return false;
791 }
792 
793 bool SPxFastRT::minShortLeave(Real& sel, int leave, Real maxabs)
794 {
795  assert(leave >= 0);
796  assert(maxabs >= 0);
797 
798  sel = thesolver->fVec().delta()[leave];
799 
800  if(sel > maxabs * SHORT)
801  {
802  sel = (thesolver->lbBound()[leave] - thesolver->fVec()[leave]) / sel;
803  return true;
804  }
805 
806  if(sel < -maxabs * SHORT)
807  {
808  sel = (thesolver->ubBound()[leave] - thesolver->fVec()[leave]) / sel;
809  return true;
810  }
811 
812  return false;
813 }
814 
815 bool SPxFastRT::maxReLeave(Real& sel, int leave, Real maxabs, bool polish)
816 {
817  UpdateVector& vec = thesolver->fVec();
818  Vector& low = thesolver->lbBound();
819  Vector& up = thesolver->ubBound();
820 
821  if(leave < 0)
822  return true;
823 
824  if(up[leave] > low[leave])
825  {
826  Real x = vec.delta()[leave];
827 
828  if(sel < -fastDelta / maxabs)
829  {
830  sel = 0.0;
831 
832  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
834  {
835  if(x < 0.0)
836  thesolver->shiftLBbound(leave, vec[leave]);
837  else
838  thesolver->shiftUBbound(leave, vec[leave]);
839  }
840  }
841  }
842  else
843  {
844  sel = 0.0;
845 
846  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
847  if(!polish)
848  {
849  thesolver->shiftLBbound(leave, vec[leave]);
850  thesolver->shiftUBbound(leave, vec[leave]);
851  }
852  }
853 
854  return false;
855 }
856 
857 bool SPxFastRT::minReLeave(Real& sel, int leave, Real maxabs, bool polish)
858 {
859  UpdateVector& vec = thesolver->fVec();
860  Vector& low = thesolver->lbBound();
861  Vector& up = thesolver->ubBound();
862 
863  if(leave < 0)
864  return true;
865 
866  if(up[leave] > low[leave])
867  {
868  Real x = vec.delta()[leave];
869 
870  if(sel > fastDelta / maxabs)
871  {
872  sel = 0.0;
873 
874  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
876  {
877  if(x > 0.0)
878  thesolver->shiftLBbound(leave, vec[leave]);
879  else
880  thesolver->shiftUBbound(leave, vec[leave]);
881  }
882  }
883  }
884  else
885  {
886  sel = 0.0;
887 
888  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
889  if(!polish)
890  {
891  thesolver->shiftLBbound(leave, vec[leave]);
892  thesolver->shiftUBbound(leave, vec[leave]);
893  }
894  }
895 
896  return false;
897 }
898 
899 int SPxFastRT::selectLeave(Real& val, Real, bool polish)
900 {
901  Real maxabs, max, sel;
902  int leave = -1;
903  int cnt = 0;
904 
905  assert(m_type == SPxSolver::ENTER);
906 
907  // force instable pivot iff true (see explanation in enter.cpp and spxsolve.cpp)
908  bool instable = solver()->instableEnter;
909  Real lowstab = LOWSTAB;
910  assert(!instable || solver()->instableEnterId.isValid());
911 
912  resetTols();
913 
914  if(val > epsilon)
915  {
916  do
917  {
918  // phase 1:
919  max = val;
920  maxabs = 0.0;
921  leave = maxDelta(max, maxabs);
922 
923  assert(leave < 0 || !(thesolver->baseId(leave).isSPxColId()) ||
925  leave)))) != SPxBasis::Desc::P_FIXED);
926 
927  if(max == val || leave == -1)
928  {
929  assert(max == val && leave == -1);
930  return -1;
931  }
932 
933  if(!maxShortLeave(sel, leave, maxabs))
934  {
935  // phase 2:
936  Real stab, bestDelta;
937 
938  stab = 100.0 * minStability(maxabs);
939 
940  // force instable pivot iff instable is true (see explanation in enter.cpp and spxsolve.cpp)
941  if(instable)
942  leave = maxSelect(sel, lowstab, bestDelta, max);
943  else
944  leave = maxSelect(sel, stab, bestDelta, max);
945 
946  if(bestDelta < DELTA_SHIFT * TRIES)
947  cnt++;
948  else
949  cnt += TRIES;
950  }
951 
952  if(!maxReLeave(sel, leave, maxabs, polish))
953  break;
954 
955  relax();
956  }
957  while(cnt < TRIES);
958  }
959  else if(val < -epsilon)
960  {
961  do
962  {
963  max = val;
964  maxabs = 0;
965  leave = minDelta(max, maxabs);
966 
967  assert(leave < 0 || !(thesolver->baseId(leave).isSPxColId()) ||
969  leave)))) != SPxBasis::Desc::P_FIXED);
970 
971  if(max == val || leave == -1)
972  {
973  assert(max == val && leave == -1);
974  return -1;
975  }
976 
977  if(!minShortLeave(sel, leave, maxabs))
978  {
979  // phase 2:
980  Real stab, bestDelta;
981 
982  stab = 100.0 * minStability(maxabs);
983 
984  // force instable pivot iff instable is true (see explanation in enter.cpp and spxsolve.cpp)
985  if(instable)
986  leave = minSelect(sel, lowstab, bestDelta, max);
987  else
988  leave = minSelect(sel, stab, bestDelta, max);
989 
990  assert(leave < 0 || !(thesolver->baseId(leave).isSPxColId())
992  leave)))) != SPxBasis::Desc::P_FIXED);
993 
994  if(bestDelta < DELTA_SHIFT * TRIES)
995  cnt++;
996  else
997  cnt += TRIES;
998  }
999 
1000  if(!minReLeave(sel, leave, maxabs, polish))
1001  break;
1002 
1003  relax();
1004  }
1005  while(cnt < TRIES);
1006  }
1007  else
1008  return -1;
1009 
1010  MSG_DEBUG(
1011 
1012  if(leave >= 0)
1013  std::cout
1014  << "DFSTRT01 "
1015  << thesolver->basis().iteration() << "("
1016  << std::setprecision(6) << thesolver->value() << ","
1017  << std::setprecision(2) << thesolver->basis().stability() << "):"
1018  << leave << "\t"
1019  << std::setprecision(4) << sel << " "
1020  << std::setprecision(4) << thesolver->fVec().delta()[leave] << " "
1021  << std::setprecision(6) << maxabs
1022  << std::endl;
1023  else
1024  std::cout << "DFSTRT02 " << thesolver->basis().iteration()
1025  << ": skipping instable pivot" << std::endl;
1026  )
1027 
1028  if(polish && leave >= 0)
1029  {
1030  assert(thesolver->rep() == SPxSolver::COLUMN);
1031  SPxId leaveId = thesolver->baseId(leave);
1032 
1033  // decide whether the chosen leave index contributes to the polishing objective
1035  {
1036  // only allow (integer) variables to leave the basis
1037  if(leaveId.isSPxRowId())
1038  return -1;
1039  else if(thesolver->integerVariables.size() == thesolver->nCols())
1040  {
1041  if(leaveId.isSPxColId() && thesolver->integerVariables[thesolver->number(leaveId)] == 0)
1042  return -1;
1043  }
1044  }
1046  {
1047  // only allow slacks and continuous variables to leave the basis
1049  {
1050  if(thesolver->baseId(leave).isSPxColId()
1051  && thesolver->integerVariables[thesolver->number(leaveId)] == 1)
1052  return -1;
1053  }
1054  else if(thesolver->baseId(leave).isSPxColId())
1055  return -1;
1056  }
1057  }
1058 
1059  if(leave >= 0 || minStab > 2 * solver()->epsilon())
1060  {
1061  val = sel;
1062 
1063  if(leave >= 0)
1064  tighten();
1065  }
1066 
1067  assert(leave < 0 || !(thesolver->baseId(leave).isSPxColId())
1069  leave)))) != SPxBasis::Desc::P_FIXED);
1070 
1071  return leave;
1072 }
1073 
1074 
1076  Real& sel,
1077  Real maxabs,
1078  const SPxId& id,
1079  int nr,
1080  bool polish)
1081 {
1082  Real x, d;
1083  Vector* up;
1084  Vector* low;
1085 
1086  UpdateVector& pvec = thesolver->pVec();
1087  SSVector& pupd = thesolver->pVec().delta();
1088  Vector& upb = thesolver->upBound();
1089  Vector& lpb = thesolver->lpBound();
1090  UpdateVector& cvec = thesolver->coPvec();
1091  SSVector& cupd = thesolver->coPvec().delta();
1092  Vector& ucb = thesolver->ucBound();
1093  Vector& lcb = thesolver->lcBound();
1094 
1095  if(thesolver->isCoId(id))
1096  {
1097  if(thesolver->isCoBasic(nr))
1098  {
1099  cupd.clearIdx(nr);
1100  return true;
1101  }
1102 
1103  x = cvec[nr];
1104  d = cupd[nr];
1105  up = &ucb;
1106  low = &lcb;
1107 
1108  if(d < 0.0)
1109  sel = (lcb[nr] - cvec[nr]) / d;
1110  else
1111  sel = (ucb[nr] - cvec[nr]) / d;
1112  }
1113  else if(thesolver->isId(id))
1114  {
1115  pvec[nr] = thesolver->vector(nr) * cvec;
1116 
1117  if(thesolver->isBasic(nr))
1118  {
1119  pupd.clearIdx(nr);
1120  return true;
1121  }
1122 
1123  x = pvec[nr];
1124  d = pupd[nr];
1125  up = &upb;
1126  low = &lpb;
1127 
1128  if(d < 0.0)
1129  sel = (lpb[nr] - pvec[nr]) / d;
1130  else
1131  sel = (upb[nr] - pvec[nr]) / d;
1132  }
1133  else
1134  return true;
1135 
1136  if((*up)[nr] != (*low)[nr])
1137  {
1138  if(sel < -fastDelta / maxabs)
1139  {
1140  sel = 0.0;
1141 
1142  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
1143  if(!polish)
1144  {
1145  if(d > 0.0)
1146  {
1147  thesolver->theShift -= (*up)[nr];
1148  (*up)[nr] = x;
1149  thesolver->theShift += (*up)[nr];
1150  }
1151  else
1152  {
1153  thesolver->theShift += (*low)[nr];
1154  (*low)[nr] = x;
1155  thesolver->theShift -= (*low)[nr];
1156  }
1157  }
1158  }
1159  }
1160  else
1161  {
1162  sel = 0.0;
1163 
1164  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
1165  if(!polish)
1166  {
1167  if(x > (*up)[nr])
1168  thesolver->theShift += x - (*up)[nr];
1169  else
1170  thesolver->theShift += (*low)[nr] - x;
1171 
1172  (*up)[nr] = (*low)[nr] = x;
1173  }
1174  }
1175 
1176  return false;
1177 }
1178 
1180  Real& sel,
1181  Real maxabs,
1182  const SPxId& id,
1183  int nr,
1184  bool polish)
1185 {
1186  Real x, d;
1187  Vector* up;
1188  Vector* low;
1189 
1190  UpdateVector& pvec = thesolver->pVec();
1191  SSVector& pupd = thesolver->pVec().delta();
1192  Vector& upb = thesolver->upBound();
1193  Vector& lpb = thesolver->lpBound();
1194  UpdateVector& cvec = thesolver->coPvec();
1195  SSVector& cupd = thesolver->coPvec().delta();
1196  Vector& ucb = thesolver->ucBound();
1197  Vector& lcb = thesolver->lcBound();
1198 
1199  if(thesolver->isCoId(id))
1200  {
1201  if(thesolver->isCoBasic(nr))
1202  {
1203  cupd.clearIdx(nr);
1204  return true;
1205  }
1206 
1207  x = cvec[nr];
1208  d = cupd[nr];
1209  up = &ucb;
1210  low = &lcb;
1211 
1212  if(d > 0.0)
1213  sel = (thesolver->lcBound()[nr] - cvec[nr]) / d;
1214  else
1215  sel = (thesolver->ucBound()[nr] - cvec[nr]) / d;
1216  }
1217 
1218  else if(thesolver->isId(id))
1219  {
1220  pvec[nr] = thesolver->vector(nr) * cvec;
1221 
1222  if(thesolver->isBasic(nr))
1223  {
1224  pupd.clearIdx(nr);
1225  return true;
1226  }
1227 
1228  x = pvec[nr];
1229  d = pupd[nr];
1230  up = &upb;
1231  low = &lpb;
1232 
1233  if(d > 0.0)
1234  sel = (thesolver->lpBound()[nr] - pvec[nr]) / d;
1235  else
1236  sel = (thesolver->upBound()[nr] - pvec[nr]) / d;
1237  }
1238 
1239  else
1240  return true;
1241 
1242  if((*up)[nr] != (*low)[nr])
1243  {
1244  if(sel > fastDelta / maxabs)
1245  {
1246  sel = 0.0;
1247 
1248  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
1249  if(!polish)
1250  {
1251  if(d < 0.0)
1252  {
1253  thesolver->theShift -= (*up)[nr];
1254  (*up)[nr] = x;
1255  thesolver->theShift += (*up)[nr];
1256  }
1257  else
1258  {
1259  thesolver->theShift += (*low)[nr];
1260  (*low)[nr] = x;
1261  thesolver->theShift -= (*low)[nr];
1262  }
1263  }
1264  }
1265  }
1266  else
1267  {
1268  sel = 0.0;
1269 
1270  // prevent shifts in polishing mode to avoid a final cleanup step (i.e. simplex type switch)
1271  if(!polish)
1272  {
1273  if(x > (*up)[nr])
1274  thesolver->theShift += x - (*up)[nr];
1275  else
1276  thesolver->theShift += (*low)[nr] - x;
1277 
1278  (*up)[nr] = (*low)[nr] = x;
1279  }
1280  }
1281 
1282  return false;
1283 }
1284 
1286  const SPxId& enterId,
1287  int nr,
1288  Real max,
1289  Real maxabs) const
1290 {
1291  if(thesolver->isCoId(enterId))
1292  {
1293  if(max != 0.0)
1294  {
1295  Real x = thesolver->coPvec().delta()[nr];
1296 
1297  if(x < maxabs * SHORT && -x < maxabs * SHORT)
1298  return false;
1299  }
1300 
1301  return true;
1302  }
1303  else if(thesolver->isId(enterId))
1304  {
1305  if(max != 0.0)
1306  {
1307  Real x = thesolver->pVec().delta()[nr];
1308 
1309  if(x < maxabs * SHORT && -x < maxabs * SHORT)
1310  return false;
1311  }
1312 
1313  return true;
1314  }
1315 
1316  return false;
1317 }
1318 
1319 SPxId SPxFastRT::selectEnter(Real& val, int, bool polish)
1320 {
1321  SPxId enterId;
1322  Real max, sel;
1323  Real maxabs = 0.0;
1324  int nr;
1325  int cnt = 0;
1326 
1327  assert(m_type == SPxSolver::LEAVE);
1328 
1329  // force instable pivot iff true (see explanation in leave.cpp and spxsolve.cpp)
1330  bool instable = solver()->instableLeave;
1331  Real lowstab = LOWSTAB;
1332  assert(!instable || solver()->instableLeaveNum >= 0);
1333 
1334  resetTols();
1335  sel = 0.0;
1336 
1337  if(val > epsilon)
1338  {
1339  do
1340  {
1341  maxabs = 0.0;
1342  max = val;
1343 
1344  enterId = maxDelta(nr, max, maxabs);
1345 
1346  if(!enterId.isValid())
1347  return enterId;
1348 
1349  assert(max >= 0.0);
1350  assert(!enterId.isValid() || !solver()->isBasic(enterId));
1351 
1352  if(!shortEnter(enterId, nr, max, maxabs))
1353  {
1354  Real bestDelta, stab;
1355 
1356  stab = minStability(maxabs);
1357 
1358  // force instable pivot iff instable is true (see explanation in leave.cpp and spxsolve.cpp)
1359  if(instable)
1360  {
1361  enterId = maxSelect(nr, sel, lowstab, bestDelta, max);
1362  }
1363  else
1364  {
1365  enterId = maxSelect(nr, sel, stab, bestDelta, max);
1366  }
1367 
1368  if(bestDelta < DELTA_SHIFT * TRIES)
1369  cnt++;
1370  else
1371  cnt += TRIES;
1372  }
1373 
1374  if(!maxReEnter(sel, maxabs, enterId, nr, polish))
1375  break;
1376 
1377  relax();
1378  }
1379  while(cnt < TRIES);
1380  }
1381  else if(val < -epsilon)
1382  {
1383  do
1384  {
1385  maxabs = 0.0;
1386  max = val;
1387  enterId = minDelta(nr, max, maxabs);
1388 
1389  if(!enterId.isValid())
1390  return enterId;
1391 
1392  assert(max <= 0.0);
1393  assert(!enterId.isValid() || !solver()->isBasic(enterId));
1394 
1395  if(!shortEnter(enterId, nr, max, maxabs))
1396  {
1397  Real bestDelta, stab;
1398 
1399  stab = minStability(maxabs);
1400 
1401  // force instable pivot iff instable is true (see explanation in leave.cpp and spxsolve.cpp)
1402  if(instable)
1403  {
1404  enterId = minSelect(nr, sel, lowstab, bestDelta, max);
1405  }
1406  else
1407  {
1408  enterId = minSelect(nr, sel, stab, bestDelta, max);
1409  }
1410 
1411  if(bestDelta < DELTA_SHIFT * TRIES)
1412  cnt++;
1413  else
1414  cnt += TRIES;
1415  }
1416 
1417  if(!minReEnter(sel, maxabs, enterId, nr, polish))
1418  break;
1419 
1420  relax();
1421  }
1422  while(cnt < TRIES);
1423  }
1424 
1425  MSG_DEBUG(
1426 
1427  if(enterId.isValid())
1428 {
1429  assert(!enterId.isValid() || !solver()->isBasic(enterId));
1430 
1431  Real x;
1432 
1433  if(thesolver->isCoId(enterId))
1434  x = thesolver->coPvec().delta()[ thesolver->number(enterId) ];
1435  else
1436  x = thesolver->pVec().delta()[ thesolver->number(enterId) ];
1437 
1438  std::cout << "DFSTRT03 " << thesolver->basis().iteration() << ": "
1439  << sel << '\t' << x << " (" << maxabs << ")" << std::endl;
1440  }
1441  else
1442  std::cout << "DFSTRT04 " << thesolver->basis().iteration()
1443  << ": skipping instable pivot" << std::endl;
1444  )
1445 
1446  if(polish && enterId.isValid())
1447  {
1448  assert(thesolver->rep() == SPxSolver::ROW);
1449 
1450  // decide whether the chosen entering index contributes to the polishing objective
1452  {
1453  // only allow (integer) variables to enter the basis
1454  if(enterId.isSPxRowId())
1455  return SPxId();
1456  else if(thesolver->integerVariables.size() == thesolver->nCols()
1457  && thesolver->integerVariables[thesolver->number(enterId)] == 0)
1458  return SPxId();
1459  }
1461  {
1462  // only allow slacks and continuous variables to enter the basis
1464  {
1465  if(enterId.isSPxColId() && thesolver->integerVariables[thesolver->number(enterId)] == 1)
1466  return SPxId();
1467  }
1468  else if(enterId.isSPxColId())
1469  return SPxId();
1470  }
1471  }
1472 
1473 
1474  if(enterId.isValid() || minStab > 2 * epsilon)
1475  {
1476  val = sel;
1477 
1478  if(enterId.isValid())
1479  tighten();
1480  }
1481 
1482  assert(!enterId.isValid() || !solver()->isBasic(enterId));
1483 
1484  return enterId;
1485 }
1486 
1488 {
1489  thesolver = spx;
1490  setType(spx->type());
1491 }
1492 
1494 {
1495  m_type = type;
1496 
1497  minStab = MINSTAB;
1498  fastDelta = delta;
1499 }
1500 } // namespace soplex
Fast shifting ratio test.
SPxId coId(int i) const
id of i &#39;th covector.
Definition: spxsolver.h:1117
const Vector & ucBound() const
Definition: spxsolver.h:1417
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:546
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:121
primal variable is fixed to both bounds
Definition: spxbasis.h:190
bool maxReEnter(Real &sel, Real maxabs, const SPxId &id, int nr, bool polish=false)
Definition: spxfastrt.cpp:1075
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
Type
Algorithmic type.
Definition: spxsolver.h:124
bool maxShortLeave(Real &sel, int leave, Real maxabs)
Definition: spxfastrt.cpp:771
int minSelect(Real &val, Real &stab, Real &best, Real &bestDelta, Real max, const UpdateVector &upd, const Vector &low, const Vector &up, int start=0, int incr=1) const
selects stable index for minimizing ratio test.
Definition: spxfastrt.cpp:516
#define TRIES
Definition: spxfastrt.cpp:43
Real delta
allowed bound violation
minimize number of basic slack variables, i.e. more variables in between bounds
Definition: spxsolver.h:232
Real fastDelta
currently allowed infeasibility.
Definition: spxfastrt.h:52
#define SHORT
Definition: spxfastrt.cpp:44
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:527
virtual int selectLeave(Real &val, Real, bool polish=false)
Definition: spxfastrt.cpp:899
bool isId(const SPxId &p_id) const
Is p_id an SPxId ?
Definition: spxsolver.h:1135
bool minReLeave(Real &sel, int leave, Real maxabs, bool polish=false)
numerical stability tests.
Definition: spxfastrt.cpp:857
const Vector & lcBound() const
Definition: spxsolver.h:1438
void shiftLBbound(int i, Real to)
shift i &#39;th lbBound to to.
Definition: spxsolver.h:1584
Real epsilon
|value| < epsilon is considered 0.
Definition: spxfastrt.h:50
virtual void setType(SPxSolver::Type type)
Definition: spxfastrt.cpp:1493
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
int maxDelta(Real &val, Real &maxabs, UpdateVector &update, const Vector &lowBound, const Vector &upBound, int start, int incr) const
Max phase 1 value.
Definition: spxfastrt.cpp:104
void relax()
relaxes stability requirements.
Definition: spxfastrt.cpp:82
Desc::Status dualStatus(const SPxColId &id) const
dual Status for the column variable with ID id of the loaded LP.
Definition: spxbasis.cpp:34
#define LOWSTAB
Definition: spxfastrt.cpp:42
virtual Real value()
current objective value.
Definition: spxsolver.cpp:939
rowwise representation.
Definition: spxsolver.h:107
int * altIndexMem()
Returns array indices.
Definition: ssvectorbase.h:312
maximize number of basic slack variables, i.e. more variables on bounds
Definition: spxsolver.h:231
const R * get_const_ptr() const
Conversion to C-style pointer.
Definition: vectorbase.h:455
const Vector & ubBound() const
upper bound for fVec.
Definition: spxsolver.h:1341
Entering Simplex.
Definition: spxsolver.h:134
Real minStability(Real maxabs)
Compute stability requirement.
Definition: spxfastrt.cpp:89
R * altValues()
Returns array values.
Definition: ssvectorbase.h:319
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 resetTols()
resets tolerances (epsilon).
Definition: spxfastrt.cpp:48
Leaving Simplex.
Definition: spxsolver.h:143
double Real
Definition: spxdefines.h:218
const R * values() const
Returns array values.
Definition: ssvectorbase.h:300
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
const Vector & lbBound() const
lower bound for fVec.
Definition: spxsolver.h:1359
SPxId id(int i) const
id of i &#39;th vector.
Definition: spxsolver.h:1098
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1323
bool isSPxColId() const
is id a column id?
Definition: spxid.h:166
bool shortEnter(const SPxId &enterId, int nr, Real max, Real maxabs) const
Tests and returns whether a shortcut after phase 1 is feasible for the selected enter pivot...
Definition: spxfastrt.cpp:1285
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1263
Dense vector with semi-sparse vector for updatesIn many algorithms vectors are updated in every itera...
Definition: updatevector.h:53
void shiftUBbound(int i, Real to)
shift i &#39;th ubBound to to.
Definition: spxsolver.h:1576
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:504
const int * indexMem() const
Returns array indices.
Definition: ssvectorbase.h:294
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:784
Debugging, floating point type and parameter definitions.
void setSize(int n)
Sets number of nonzeros (thereby unSetup SSVectorBase).
Definition: ssvectorbase.h:584
void clearIdx(int i)
Clears element i.
Definition: ssvectorbase.h:254
bool isCoId(const SPxId &p_id) const
Is p_id a CoId.
Definition: spxsolver.h:1144
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:85
SolutionPolish polishObj
objective of solution polishing
Definition: spxsolver.h:246
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1478
bool minReEnter(Real &sel, Real maxabs, const SPxId &id, int nr, bool polish=false)
numerical stability check.
Definition: spxfastrt.cpp:1179
SPxSolver * thesolver
the solver
const Vector & lpBound() const
Definition: spxsolver.h:1504
int dim() const
Dimension of vector.
Definition: vectorbase.h:217
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:200
Everything should be within this namespace.
void tighten()
tightens stability requirements.
Definition: spxfastrt.cpp:58
bool iscoid
flag used in methods minSelect/maxSelect to retrieve correct basis status
Definition: spxfastrt.h:54
virtual SPxSolver * solver() const
returns loaded LP solver.
int maxSelect(Real &val, Real &stab, Real &best, Real &bestDelta, Real max, const UpdateVector &upd, const Vector &low, const Vector &up, int start=0, int incr=1) const
selects stable index for maximizing ratio test.
Definition: spxfastrt.cpp:597
bool minShortLeave(Real &sel, int leave, Real maxabs)
tests for stop after phase 1.
Definition: spxfastrt.cpp:793
int minDelta(Real &val, Real &maxabs, UpdateVector &update, const Vector &lowBound, const Vector &upBound, int start, int incr) const
Min phase 1 value.
Definition: spxfastrt.cpp:270
bool maxReLeave(Real &sel, int leave, Real maxabs, bool polish=false)
Definition: spxfastrt.cpp:815
virtual void load(SPxSolver *solver)
Definition: spxfastrt.cpp:1487
const Vector & upBound() const
Definition: spxsolver.h:1483
virtual SPxId selectEnter(Real &val, int, bool polish=false)
Definition: spxfastrt.cpp:1319
void forceSetup()
Forces setup status.
Definition: ssvectorbase.h:163
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:161
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:151
int size() const
return nr. of elements.
Definition: dataarray.h:214
Type type() const
return current Type.
Definition: spxsolver.h:512
Real theShift
sum of all shifts applied to any bound.
Definition: spxsolver.h:268
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:158
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
Real minStab
parameter for computing minimum stability requirement
Definition: spxfastrt.h:48
dual variable has two bounds
Definition: spxbasis.h:194
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1157
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
#define MINSTAB
Definition: spxfastrt.cpp:41
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1761
#define EPSILON
Definition: spxfastrt.cpp:46
Real stability() const
returns the stability of the basis matrix.
Definition: spxbasis.h:627
SPxSolver::Type m_type
internal storage of type
const Desc & desc() const
Definition: spxbasis.h:464
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:506
columnwise representation.
Definition: spxsolver.h:108
#define DELTA_SHIFT
Definition: spxfastrt.cpp:45