Scippy

SoPlex

Sequential object-oriented simPlex

spxboundflippingrt.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 "soplex/spxdefines.h"
19 #include "soplex/sorter.h"
20 #include "soplex/spxsolver.h"
21 #include "soplex/spxout.h"
22 #include "soplex/spxid.h"
23 
24 namespace soplex
25 {
26 
27 #define LOWSTAB 1e-10
28 #define MAX_RELAX_COUNT 2
29 #define LONGSTEP_FREQ 100
30 
31 
32 /** perform necessary bound flips to restore dual feasibility */
34  int& nflips /**< number of bounds that should be flipped */
35 )
36 {
37  assert(nflips > 0);
38 
39  // number of bound flips that are not performed
40  int skipped;
41 
42  updPrimRhs.setup();
45  updPrimRhs.clear();
46  updPrimVec.clear();
47 
48  skipped = 0;
49 
50  for(int i = 0; i < nflips; ++i)
51  {
52  int idx;
53  idx = breakpoints[i].idx;
54 
55  if(idx < 0)
56  {
57  ++skipped;
58  continue;
59  }
60 
61  Real range;
62  Real upper;
63  Real lower;
64  Real objChange = 0.0;
67 
68  range = 0;
69 
70  if(breakpoints[i].src == PVEC)
71  {
72  assert(thesolver->rep() == SPxSolver::COLUMN);
73  stat = ds.status(idx);
74  upper = thesolver->upper(idx);
75  lower = thesolver->lower(idx);
76 
77  switch(stat)
78  {
81  range = lower - upper;
82  assert((*thesolver->theLbound)[idx] == -infinity);
83  (*thesolver->theLbound)[idx] = (*thesolver->theUbound)[idx];
84  (*thesolver->theUbound)[idx] = infinity;
85  objChange = range * (*thesolver->theLbound)[idx];
86  break;
87 
90  range = upper - lower;
91  assert((*thesolver->theUbound)[idx] == infinity);
92  (*thesolver->theUbound)[idx] = (*thesolver->theLbound)[idx];
93  (*thesolver->theLbound)[idx] = -infinity;
94  objChange = range * (*thesolver->theUbound)[idx];
95  break;
96 
97  default :
98  ++skipped;
99  MSG_WARNING((*thesolver->spxout), (*thesolver->spxout) << "PVEC unexpected status: " << stat
100  << " index: " << idx
101  << " val: " << thesolver->pVec()[idx]
102  << " upd: " << thesolver->pVec().delta()[idx]
103  << " lower: " << lower
104  << " upper: " << upper
105  << " bp.val: " << breakpoints[i].val
106  << std::endl;)
107  }
108 
109  MSG_DEBUG(std::cout << "PVEC flipped from: " << stat
110  << " index: " << idx
111  << " val: " << thesolver->pVec()[idx]
112  << " upd: " << thesolver->pVec().delta()[idx]
113  << " lower: " << lower
114  << " upper: " << upper
115  << " bp.val: " << breakpoints[i].val
116  << " UCbound: " << thesolver->theUCbound[idx]
117  << " LCbound: " << thesolver->theLCbound[idx]
118  << std::endl;)
119  assert(spxAbs(range) < 1e20);
120  updPrimRhs.multAdd(range, thesolver->vector(idx));
121 
122  if(objChange != 0.0)
123  thesolver->updateNonbasicValue(objChange);
124  }
125  else if(breakpoints[i].src == COPVEC)
126  {
127  assert(thesolver->rep() == SPxSolver::COLUMN);
128  stat = ds.coStatus(idx);
129  upper = thesolver->rhs(idx);
130  lower = thesolver->lhs(idx);
131 
132  switch(stat)
133  {
136  range = lower - upper;
137  assert((*thesolver->theCoUbound)[idx] == infinity);
138  (*thesolver->theCoUbound)[idx] = -(*thesolver->theCoLbound)[idx];
139  (*thesolver->theCoLbound)[idx] = -infinity;
140  objChange = range * (*thesolver->theCoUbound)[idx];
141  break;
142 
145  range = upper - lower;
146  assert((*thesolver->theCoLbound)[idx] == -infinity);
147  (*thesolver->theCoLbound)[idx] = -(*thesolver->theCoUbound)[idx];
148  (*thesolver->theCoUbound)[idx] = infinity;
149  objChange = range * (*thesolver->theCoLbound)[idx];
150  break;
151 
152  default :
153  ++skipped;
154  MSG_WARNING((*thesolver->spxout), (*thesolver->spxout) << "COPVEC unexpected status: " << stat
155  << " index: " << idx
156  << " val: " << thesolver->coPvec()[idx]
157  << " upd: " << thesolver->coPvec().delta()[idx]
158  << " lower: " << lower
159  << " upper: " << upper
160  << " bp.val: " << breakpoints[i].val
161  << std::endl;)
162  }
163 
164  MSG_DEBUG(std::cout << "COPVEC flipped from: " << stat
165  << " index: " << idx
166  << " val: " << thesolver->coPvec()[idx]
167  << " upd: " << thesolver->coPvec().delta()[idx]
168  << " lower: " << lower
169  << " upper: " << upper
170  << " bp.val: " << breakpoints[i].val
171  << " URbound: " << thesolver->theURbound[idx]
172  << " LRbound: " << thesolver->theLRbound[idx]
173  << std::endl;)
174  assert(spxAbs(range) < 1e20);
175  updPrimRhs.setValue(idx, updPrimRhs[idx] - range);
176 
177  if(objChange != 0.0)
178  thesolver->updateNonbasicValue(objChange);
179  }
180  else if(breakpoints[i].src == FVEC)
181  {
182  assert(thesolver->rep() == SPxSolver::ROW);
183  SPxId baseId = thesolver->basis().baseId(idx);
184  int IdNumber;
185 
186  if(baseId.isSPxRowId())
187  {
188  IdNumber = thesolver->number(SPxRowId(baseId));
189  stat = ds.rowStatus(IdNumber);
190  upper = thesolver->rhs(IdNumber);
191  lower = thesolver->lhs(IdNumber);
192 
193  switch(stat)
194  {
196  ds.rowStatus(IdNumber) = SPxBasis::Desc::P_ON_LOWER;
197  range = upper - lower;
198  assert(thesolver->theUBbound[idx] == infinity);
199  thesolver->theUBbound[idx] = -thesolver->theLBbound[idx];
200  thesolver->theLBbound[idx] = -infinity;
201  break;
202 
204  ds.rowStatus(IdNumber) = SPxBasis::Desc::P_ON_UPPER;
205  range = lower - upper;
206  assert(thesolver->theLBbound[idx] == -infinity);
207  thesolver->theLBbound[idx] = -thesolver->theUBbound[idx];
208  thesolver->theUBbound[idx] = infinity;
209  break;
210 
211  default :
212  ++skipped;
213  MSG_WARNING((*thesolver->spxout), (*thesolver->spxout) << "unexpected basis status: " << stat
214  << " index: " << idx
215  << " val: " << thesolver->fVec()[idx]
216  << " upd: " << thesolver->fVec().delta()[idx]
217  << " lower: " << lower
218  << " upper: " << upper
219  << " bp.val: " << breakpoints[i].val
220  << std::endl;)
221  }
222  }
223  else
224  {
225  assert(baseId.isSPxColId());
226  IdNumber = thesolver->number(SPxColId(baseId));
227  stat = ds.colStatus(IdNumber);
228  upper = thesolver->upper(IdNumber);
229  lower = thesolver->lower(IdNumber);
230 
231  switch(stat)
232  {
234  ds.colStatus(IdNumber) = SPxBasis::Desc::P_ON_LOWER;
235  range = upper - lower;
236  assert(thesolver->theUBbound[idx] == infinity);
237  thesolver->theUBbound[idx] = -thesolver->theLBbound[idx];
238  thesolver->theLBbound[idx] = -infinity;
239  break;
240 
242  ds.colStatus(IdNumber) = SPxBasis::Desc::P_ON_UPPER;
243  range = lower - upper;
244  assert(thesolver->theLBbound[idx] == -infinity);
245  thesolver->theLBbound[idx] = -thesolver->theUBbound[idx];
246  thesolver->theUBbound[idx] = infinity;
247  break;
248 
249  default :
250  ++skipped;
251  MSG_WARNING((*thesolver->spxout), (*thesolver->spxout) << "FVEC unexpected status: " << stat
252  << " index: " << idx
253  << " val: " << thesolver->fVec()[idx]
254  << " upd: " << thesolver->fVec().delta()[idx]
255  << " lower: " << lower
256  << " upper: " << upper
257  << " bp.val: " << breakpoints[i].val
258  << std::endl;)
259  }
260  }
261 
262  MSG_DEBUG(std::cout << "basic row/col flipped from: " << stat
263  << " index: " << idx
264  << " val: " << thesolver->fVec()[idx]
265  << " upd: " << thesolver->fVec().delta()[idx]
266  << " lower: " << lower
267  << " upper: " << upper
268  << " bp.val: " << breakpoints[i].val
269  << std::endl;)
270  assert(spxAbs(range) < 1e20);
271  assert(updPrimRhs[idx] == 0);
272  updPrimRhs.add(idx, range);
273  }
274  }
275 
276  nflips -= skipped;
277 
278  if(nflips > 0)
279  {
280  if(thesolver->rep() == SPxSolver::ROW)
281  {
282  assert(m_type == SPxSolver::ENTER);
285  }
286  else
287  {
288  assert(thesolver->rep() == SPxSolver::COLUMN);
289  assert(m_type == SPxSolver::LEAVE);
292  }
293  }
294 
295  return;
296 }
297 
298 /** store all available pivots/breakpoints in an array (positive pivot search direction) */
300  int& nBp, /**< number of found breakpoints so far */
301  int& minIdx, /**< index to current minimal breakpoint */
302  const int* idx, /**< pointer to indices of current vector */
303  int nnz, /**< number of nonzeros in current vector */
304  const Real* upd, /**< pointer to update values of current vector */
305  const Real* vec, /**< pointer to values of current vector */
306  const Real* upp, /**< pointer to upper bound/rhs of current vector */
307  const Real* low, /**< pointer to lower bound/lhs of current vector */
308  BreakpointSource src /**< type of vector (pVec, coPvec or fVec)*/
309 )
310 {
311  Real minVal;
312  Real curVal;
313  const int* last;
314 
315  minVal = (nBp == 0) ? infinity : breakpoints[minIdx].val;
316 
317  last = idx + nnz;
318 
319  for(; idx < last; ++idx)
320  {
321  int i = *idx;
322  Real x = upd[i];
323 
324  if(x > epsilon)
325  {
326  if(upp[i] < infinity)
327  {
328  Real y = upp[i] - vec[i];
329  curVal = (y <= 0) ? fastDelta / x : (y + fastDelta) / x;
330  assert(curVal > 0);
331 
332  breakpoints[nBp].idx = i;
333  breakpoints[nBp].src = src;
334  breakpoints[nBp].val = curVal;
335 
336  if(curVal < minVal)
337  {
338  minVal = curVal;
339  minIdx = nBp;
340  }
341 
342  nBp++;
343  }
344  }
345  else if(x < -epsilon)
346  {
347  if(low[i] > -infinity)
348  {
349  Real y = low[i] - vec[i];
350  curVal = (y >= 0) ? -fastDelta / x : (y - fastDelta) / x;
351  assert(curVal > 0);
352 
353  breakpoints[nBp].idx = i;
354  breakpoints[nBp].src = src;
355  breakpoints[nBp].val = curVal;
356 
357  if(curVal < minVal)
358  {
359  minVal = curVal;
360  minIdx = nBp;
361  }
362 
363  nBp++;
364  }
365  }
366 
367  if(nBp >= breakpoints.size())
368  breakpoints.reSize(nBp * 2);
369  }
370 
371  return;
372 }
373 
374 /** store all available pivots/breakpoints in an array (negative pivot search direction) */
376  int& nBp, /**< number of found breakpoints so far */
377  int& minIdx, /**< index to current minimal breakpoint */
378  const int* idx, /**< pointer to indices of current vector */
379  int nnz, /**< number of nonzeros in current vector */
380  const Real* upd, /**< pointer to update values of current vector */
381  const Real* vec, /**< pointer to values of current vector */
382  const Real* upp, /**< pointer to upper bound/rhs of current vector */
383  const Real* low, /**< pointer to lower bound/lhs of current vector */
384  BreakpointSource src /**< type of vector (pVec, coPvec or fVec)*/
385 )
386 {
387  Real minVal;
388  Real curVal;
389  const int* last;
390 
391  minVal = (nBp == 0) ? infinity : breakpoints[minIdx].val;
392 
393  last = idx + nnz;
394 
395  for(; idx < last; ++idx)
396  {
397  int i = *idx;
398  Real x = upd[i];
399 
400  if(x > epsilon)
401  {
402  if(low[i] > -infinity)
403  {
404  Real y = low[i] - vec[i];
405 
406  curVal = (y >= 0) ? fastDelta / x : (fastDelta - y) / x;
407  assert(curVal > 0);
408 
409  breakpoints[nBp].idx = i;
410  breakpoints[nBp].src = src;
411  breakpoints[nBp].val = curVal;
412 
413  if(curVal < minVal)
414  {
415  minVal = curVal;
416  minIdx = nBp;
417  }
418 
419  nBp++;
420  }
421  }
422  else if(x < -epsilon)
423  {
424  if(upp[i] < infinity)
425  {
426  Real y = upp[i] - vec[i];
427  curVal = (y <= 0) ? -fastDelta / x : -(y + fastDelta) / x;
428  assert(curVal > 0);
429 
430  breakpoints[nBp].idx = i;
431  breakpoints[nBp].src = src;
432  breakpoints[nBp].val = curVal;
433 
434  if(curVal < minVal)
435  {
436  minVal = curVal;
437  minIdx = nBp;
438  }
439 
440  nBp++;
441  }
442  }
443 
444  if(nBp >= breakpoints.size())
445  breakpoints.reSize(nBp * 2);
446  }
447 
448  return;
449 }
450 
451 /** get values for entering index and perform shifts if necessary */
453  Real& val,
454  SPxId& enterId,
455  int idx,
456  Real stab,
457  Real degeneps,
458  const Real* upd,
459  const Real* vec,
460  const Real* low,
461  const Real* upp,
462  BreakpointSource src,
463  Real max
464 )
465 {
466  if(src == PVEC)
467  {
468  thesolver->pVec()[idx] = thesolver->vector(idx) * thesolver->coPvec();
469  Real x = upd[idx];
470 
471  // skip breakpoint if it is too small
472  if(spxAbs(x) < stab)
473  {
474  return false;
475  }
476 
477  enterId = thesolver->id(idx);
478  val = (max * x > 0) ? upp[idx] : low[idx];
479  val = (val - vec[idx]) / x;
480 
481  if(upp[idx] == low[idx])
482  {
483  val = 0.0;
484 
485  if(vec[idx] > upp[idx])
486  thesolver->theShift += vec[idx] - upp[idx];
487  else
488  thesolver->theShift += low[idx] - vec[idx];
489 
490  thesolver->upBound()[idx] = thesolver->lpBound()[idx] = vec[idx];
491  }
492  else if((max > 0 && val < -degeneps) || (max < 0 && val > degeneps))
493  {
494  val = 0.0;
495 
496  if(max * x > 0)
497  thesolver->shiftUPbound(idx, vec[idx]);
498  else
499  thesolver->shiftLPbound(idx, vec[idx]);
500  }
501  }
502  else // src == COPVEC
503  {
504  Real x = upd[idx];
505 
506  if(spxAbs(x) < stab)
507  {
508  return false;
509  }
510 
511  enterId = thesolver->coId(idx);
512  val = (max * x > 0.0) ? upp[idx] : low[idx];
513  val = (val - vec[idx]) / x;
514 
515  if(upp[idx] == low[idx])
516  {
517  val = 0.0;
518 
519  if(vec[idx] > upp[idx])
520  thesolver->theShift += vec[idx] - upp[idx];
521  else
522  thesolver->theShift += low[idx] - vec[idx];
523 
524  thesolver->ucBound()[idx] = thesolver->lcBound()[idx] = vec[idx];
525  }
526  else if((max > 0 && val < -degeneps) || (max < 0 && val > degeneps))
527  {
528  val = 0.0;
529 
530  if(max * x > 0)
531  thesolver->shiftUCbound(idx, vec[idx]);
532  else
533  thesolver->shiftLCbound(idx, vec[idx]);
534  }
535  }
536 
537  return true;
538 }
539 
540 /** get values for leaving index and perform shifts if necessary */
542  Real& val,
543  int& leaveIdx,
544  int idx,
545  Real stab,
546  Real degeneps,
547  const Real* upd,
548  const Real* vec,
549  const Real* low,
550  const Real* upp,
551  BreakpointSource src,
552  Real max
553 )
554 {
555  assert(src == FVEC);
556 
557  Real x = upd[idx];
558 
559  // skip breakpoint if it is too small
560  if(spxAbs(x) < stab)
561  {
562  return false;
563  }
564 
565  leaveIdx = idx;
566  val = (max * x > 0) ? upp[idx] : low[idx];
567  val = (val - vec[idx]) / x;
568 
569  if(upp[idx] == low[idx])
570  {
571  val = 0.0;
572  thesolver->shiftLBbound(idx, vec[idx]);
573  thesolver->shiftUBbound(idx, vec[idx]);
574  }
575  else if((max > 0 && val < -degeneps) || (max < 0 && val > degeneps))
576  {
577  val = 0.0;
578 
580  {
581  if(max * x > 0)
582  thesolver->shiftUBbound(idx, vec[idx]);
583  else
584  thesolver->shiftLBbound(idx, vec[idx]);
585  }
586  }
587 
588  return true;
589 }
590 
591 /** determine entering row/column */
593  Real& val,
594  int leaveIdx,
595  bool polish
596 )
597 {
598  assert(m_type == SPxSolver::LEAVE);
599  assert(thesolver->boundflips == 0);
600 
601  // reset the history and try again to do some long steps
603  {
604  MSG_DEBUG(std::cout << "DLBFRT06 resetting long step history" << std::endl;)
605  flipPotential = 1;
606  }
607 
608  if(!enableBoundFlips || polish || thesolver->rep() == SPxSolver::ROW || flipPotential <= 0)
609  {
610  MSG_DEBUG(std::cout << "DLBFRT07 switching to fast ratio test" << std::endl;)
611  return SPxFastRT::selectEnter(val, leaveIdx, polish);
612  }
613 
614  const Real* pvec = thesolver->pVec().get_const_ptr();
615  const Real* pupd = thesolver->pVec().delta().values();
616  const int* pidx = thesolver->pVec().delta().indexMem();
617  int pupdnnz = thesolver->pVec().delta().size();
618  const Real* lpb = thesolver->lpBound().get_const_ptr();
619  const Real* upb = thesolver->upBound().get_const_ptr();
620 
621  const Real* cvec = thesolver->coPvec().get_const_ptr();
622  const Real* cupd = thesolver->coPvec().delta().values();
623  const int* cidx = thesolver->coPvec().delta().indexMem();
624  int cupdnnz = thesolver->coPvec().delta().size();
625  const Real* lcb = thesolver->lcBound().get_const_ptr();
626  const Real* ucb = thesolver->ucBound().get_const_ptr();
627 
628  resetTols();
629 
630  Real max;
631 
632  // index in breakpoint array of minimal value (i.e. choice of normal RT)
633  int minIdx;
634 
635  // temporary breakpoint data structure to make swaps possible
636  Breakpoint tmp;
637 
638  // most stable pivot value in candidate set
639  Real moststable;
640 
641  // initialize invalid enterId
642  SPxId enterId;
643 
644  // slope of objective function improvement
645  Real slope;
646 
647  // number of found breakpoints
648  int nBp;
649 
650  // number of passed breakpoints
651  int npassedBp;
652 
653  Real degeneps;
654  Real stab;
655  bool instable;
656 
657  max = val;
658  val = 0.0;
659  moststable = 0.0;
660  nBp = 0;
661  minIdx = -1;
662 
663  // get breakpoints and and determine the index of the minimal value
664  if(max > 0)
665  {
666  collectBreakpointsMax(nBp, minIdx, pidx, pupdnnz, pupd, pvec, upb, lpb, PVEC);
667  collectBreakpointsMax(nBp, minIdx, cidx, cupdnnz, cupd, cvec, ucb, lcb, COPVEC);
668  }
669  else
670  {
671  collectBreakpointsMin(nBp, minIdx, pidx, pupdnnz, pupd, pvec, upb, lpb, PVEC);
672  collectBreakpointsMin(nBp, minIdx, cidx, cupdnnz, cupd, cvec, ucb, lcb, COPVEC);
673  }
674 
675  if(nBp == 0)
676  {
677  val = max;
678  return enterId;
679  }
680 
681  assert(minIdx >= 0);
682 
683  // swap smallest breakpoint to the front to skip the sorting phase if no bound flip is possible
684  tmp = breakpoints[minIdx];
685  breakpoints[minIdx] = breakpoints[0];
686  breakpoints[0] = tmp;
687 
688  // get initial slope
689  slope = spxAbs(thesolver->fTest()[leaveIdx]);
690 
691  if(slope == 0)
692  {
693  // this may only happen if SoPlex decides to make an instable pivot
694  assert(thesolver->instableLeaveNum >= 0);
695  // restore original slope
697  }
698 
699  // set up structures for the quicksort implementation
700  BreakpointCompare compare;
701  compare.entry = breakpoints.get_const_ptr();
702 
703  // pointer to end of sorted part of breakpoints
704  int sorted = 0;
705  // minimum number of entries that are supposed to be sorted by partial sort
706  int sortsize = 4;
707 
708  // get all skipable breakpoints
709  for(npassedBp = 0; npassedBp < nBp && slope > 0; ++npassedBp)
710  {
711  // sort breakpoints only partially to save time
712  if(npassedBp > sorted)
713  {
714  sorted = SPxQuicksortPart(breakpoints.get_ptr(), compare, sorted + 1, nBp, sortsize);
715  }
716 
717  int i = breakpoints[npassedBp].idx;
718 
719  // compute new slope
720  if(breakpoints[npassedBp].src == PVEC)
721  {
722  if(thesolver->isBasic(i))
723  {
724  // mark basic indices
725  breakpoints[npassedBp].idx = -1;
726  thesolver->pVec().delta().clearIdx(i);
727  }
728  else
729  {
730  Real absupd = spxAbs(pupd[i]);
731  slope -= (thesolver->upper(i) * absupd) - (thesolver->lower(i) * absupd);
732 
733  // get most stable pivot
734  if(absupd > moststable)
735  moststable = absupd;
736  }
737  }
738  else
739  {
740  assert(breakpoints[npassedBp].src == COPVEC);
741 
742  if(thesolver->isCoBasic(i))
743  {
744  // mark basic indices
745  breakpoints[npassedBp].idx = -1;
746  thesolver->coPvec().delta().clearIdx(i);
747  }
748  else
749  {
750  Real absupd = spxAbs(cupd[i]);
751  slope -= (thesolver->rhs(i) * absupd) - (thesolver->lhs(i) * absupd);
752 
753  if(absupd > moststable)
754  moststable = absupd;
755  }
756  }
757  }
758 
759  --npassedBp;
760  assert(npassedBp >= 0);
761 
762  // check for unboundedness/infeasibility
763  if(slope > delta && npassedBp >= nBp - 1)
764  {
765  MSG_DEBUG(std::cout << "DLBFRT02 " << thesolver->basis().iteration()
766  << ": unboundedness in ratio test" << std::endl;)
767  flipPotential -= 0.5;
768  val = max;
769  return SPxFastRT::selectEnter(val, leaveIdx);
770  }
771 
772  MSG_DEBUG(std::cout << "DLBFRT01 "
773  << thesolver->basis().iteration()
774  << ": number of flip candidates: "
775  << npassedBp
776  << std::endl;)
777 
778  // try to get a more stable pivot by looking at those with similar step length
779  int stableBp; // index to walk over additional breakpoints (after slope change)
780  int bestBp = -1; // breakpoints index with best possible stability
781  Real bestDelta = breakpoints[npassedBp].val; // best step length (after bound flips)
782 
783  for(stableBp = npassedBp + 1; stableBp < nBp; ++stableBp)
784  {
785  Real stableDelta = 0;
786 
787  // get next breakpoints in increasing order
788  if(stableBp > sorted)
789  {
790  sorted = SPxQuicksortPart(breakpoints.get_ptr(), compare, sorted + 1, nBp, sortsize);
791  }
792 
793  int idx = breakpoints[stableBp].idx;
794 
795  if(breakpoints[stableBp].src == PVEC)
796  {
797  if(thesolver->isBasic(idx))
798  {
799  // mark basic indices
800  breakpoints[stableBp].idx = -1;
801  thesolver->pVec().delta().clearIdx(idx);
802  continue;
803  }
804 
805  Real x = pupd[idx];
806 
807  if(spxAbs(x) > moststable)
808  {
809  thesolver->pVec()[idx] = thesolver->vector(idx) * thesolver->coPvec();
810  stableDelta = (x > 0.0) ? upb[idx] : lpb[idx];
811  stableDelta = (stableDelta - pvec[idx]) / x;
812 
813  if(stableDelta <= bestDelta)
814  {
815  moststable = spxAbs(x);
816  bestBp = stableBp;
817  }
818  }
819  }
820  else
821  {
822  if(thesolver->isCoBasic(idx))
823  {
824  // mark basic indices
825  breakpoints[stableBp].idx = -1;
826  thesolver->coPvec().delta().clearIdx(idx);
827  continue;
828  }
829 
830  Real x = cupd[idx];
831 
832  if(spxAbs(x) > moststable)
833  {
834  stableDelta = (x > 0.0) ? ucb[idx] : lcb[idx];
835  stableDelta = (stableDelta - cvec[idx]) / x;
836 
837  if(stableDelta <= bestDelta)
838  {
839  moststable = spxAbs(x);
840  bestBp = stableBp;
841  }
842  }
843  }
844 
845  // stop searching if the step length is too big
846  if(stableDelta > delta + bestDelta)
847  break;
848  }
849 
850  degeneps = fastDelta / moststable; /* as in SPxFastRT */
851  // get stability requirements
852  instable = thesolver->instableLeave;
853  assert(!instable || thesolver->instableLeaveNum >= 0);
854  stab = instable ? LOWSTAB : SPxFastRT::minStability(moststable);
855 
856  bool foundStable = false;
857 
858  if(bestBp >= 0)
859  {
860  // found a more stable pivot
861  if(moststable > stab)
862  {
863  // stability requirements are satisfied
864  int idx = breakpoints[bestBp].idx;
865  assert(idx >= 0);
866 
867  if(breakpoints[bestBp].src == PVEC)
868  foundStable = getData(val, enterId, idx, stab, degeneps, pupd, pvec, lpb, upb, PVEC, max);
869  else
870  foundStable = getData(val, enterId, idx, stab, degeneps, cupd, cvec, lcb, ucb, COPVEC, max);
871  }
872  }
873 
874  else
875  {
876  // scan passed breakpoints from back to front and stop as soon as a good one is found
877  while(!foundStable && npassedBp >= 0)
878  {
879  int idx = breakpoints[npassedBp].idx;
880 
881  // only look for non-basic variables
882  if(idx >= 0)
883  {
884  if(breakpoints[npassedBp].src == PVEC)
885  foundStable = getData(val, enterId, idx, stab, degeneps, pupd, pvec, lpb, upb, PVEC, max);
886  else
887  foundStable = getData(val, enterId, idx, stab, degeneps, cupd, cvec, lcb, ucb, COPVEC, max);
888  }
889 
890  --npassedBp;
891  }
892 
893  ++npassedBp;
894  }
895 
896  if(!foundStable)
897  {
898  assert(!enterId.isValid());
899 
901  {
902  MSG_DEBUG(std::cout << "DLBFRT04 "
903  << thesolver->basis().iteration()
904  << ": no valid enterId found - relaxing..."
905  << std::endl;)
906  relax();
907  ++relax_count;
908  // restore original value
909  val = max;
910  // try again with relaxed delta
911  return SPxBoundFlippingRT::selectEnter(val, leaveIdx);
912  }
913  else
914  {
915  MSG_DEBUG(std::cout << "DLBFRT05 "
916  << thesolver->basis().iteration()
917  << " no valid enterId found - breaking..."
918  << std::endl;)
919  return enterId;
920  }
921  }
922  else
923  {
924  relax_count = 0;
925  tighten();
926  }
927 
928  // flip bounds of skipped breakpoints only if a nondegenerate step is to be performed
929  if(npassedBp > 0 && spxAbs(breakpoints[npassedBp].val) > fastDelta)
930  {
931  flipAndUpdate(npassedBp);
932  thesolver->boundflips = npassedBp;
933 
934  if(npassedBp >= 10)
935  flipPotential = 1;
936  else
937  flipPotential -= 0.05;
938  }
939  else
940  {
941  thesolver->boundflips = 0;
942  flipPotential -= 0.1;
943  }
944 
945  MSG_DEBUG(std::cout << "DLBFRT06 "
946  << thesolver->basis().iteration()
947  << ": selected Id: "
948  << enterId
949  << " number of candidates: "
950  << nBp
951  << std::endl;)
952  return enterId;
953 }
954 
955 /** determine leaving row/column */
957  Real& val,
958  Real enterTest,
959  bool polish
960 )
961 {
962  assert(m_type == SPxSolver::ENTER);
963  assert(thesolver->boundflips == 0);
964 
965  // reset the history and try again to do some long steps
967  {
968  MSG_DEBUG(std::cout << "DEBFRT06 resetting long step history" << std::endl;)
969  flipPotential = 1;
970  }
971 
973  || flipPotential <= 0)
974  {
975  MSG_DEBUG(std::cout << "DEBFRT07 switching to fast ratio test" << std::endl;)
976  return SPxFastRT::selectLeave(val, enterTest, polish);
977  }
978 
979  const Real* vec =
980  thesolver->fVec().get_const_ptr(); /**< pointer to values of current vector */
981  const Real* upd =
982  thesolver->fVec().delta().values(); /**< pointer to update values of current vector */
983  const int* idx =
984  thesolver->fVec().delta().indexMem(); /**< pointer to indices of current vector */
985  int updnnz =
986  thesolver->fVec().delta().size(); /**< number of nonzeros in update vector */
987  const Real* lb =
988  thesolver->lbBound().get_const_ptr(); /**< pointer to lower bound/lhs of current vector */
989  const Real* ub =
990  thesolver->ubBound().get_const_ptr(); /**< pointer to upper bound/rhs of current vector */
991 
992  resetTols();
993 
994  Real max;
995 
996  // index in breakpoint array of minimal value (i.e. choice of normal RT)
997  int minIdx;
998 
999  // temporary breakpoint data structure to make swaps possible
1000  Breakpoint tmp;
1001 
1002  // most stable pivot value in candidate set
1003  Real moststable;
1004 
1005  // initialize invalid leaving index
1006  int leaveIdx = -1;
1007 
1008  // slope of objective function improvement
1009  Real slope;
1010 
1011  // number of found breakpoints
1012  int nBp;
1013 
1014  // number of passed breakpoints
1015  int npassedBp;
1016 
1017  Real degeneps;
1018  Real stab;
1019  bool instable;
1020 
1021  max = val;
1022  val = 0.0;
1023  moststable = 0.0;
1024  nBp = 0;
1025  minIdx = -1;
1026 
1027  assert(thesolver->fVec().delta().isSetup());
1028 
1029  // get breakpoints and and determine the index of the minimal value
1030  if(max > 0)
1031  {
1032  collectBreakpointsMax(nBp, minIdx, idx, updnnz, upd, vec, ub, lb, FVEC);
1033  }
1034  else
1035  {
1036  collectBreakpointsMin(nBp, minIdx, idx, updnnz, upd, vec, ub, lb, FVEC);
1037  }
1038 
1039  // return -1 if no BP was found
1040  if(nBp == 0)
1041  {
1042  val = max;
1043  return leaveIdx;
1044  }
1045 
1046  assert(minIdx >= 0);
1047 
1048  // swap smallest breakpoint to the front to skip the sorting phase if no bound flip is possible
1049  tmp = breakpoints[minIdx];
1050  breakpoints[minIdx] = breakpoints[0];
1051  breakpoints[0] = tmp;
1052 
1053  // get initial slope
1054  slope = spxAbs(enterTest);
1055 
1056  if(slope == 0)
1057  {
1058  // this may only happen if SoPlex decides to make an instable pivot
1059  assert(thesolver->instableEnterId.isValid());
1060  // restore original slope
1061  slope = thesolver->instableEnterVal;
1062  }
1063 
1064  // set up structures for the quicksort implementation
1065  BreakpointCompare compare;
1066  compare.entry = breakpoints.get_const_ptr();
1067 
1068  // pointer to end of sorted part of breakpoints
1069  int sorted = 0;
1070  // minimum number of entries that are supposed to be sorted by partial sort
1071  int sortsize = 4;
1072 
1073  // get all skipable breakpoints
1074  for(npassedBp = 0; npassedBp < nBp && slope > 0; ++npassedBp)
1075  {
1076  // sort breakpoints only partially to save time
1077  if(npassedBp > sorted)
1078  {
1079  sorted = SPxQuicksortPart(breakpoints.get_ptr(), compare, sorted + 1, nBp, sortsize);
1080  }
1081 
1082  assert(breakpoints[npassedBp].src == FVEC);
1083  int breakpointidx = breakpoints[npassedBp].idx;
1084  // compute new slope
1085  Real upper;
1086  Real lower;
1087  Real absupd = spxAbs(upd[breakpointidx]);
1088  SPxId baseId = thesolver->baseId(breakpointidx);
1089  int i = thesolver->number(baseId);
1090 
1091  if(baseId.isSPxColId())
1092  {
1093  upper = thesolver->upper(i);
1094  lower = thesolver->lower(i);
1095  }
1096  else
1097  {
1098  assert(baseId.isSPxRowId());
1099  upper = thesolver->rhs(i);
1100  lower = thesolver->lhs(i);
1101  }
1102 
1103  slope -= (upper * absupd) - (lower * absupd);
1104 
1105  // get most stable pivot
1106  if(absupd > moststable)
1107  moststable = absupd;
1108  }
1109 
1110  --npassedBp;
1111  assert(npassedBp >= 0);
1112 
1113  // check for unboundedness/infeasibility
1114  if(slope > delta && npassedBp >= nBp - 1)
1115  {
1116  MSG_DEBUG(std::cout << "DEBFRT02 " << thesolver->basis().iteration()
1117  << ": unboundedness in ratio test" << std::endl;)
1118  flipPotential -= 0.5;
1119  val = max;
1120  return SPxFastRT::selectLeave(val, enterTest);
1121  }
1122 
1123  MSG_DEBUG(std::cout << "DEBFRT01 "
1124  << thesolver->basis().iteration()
1125  << ": number of flip candidates: "
1126  << npassedBp
1127  << std::endl;)
1128 
1129  // try to get a more stable pivot by looking at those with similar step length
1130  int stableBp; // index to walk over additional breakpoints (after slope change)
1131  int bestBp = -1; // breakpoints index with best possible stability
1132  Real bestDelta = breakpoints[npassedBp].val; // best step length (after bound flips)
1133 
1134  for(stableBp = npassedBp + 1; stableBp < nBp; ++stableBp)
1135  {
1136  Real stableDelta = 0;
1137 
1138  // get next breakpoints in increasing order
1139  if(stableBp > sorted)
1140  {
1141  sorted = SPxQuicksortPart(breakpoints.get_ptr(), compare, sorted + 1, nBp, sortsize);
1142  }
1143 
1144  int breakpointidx = breakpoints[stableBp].idx;
1145  assert(breakpoints[stableBp].src == FVEC);
1146  Real x = upd[breakpointidx];
1147 
1148  if(spxAbs(x) > moststable)
1149  {
1150  stableDelta = (x > 0.0) ? ub[breakpointidx] : lb[breakpointidx];
1151  stableDelta = (stableDelta - vec[breakpointidx]) / x;
1152 
1153  if(stableDelta <= bestDelta)
1154  {
1155  moststable = spxAbs(x);
1156  bestBp = stableBp;
1157  }
1158  }
1159  // stop searching if the step length is too big
1160  else if(stableDelta > delta + bestDelta)
1161  break;
1162  }
1163 
1164  degeneps = fastDelta / moststable; /* as in SPxFastRT */
1165  // get stability requirements
1166  instable = thesolver->instableEnter;
1167  assert(!instable || thesolver->instableEnterId.isValid());
1168  stab = instable ? LOWSTAB : SPxFastRT::minStability(moststable);
1169 
1170  bool foundStable = false;
1171 
1172  if(bestBp >= 0)
1173  {
1174  // found a more stable pivot
1175  if(moststable > stab)
1176  {
1177  // stability requirements are satisfied
1178  int breakpointidx = breakpoints[bestBp].idx;
1179  assert(breakpointidx >= 0);
1180  foundStable = getData(val, leaveIdx, breakpointidx, moststable, degeneps, upd, vec, lb, ub, FVEC,
1181  max);
1182  }
1183  }
1184 
1185  else
1186  {
1187  // scan passed breakpoints from back to front and stop as soon as a good one is found
1188  while(!foundStable && npassedBp >= 0)
1189  {
1190  int breakpointidx = breakpoints[npassedBp].idx;
1191 
1192  // only look for non-basic variables
1193  if(breakpointidx >= 0)
1194  {
1195  foundStable = getData(val, leaveIdx, breakpointidx, moststable, degeneps, upd, vec, lb, ub, FVEC,
1196  max);
1197  }
1198 
1199  --npassedBp;
1200  }
1201 
1202  ++npassedBp;
1203  }
1204 
1205  if(!foundStable)
1206  {
1207  assert(leaveIdx < 0);
1208 
1210  {
1211  MSG_DEBUG(std::cout << "DEBFRT04 "
1212  << thesolver->basis().iteration()
1213  << ": no valid leaveIdx found - relaxing..."
1214  << std::endl;)
1215  relax();
1216  ++relax_count;
1217  // restore original value
1218  val = max;
1219  // try again with relaxed delta
1220  return SPxBoundFlippingRT::selectLeave(val, enterTest);
1221  }
1222  else
1223  {
1224  MSG_DEBUG(std::cout << "DEBFRT05 "
1225  << thesolver->basis().iteration()
1226  << " no valid leaveIdx found - breaking..."
1227  << std::endl;)
1228  return leaveIdx;
1229  }
1230  }
1231  else
1232  {
1233  relax_count = 0;
1234  tighten();
1235  }
1236 
1237  // flip bounds of skipped breakpoints only if a nondegenerate step is to be performed
1238  if(npassedBp > 0 && spxAbs(breakpoints[npassedBp].val) > fastDelta)
1239  {
1240  flipAndUpdate(npassedBp);
1241  thesolver->boundflips = npassedBp;
1242 
1243  if(npassedBp >= 10)
1244  flipPotential = 1;
1245  else
1246  flipPotential -= 0.05;
1247  }
1248  else
1249  {
1250  thesolver->boundflips = 0;
1251  flipPotential -= 0.1;
1252  }
1253 
1254  MSG_DEBUG(std::cout << "DEBFRT06 "
1255  << thesolver->basis().iteration()
1256  << ": selected Index: "
1257  << leaveIdx
1258  << " number of candidates: "
1259  << nBp
1260  << std::endl;)
1261 
1262  return leaveIdx;
1263 }
1264 
1265 
1266 } // namespace soplex
const VectorBase< R > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:221
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:4102
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
Status & coStatus(int i)
Definition: spxbasis.h:284
void collectBreakpointsMax(int &nBp, int &minIdx, const int *idx, int nnz, const Real *upd, const Real *vec, const Real *upp, const Real *low, BreakpointSource src)
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:121
int boundflips
number of performed bound flips
Definition: spxsolver.h:392
const VectorBase< R > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:461
const Vector & fTest() const
Violations of fVec.
Definition: spxsolver.h:1385
SPxOut * spxout
message handler
Definition: spxsolver.h:463
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
DVector * theUbound
Upper bound for vars.
Definition: spxsolver.h:375
DVector * theCoUbound
Upper bound for covars.
Definition: spxsolver.h:377
Real delta
allowed bound violation
#define LOWSTAB
Status & rowStatus(int i)
Definition: spxbasis.h:239
virtual int selectLeave(Real &val, Real enterTest, bool polish=false)
Real fastDelta
currently allowed infeasibility.
Definition: spxfastrt.h:52
void setValue(int i, R x)
Sets i &#39;th element to x.
Definition: ssvectorbase.h:219
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
const Vector & lcBound() const
Definition: spxsolver.h:1438
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1075
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
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
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
rowwise representation.
Definition: spxsolver.h:107
void collectBreakpointsMin(int &nBp, int &minIdx, const int *idx, int nnz, const Real *upd, const Real *vec, const Real *upp, const Real *low, BreakpointSource src)
const R * get_const_ptr() const
Conversion to C-style pointer.
Definition: vectorbase.h:455
Wrapper for different output streams and verbosity levels.
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
primal variable is set to its upper bound
Definition: spxbasis.h:188
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
UpdateVector & coPvec() const
copricing vector.
Definition: spxsolver.h:1398
void 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
DVector * theFrhs
Definition: spxsolver.h:360
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
void shiftLPbound(int i, Real to)
shift i &#39;th lpBound to to.
Definition: spxsolver.h:1600
Row and columns Id&#39;s SPxLP.
DVector * theLbound
Lower bound for vars.
Definition: spxsolver.h:376
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
SPxId instableEnterId
Definition: spxsolver.h:305
bool isSPxColId() const
is id a column id?
Definition: spxid.h:166
DVector theLBbound
Lower Basic Feasibility bound.
Definition: spxsolver.h:357
main LP solver class
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1263
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:255
void clear()
Clears vector.
Definition: ssvectorbase.h:603
void shiftUCbound(int i, Real to)
shift i &#39;th ucBound to to.
Definition: spxsolver.h:1608
bool updateNonbasicValue(Real objChange)
Definition: spxsolver.cpp:962
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:346
virtual SPxId selectEnter(Real &val, int leaveIdx, bool polish=false)
SSVectorBase< R > & multAdd(S xx, const SVectorBase< T > &vec)
Addition of a scaled vector.
Definition: basevectors.h:409
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
Generic QuickSort implementation.
const int * indexMem() const
Returns array indices.
Definition: ssvectorbase.h:294
DVector theUBbound
Upper Basic Feasibility bound.
Definition: spxsolver.h:356
Bound flipping ratio test (long step dual) for SoPlex.
DVector * theCoLbound
Lower bound for covars.
Definition: spxsolver.h:378
void reDim(int newdim)
Resets dimension to newdim.
Definition: ssvectorbase.h:569
Debugging, floating point type and parameter definitions.
void clearIdx(int i)
Clears element i.
Definition: ssvectorbase.h:254
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1478
SPxSolver * thesolver
the solver
const Vector & lpBound() const
Definition: spxsolver.h:1504
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:347
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:348
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:200
Everything should be within this namespace.
void shiftUPbound(int i, Real to)
shift i &#39;th upBound to to.
Definition: spxsolver.h:1592
void shiftLCbound(int i, Real to)
shift i &#39;th lcBound to to.
Definition: spxsolver.h:1616
void tighten()
tightens stability requirements.
Definition: spxfastrt.cpp:58
#define LONGSTEP_FREQ
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:116
primal variable is set to its lower bound
Definition: spxbasis.h:187
bool getData(Real &val, SPxId &enterId, int idx, Real stab, Real degeneps, const Real *upd, const Real *vec, const Real *low, const Real *upp, BreakpointSource src, Real max)
void setup()
Initializes nonzero indices for elements with absolute values above epsilon and sets all other elemen...
Definition: ssvectorbase.h:133
DVector theLCbound
Lower Column Feasibility bound.
Definition: spxsolver.h:349
int leaveCount
number of LEAVE iterations
Definition: spxsolver.h:387
int SPxQuicksortPart(T *keys, COMPARATOR &compare, int start, int end, int size, int start2=0, int end2=0, bool type=true)
Generic implementation of Partial QuickSort.
Definition: sorter.h:227
const Vector & upBound() const
Definition: spxsolver.h:1483
virtual SPxId selectEnter(Real &val, int, bool polish=false)
Definition: spxfastrt.cpp:1319
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:161
DVector * theCoPrhs
Definition: spxsolver.h:365
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:151
Real theShift
sum of all shifts applied to any bound.
Definition: spxsolver.h:268
#define MAX_RELAX_COUNT
DataArray< Breakpoint > breakpoints
int enterCount
number of ENTER iterations
Definition: spxsolver.h:388
bool isCoBasic(int i) const
is the i &#39;th covector basic ?
Definition: spxsolver.h:1308
dual variable has two bounds
Definition: spxbasis.h:194
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1157
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
Status & status(int i)
Definition: spxbasis.h:269
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1761
void setup4solve2(SSVector *p_y2, SSVector *p_rhs2)
Setup vectors to be solved within Simplex loop.
Definition: spxsolver.h:1708
Status
Status of a variable.
Definition: spxbasis.h:185
void add(int i, R x)
Adds nonzero (i, x) to SSVectorBase.
Definition: ssvectorbase.h:209
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:488
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
void setup4coSolve2(SSVector *p_z, SSVector *p_rhs)
Setup vectors to be cosolved within Simplex loop.
Definition: spxsolver.h:1734