Scippy

SoPlex

Sequential object-oriented simPlex

enter.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 /* \SubSection{Updating the Basis for Entering Variables}
17  */
18 #include <assert.h>
19 
20 #include "soplex/spxdefines.h"
21 #include "soplex/spxratiotester.h"
22 #include "soplex/spxpricer.h"
23 #include "soplex/spxout.h"
24 #include "soplex/exceptions.h"
25 #include "soplex/stablesum.h"
26 
27 namespace soplex
28 {
29 
30 /*
31 In the entering simplex algorithms (i.e. iteratively a vector is selected to
32 \em enter the simplex basis as in the dual rowwise and primal columnwise case)
33 let $A$ denote the current basis, $x$ and entering vector and $f$ the
34 feasibility vector. For a feasible basis $l \le f \le u$ holds.
35 For the rowwise case $f$ is obtained by solving $f^T = c^T A^{-1}$,
36 wherease in columnwisecase $f = A^{-1} b$.
37 
38 Let us further consider the rowwise case. Exchanging $x$ with the $i$-th
39 vector of $A$ yields
40 
41 \begin{equation}\label{update.eq}
42  A^{(i)} = E_i A \hbox{, with } E_i = I + e_i (x^T A^{-1} - e_i^T).
43 \end{equation}
44 
45 With $E_i^{-1} = I + e_i \frac{e_i^T - \delta^T}{\delta}$,
46 $\delta^T = x^T A^{-1}$ one gets the new feasibility vector
47 
48 \begin{eqnarray*}
49  (f^{(i)})^T
50  &=& c^T (A^{(i)})^{-1} \\
51  &=& c^T A^{-1} + c^T A^{-1} e_i \frac{e_i^T - \delta^T}{\delta_i} \\
52  &=& f^T + \frac{f_i}{\delta_i} e_i^T - \frac{f_i}{\delta_i} \delta^T. \\
53 \end{eqnarray*}
54 
55 The selection of the leaving vector $i^*$ for the basis must ensure, that for
56 all $j \ne i^*$ $f^{(i^*)}_j$ remains within its bounds $l_j$ and $u_j$.
57  */
58 
59 
60 /*
61  Testing all values of |pVec| against its bounds. If $i$, say, is violated
62  the violation is saved as negative value in |theTest[i]|.
63  */
65 {
66  assert(type() == ENTER);
67  assert(!isBasic(stat));
68 
69  Real x;
70 
71  switch(stat)
72  {
75  assert(rep() == ROW);
76  x = (*thePvec)[i] - lhs(i);
77 
78  if(x < 0)
79  return x;
80 
81  // no break: next is else case
82  //lint -fallthrough
84  assert(rep() == ROW);
85  return rhs(i) - (*thePvec)[i];
86 
88  assert(rep() == ROW);
89  return (*thePvec)[i] - lhs(i);
90 
92  assert(rep() == COLUMN);
93  return maxObj(i) - (*thePvec)[i];
94 
96  assert(rep() == COLUMN);
97  return (*thePvec)[i] - maxObj(i);
98 
100  x = maxObj(i) - (*thePvec)[i];
101  return (x < 0) ? x : -x;
102 
103  default:
104  return 0;
105  }
106 }
107 
109 {
110 
111  const SPxBasis::Desc& ds = desc();
112  Real pricingTol = leavetol();
114  m_pricingViolCo = 0;
116  int ninfeasibilities = 0;
117  int sparsitythreshold = (int)(sparsePricingFactor * coDim());
118 
119  for(int i = 0; i < coDim(); ++i)
120  {
121  SPxBasis::Desc::Status stat = ds.status(i);
122 
123  if(isBasic(stat))
124  {
125  theTest[i] = 0.0;
126 
127  if(remainingRoundsEnterCo == 0)
129  }
130  else
131  {
132  assert(!isBasic(stat));
133  theTest[i] = test(i, stat);
134 
135  if(remainingRoundsEnterCo == 0)
136  {
137  if(theTest[i] < -pricingTol)
138  {
140  m_pricingViolCo -= theTest[i];
143  ++ninfeasibilities;
144  }
145  else
147 
148  if(ninfeasibilities > sparsitythreshold)
149  {
150  MSG_INFO2((*spxout), (*spxout) << " --- using dense pricing"
151  << std::endl;)
153  sparsePricingEnterCo = false;
154  ninfeasibilities = 0;
155  }
156  }
157  else if(theTest[i] < -pricingTol)
158  m_pricingViolCo -= theTest[i];
159  }
160  }
161 
162  if(ninfeasibilities == 0 && !sparsePricingEnterCo)
164  else if(ninfeasibilities <= sparsitythreshold && !sparsePricingEnterCo)
165  {
166  MSG_INFO2((*spxout),
167  std::streamsize prec = spxout->precision();
168 
170  (*spxout) << " --- using hypersparse pricing, ";
171  else
172  (*spxout) << " --- using sparse pricing, ";
173  (*spxout) << "sparsity: "
174  << std::setw(6) << std::fixed << std::setprecision(4)
175  << (Real) ninfeasibilities / coDim()
176  << std::scientific << std::setprecision(int(prec))
177  << std::endl;
178  )
179  sparsePricingEnterCo = true;
180  }
181 }
182 
184 {
185 
186  return (*thePvec)[i] = vector(i) * (*theCoPvec);
187 }
188 
190 {
191  SPxBasis::Desc::Status stat = desc().status(i);
192 
193  if(isBasic(stat))
194  return theTest[i] = 0;
195  else
196  return theTest[i] = test(i, stat);
197 }
198 
199 /*
200  Testing all values of #coPvec# against its bounds. If $i$, say, is violated
201  the violation is saved as negative value in |theCoTest[i]|.
202  */
204 {
205  assert(type() == ENTER);
206  assert(!isBasic(stat));
207 
208  Real x;
209 
210  switch(stat)
211  {
214  assert(rep() == ROW);
215  x = (*theCoPvec)[i] - SPxLP::lower(i);
216 
217  if(x < 0)
218  return x;
219 
220  // no break: next is else case
221  //lint -fallthrough
223  assert(rep() == ROW);
224  return SPxLP::upper(i) - (*theCoPvec)[i];
225 
227  assert(rep() == ROW);
228  return (*theCoPvec)[i] - SPxLP::lower(i);
229 
231  assert(rep() == COLUMN);
232  return (*theCoPvec)[i] - maxRowObj(i); // slacks !
233 
235  assert(rep() == COLUMN);
236  return maxRowObj(i) - (*theCoPvec)[i]; // slacks !
237 
238  default:
239  return 0;
240  }
241 }
242 
244 {
245  int i;
246  Real pricingTol = leavetol();
247  m_pricingViolUpToDate = true;
248  m_pricingViol = 0;
250  int ninfeasibilities = 0;
251  int sparsitythreshold = (int)(sparsePricingFactor * dim());
252  const SPxBasis::Desc& ds = desc();
253 
254  for(i = dim() - 1; i >= 0; --i)
255  {
256  SPxBasis::Desc::Status stat = ds.coStatus(i);
257 
258  if(isBasic(stat))
259  {
260  theCoTest[i] = 0;
261 
262  if(remainingRoundsEnter == 0)
264  }
265  else
266  {
267  theCoTest[i] = coTest(i, stat);
268 
269  if(remainingRoundsEnter == 0)
270  {
271  if(theCoTest[i] < -pricingTol)
272  {
273  assert(infeasibilities.size() < infeasibilities.max());
274  m_pricingViol -= theCoTest[i];
277  ++ninfeasibilities;
278  }
279  else
281 
282  if(ninfeasibilities > sparsitythreshold)
283  {
284  MSG_INFO2((*spxout), (*spxout) << " --- using dense pricing"
285  << std::endl;)
287  sparsePricingEnter = false;
288  ninfeasibilities = 0;
289  }
290  }
291  else if(theCoTest[i] < -pricingTol)
292  m_pricingViol -= theCoTest[i];
293  }
294  }
295 
296  if(ninfeasibilities == 0 && !sparsePricingEnter)
298  else if(ninfeasibilities <= sparsitythreshold && !sparsePricingEnter)
299  {
300  MSG_INFO2((*spxout),
301  std::streamsize prec = spxout->precision();
302 
304  (*spxout) << " --- using hypersparse pricing, ";
305  else
306  (*spxout) << " --- using sparse pricing, ";
307  (*spxout) << "sparsity: "
308  << std::setw(6) << std::fixed << std::setprecision(4)
309  << (Real) ninfeasibilities / dim()
310  << std::scientific << std::setprecision(int(prec))
311  << std::endl;
312  )
313  sparsePricingEnter = true;
314  }
315 }
316 
317 
318 /*
319  The following methods require propersy initialized vectors |fVec| and
320  #coPvec#.
321  */
323 {
324  thePvec->delta().setup();
325 
326  const IdxSet& idx = thePvec->idx();
327  const SPxBasis::Desc& ds = desc();
328  Real pricingTol = leavetol();
329 
330  int i;
332 
333  for(i = idx.size() - 1; i >= 0; --i)
334  {
335  int j = idx.index(i);
336  SPxBasis::Desc::Status stat = ds.status(j);
337 
338  if(!isBasic(stat))
339  {
340  if(m_pricingViolCoUpToDate && theTest[j] < -pricingTol)
341  m_pricingViolCo += theTest[j];
342 
343  theTest[j] = test(j, stat);
344 
346  {
347  if(theTest[j] < -pricingTol)
348  {
349  assert(remainingRoundsEnterCo == 0);
350  m_pricingViolCo -= theTest[j];
351 
353  {
356  }
357 
360  }
361  else
362  {
364  }
365  }
366  else if(theTest[j] < -pricingTol)
367  m_pricingViolCo -= theTest[j];
368  }
369  else
370  {
372  theTest[j] = 0;
373  }
374  }
375 }
376 
378 {
379  theCoPvec->delta().setup();
380 
381  const IdxSet& idx = theCoPvec->idx();
382  const SPxBasis::Desc& ds = desc();
383  Real pricingTol = leavetol();
384 
385  int i;
386  updateViols.clear();
387 
388  for(i = idx.size() - 1; i >= 0; --i)
389  {
390  int j = idx.index(i);
391  SPxBasis::Desc::Status stat = ds.coStatus(j);
392 
393  if(!isBasic(stat))
394  {
395  if(m_pricingViolUpToDate && theCoTest[j] < -pricingTol)
396  m_pricingViol += theCoTest[j];
397 
398  theCoTest[j] = coTest(j, stat);
399 
401  {
402  if(theCoTest[j] < -pricingTol)
403  {
404  assert(remainingRoundsEnter == 0);
405  m_pricingViol -= theCoTest[j];
406 
408  {
409  // if( !hyperPricingEnter )
412  }
413 
415  updateViols.addIdx(j);
416  }
417  else
418  {
419  // @todo do we need to remove index j from infeasibilitiesCo?
421  }
422  }
423  else if(theCoTest[j] < -pricingTol)
424  m_pricingViol -= theCoTest[j];
425  }
426  else
427  {
429  theCoTest[j] = 0;
430  }
431  }
432 }
433 
434 
435 
436 /* \Section{Compute statistics on entering variable}
437  Here is a list of variables relevant when including |Id| to the basis.
438  They are computed by |computeEnterStats()|.
439  */
441 (
442  SPxId enterId,
443  Real& enterTest,
444  Real& enterUB,
445  Real& enterLB,
446  Real& enterVal,
447  Real& enterMax,
448  Real& enterPric,
449  SPxBasis::Desc::Status& enterStat,
450  Real& enterRO,
451  StableSum<Real>& objChange
452 )
453 {
454  int enterIdx;
455  SPxBasis::Desc& ds = desc();
456 
457  if(enterId.isSPxColId())
458  {
459  enterIdx = number(SPxColId(enterId));
460  enterStat = ds.colStatus(enterIdx);
461  assert(!isBasic(enterStat));
462 
463  /* For an #Id# to enter the basis we better recompute the Test value.
464  */
465  if(rep() == COLUMN)
466  {
467  computePvec(enterIdx);
468  enterTest = computeTest(enterIdx);
469  theTest[enterIdx] = 0;
470  }
471  else
472  {
473  enterTest = coTest()[enterIdx];
474  theCoTest[enterIdx] = 0;
475  }
476 
477  switch(enterStat)
478  {
479  // primal/columnwise cases:
481  assert(rep() == COLUMN);
482  enterUB = theUCbound[enterIdx];
483  enterLB = theLCbound[enterIdx];
484  enterVal = enterUB;
485  enterMax = enterLB - enterUB;
486  enterPric = (*thePvec)[enterIdx];
487  enterRO = maxObj(enterIdx);
488  objChange -= enterVal * enterRO;
489 
490  if(enterLB <= -infinity)
491  ds.colStatus(enterIdx) = SPxBasis::Desc::D_ON_LOWER;
492  else if(EQ(enterLB, enterUB))
493  ds.colStatus(enterIdx) = SPxBasis::Desc::D_FREE;
494  else
495  ds.colStatus(enterIdx) = SPxBasis::Desc::D_ON_BOTH;
496 
497  break;
498 
500  assert(rep() == COLUMN);
501  enterUB = theUCbound[enterIdx];
502  enterLB = theLCbound[enterIdx];
503  enterVal = enterLB;
504  enterMax = enterUB - enterLB;
505  enterPric = (*thePvec)[enterIdx];
506  enterRO = maxObj(enterIdx);
507  objChange -= enterVal * enterRO;
508 
509  if(enterUB >= infinity)
510  ds.colStatus(enterIdx) = SPxBasis::Desc::D_ON_UPPER;
511  else if(EQ(enterLB, enterUB))
512  ds.colStatus(enterIdx) = SPxBasis::Desc::D_FREE;
513  else
514  ds.colStatus(enterIdx) = SPxBasis::Desc::D_ON_BOTH;
515 
516  break;
517 
519  assert(rep() == COLUMN);
520  enterUB = theUCbound[enterIdx];
521  enterLB = theLCbound[enterIdx];
522  enterVal = 0;
523  enterPric = (*thePvec)[enterIdx];
524  enterRO = maxObj(enterIdx);
525  ds.colStatus(enterIdx) = SPxBasis::Desc::D_UNDEFINED;
526  enterMax = (enterRO - enterPric > 0) ? infinity : -infinity;
527  break;
528 
529  // dual/rowwise cases:
531  assert(rep() == ROW);
532  assert(theUCbound[enterIdx] < infinity);
533  enterUB = theUCbound[enterIdx];
534  enterLB = -infinity;
535  enterMax = -infinity;
536  enterVal = enterUB;
537  enterPric = (*theCoPvec)[enterIdx];
538  enterRO = SPxLP::lower(enterIdx);
539  objChange -= enterRO * enterVal;
540  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
541  break;
542 
544  assert(rep() == ROW);
545  assert(theLCbound[enterIdx] > -infinity);
546  enterLB = theLCbound[enterIdx];
547  enterUB = infinity;
548  enterMax = infinity;
549  enterVal = enterLB;
550  enterPric = (*theCoPvec)[enterIdx];
551  enterRO = SPxLP::upper(enterIdx);
552  objChange -= enterRO * enterVal;
553  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
554  break;
555 
557  assert(rep() == ROW);
558  assert(SPxLP::lower(enterIdx) == SPxLP::upper(enterIdx));
559  enterUB = infinity;
560  enterLB = -infinity;
561  enterVal = 0;
562  enterRO = SPxLP::upper(enterIdx);
563  enterPric = (*theCoPvec)[enterIdx];
564 
565  if(enterPric > enterRO)
566  enterMax = infinity;
567  else
568  enterMax = -infinity;
569 
570  ds.colStatus(enterIdx) = SPxBasis::Desc::P_FIXED;
571  break;
572 
574  assert(rep() == ROW);
575  enterPric = (*theCoPvec)[enterIdx];
576 
577  if(enterPric > SPxLP::upper(enterIdx))
578  {
579  enterLB = theLCbound[enterIdx];
580  enterUB = infinity;
581  enterMax = infinity;
582  enterVal = enterLB;
583  enterRO = SPxLP::upper(enterIdx);
584  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
585  }
586  else
587  {
588  enterUB = theUCbound[enterIdx];
589  enterVal = enterUB;
590  enterRO = SPxLP::lower(enterIdx);
591  enterLB = -infinity;
592  enterMax = -infinity;
593  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
594  }
595 
596  objChange -= theLCbound[enterIdx] * SPxLP::upper(enterIdx);
597  objChange -= theUCbound[enterIdx] * SPxLP::lower(enterIdx);
598  break;
599 
600  default:
601  throw SPxInternalCodeException("XENTER01 This should never happen.");
602  }
603 
604  MSG_DEBUG(std::cout << "DENTER03 SPxSolver::getEnterVals() : col " << enterIdx
605  << ": " << enterStat
606  << " -> " << ds.colStatus(enterIdx)
607  << " objChange: " << objChange
608  << std::endl;)
609  }
610 
611  else
612  {
613  assert(enterId.isSPxRowId());
614  enterIdx = number(SPxRowId(enterId));
615  enterStat = ds.rowStatus(enterIdx);
616  assert(!isBasic(enterStat));
617 
618  /* For an #Id# to enter the basis we better recompute the Test value.
619  */
620  if(rep() == ROW)
621  {
622  computePvec(enterIdx);
623  enterTest = computeTest(enterIdx);
624  theTest[enterIdx] = 0;
625  }
626  else
627  {
628  enterTest = coTest()[enterIdx];
629  theCoTest[enterIdx] = 0;
630  }
631 
632  switch(enterStat)
633  {
634  // primal/columnwise cases:
636  assert(rep() == COLUMN);
637  enterUB = theURbound[enterIdx];
638  enterLB = theLRbound[enterIdx];
639  enterVal = enterLB;
640  enterMax = enterUB - enterLB;
641  enterPric = (*theCoPvec)[enterIdx];
642  enterRO = maxRowObj(enterIdx);
643  objChange -= enterRO * enterVal;
644 
645  if(enterUB >= infinity)
646  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_ON_LOWER;
647  else if(EQ(enterLB, enterUB))
648  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_FREE;
649  else
650  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_ON_BOTH;
651 
652  break;
653 
655  assert(rep() == COLUMN);
656  enterUB = theURbound[enterIdx];
657  enterLB = theLRbound[enterIdx];
658  enterVal = enterUB;
659  enterMax = enterLB - enterUB;
660  enterPric = (*theCoPvec)[enterIdx];
661  enterRO = maxRowObj(enterIdx);
662  objChange -= enterRO * enterVal;
663 
664  if(enterLB <= -infinity)
665  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_ON_UPPER;
666  else if(EQ(enterLB, enterUB))
667  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_FREE;
668  else
669  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_ON_BOTH;
670 
671  break;
672 
674  assert(rep() == COLUMN);
675 #if 1
676  throw SPxInternalCodeException("XENTER02 This should never happen.");
677 #else
678  MSG_ERROR(std::cerr << "EENTER99 ERROR: not yet debugged!" << std::endl;)
679  enterPric = (*theCoPvec)[enterIdx];
680  enterRO = maxRowObj(enterIdx);
681  ds.rowStatus(enterIdx) = SPxBasis::Desc::D_UNDEFINED;
682 #endif
683  break;
684 
685  // dual/rowwise cases:
687  assert(rep() == ROW);
688  assert(theURbound[enterIdx] < infinity);
689  enterUB = theURbound[enterIdx];
690  enterLB = -infinity;
691  enterVal = enterUB;
692  enterMax = -infinity;
693  enterPric = (*thePvec)[enterIdx];
694  enterRO = lhs(enterIdx);
695  objChange -= enterRO * enterVal;
696  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
697  break;
698 
700  assert(rep() == ROW);
701  assert(theLRbound[enterIdx] > -infinity);
702  enterLB = theLRbound[enterIdx];
703  enterUB = infinity;
704  enterVal = enterLB;
705  enterMax = infinity;
706  enterPric = (*thePvec)[enterIdx];
707  enterRO = rhs(enterIdx);
708  objChange -= enterRO * enterVal;
709  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
710  break;
711 
713  assert(rep() == ROW);
714  assert(rhs(enterIdx) == lhs(enterIdx));
715  enterUB = infinity;
716  enterLB = -infinity;
717  enterVal = 0;
718  enterPric = (*thePvec)[enterIdx];
719  enterRO = rhs(enterIdx);
720  enterMax = (enterPric > enterRO) ? infinity : -infinity;
721  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_FIXED;
722  break;
723 
725  assert(rep() == ROW);
726  enterPric = (*thePvec)[enterIdx];
727 
728  if(enterPric > rhs(enterIdx))
729  {
730  enterLB = theLRbound[enterIdx];
731  enterVal = enterLB;
732  enterUB = infinity;
733  enterMax = infinity;
734  enterRO = rhs(enterIdx);
735  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
736  }
737  else
738  {
739  enterUB = theURbound[enterIdx];
740  enterVal = enterUB;
741  enterLB = -infinity;
742  enterMax = -infinity;
743  enterRO = lhs(enterIdx);
744  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
745  }
746 
747  objChange -= theLRbound[enterIdx] * rhs(enterIdx);
748  objChange -= theURbound[enterIdx] * lhs(enterIdx);
749  break;
750 
751  default:
752  throw SPxInternalCodeException("XENTER03 This should never happen.");
753  }
754 
755  MSG_DEBUG(std::cout << "DENTER05 SPxSolver::getEnterVals() : row "
756  << enterIdx << ": " << enterStat
757  << " -> " << ds.rowStatus(enterIdx)
758  << " objChange: " << objChange
759  << std::endl;)
760  }
761 }
762 
763 /* process leaving variable
764  */
766 (
767  int leaveIdx,
768  Real enterMax,
769  Real& leavebound,
770  StableSum<Real>& objChange
771 )
772 {
773  int idx;
774  SPxBasis::Desc& ds = desc();
775  SPxId leftId = baseId(leaveIdx);
776 
777  if(leftId.isSPxRowId())
778  {
779  idx = number(SPxRowId(leftId));
780  SPxBasis::Desc::Status leaveStat = ds.rowStatus(idx);
781 
782  switch(leaveStat)
783  {
785  assert(rep() == ROW);
786  throw SPxInternalCodeException("XENTER04 This should never happen.");
787  break;
788 
790  assert(rep() == ROW);
791  leavebound = theLBbound[leaveIdx];
792  theLRbound[idx] = leavebound;
793  ds.rowStatus(idx) = dualRowStatus(idx);
794 
795  switch(ds.rowStatus(idx))
796  {
798  objChange += theURbound[idx] * lhs(idx);
799  break;
800 
802  objChange += theLRbound[idx] * rhs(idx);
803  break;
804 
806  objChange += theURbound[idx] * lhs(idx);
807  objChange += theLRbound[idx] * rhs(idx);
808  break;
809 
810  default:
811  break;
812  }
813 
814  break;
815 
817  assert(rep() == ROW);
818  leavebound = theUBbound[leaveIdx];
819  theURbound[idx] = leavebound;
820  ds.rowStatus(idx) = dualRowStatus(idx);
821 
822  switch(ds.rowStatus(idx))
823  {
825  objChange += theURbound[idx] * lhs(idx);
826  break;
827 
829  objChange += theLRbound[idx] * rhs(idx);
830  break;
831 
833  objChange += theURbound[idx] * lhs(idx);
834  objChange += theLRbound[idx] * rhs(idx);
835  break;
836 
837  default:
838  break;
839  }
840 
841  break;
842 
844  assert(rep() == ROW);
845 #if 1
846  throw SPxInternalCodeException("XENTER05 This should never happen.");
847 #else
848  MSG_ERROR(std::cerr << "EENTER98 ERROR: not yet debugged!" << std::endl;)
849 
850  if((*theCoPvec)[leaveIdx] - theLBbound[leaveIdx] <
851  theUBbound[leaveIdx] - (*theCoPvec)[leaveIdx])
852  {
853  leavebound = theLBbound[leaveIdx];
854  theLRbound[idx] = leavebound;
855  }
856  else
857  {
858  leavebound = theUBbound[leaveIdx];
859  theURbound[idx] = leavebound;
860  }
861 
863 #endif
864  break;
865 
866  // primal/columnwise cases:
868  assert(rep() == COLUMN);
869  throw SPxInternalCodeException("XENTER06 This should never happen.");
870  break;
871 
873  assert(rep() == COLUMN);
874 
875  if(theFvec->delta()[leaveIdx] * enterMax < 0)
876  leavebound = theUBbound[leaveIdx];
877  else
878  leavebound = theLBbound[leaveIdx];
879 
880  theLRbound[idx] = leavebound;
881  theURbound[idx] = leavebound;
882  objChange += leavebound * maxRowObj(leaveIdx);
884  break;
885 
887  assert(rep() == COLUMN);
888  leavebound = theUBbound[leaveIdx];
889  theURbound[idx] = leavebound;
890  objChange += leavebound * maxRowObj(leaveIdx);
892  break;
893 
895  assert(rep() == COLUMN);
896  leavebound = theLBbound[leaveIdx];
897  theLRbound[idx] = leavebound;
898  objChange += leavebound * maxRowObj(leaveIdx);
900  break;
901 
903  assert(rep() == COLUMN);
904 
905  if(enterMax * theFvec->delta()[leaveIdx] < 0)
906  {
907  leavebound = theUBbound[leaveIdx];
908  theURbound[idx] = leavebound;
909  objChange += leavebound * maxRowObj(leaveIdx);
911  }
912  else
913  {
914  leavebound = theLBbound[leaveIdx];
915  theLRbound[idx] = leavebound;
916  objChange += leavebound * maxRowObj(leaveIdx);
918  }
919 
920  break;
921 
922  default:
923  throw SPxInternalCodeException("XENTER07 This should never happen.");
924  }
925 
926  MSG_DEBUG(std::cout << "DENTER06 SPxSolver::getEnterVals2(): row "
927  << idx << ": " << leaveStat
928  << " -> " << ds.rowStatus(idx)
929  << " objChange: " << objChange
930  << std::endl;)
931  }
932 
933  else
934  {
935  assert(leftId.isSPxColId());
936  idx = number(SPxColId(leftId));
937  SPxBasis::Desc::Status leaveStat = ds.colStatus(idx);
938 
939  switch(leaveStat)
940  {
942  assert(rep() == ROW);
943  leavebound = theLBbound[leaveIdx];
944  theLCbound[idx] = leavebound;
945  ds.colStatus(idx) = dualColStatus(idx);
946 
947  switch(ds.colStatus(idx))
948  {
950  objChange += theUCbound[idx] * lower(idx);
951  break;
952 
954  objChange += theLCbound[idx] * upper(idx);
955  break;
956 
958  objChange += theLCbound[idx] * upper(idx);
959  objChange += theUCbound[idx] * lower(idx);
960  break;
961 
962  default:
963  break;
964  }
965 
966  break;
967 
969  assert(rep() == ROW);
970  leavebound = theUBbound[leaveIdx];
971  theUCbound[idx] = leavebound;
972  ds.colStatus(idx) = dualColStatus(idx);
973 
974  switch(ds.colStatus(idx))
975  {
977  objChange += theUCbound[idx] * lower(idx);
978  break;
979 
981  objChange += theLCbound[idx] * upper(idx);
982  break;
983 
985  objChange += theLCbound[idx] * upper(idx);
986  objChange += theUCbound[idx] * lower(idx);
987  break;
988 
989  default:
990  break;
991  }
992 
993  break;
994 
996  assert(rep() == ROW);
997 
998  if(theFvec->delta()[leaveIdx] * enterMax > 0)
999  {
1000  leavebound = theLBbound[leaveIdx];
1001  theLCbound[idx] = leavebound;
1002  }
1003  else
1004  {
1005  leavebound = theUBbound[leaveIdx];
1006  theUCbound[idx] = leavebound;
1007  }
1008 
1010  break;
1011 
1013  assert(rep() == ROW);
1014  throw SPxInternalCodeException("XENTER08 This should never happen.");
1015  break;
1016 
1017  // primal/columnwise cases:
1018  case SPxBasis::Desc::D_FREE :
1019  assert(rep() == COLUMN);
1020 
1021  if(theFvec->delta()[leaveIdx] * enterMax > 0)
1022  leavebound = theLBbound[leaveIdx];
1023  else
1024  leavebound = theUBbound[leaveIdx];
1025 
1026  theUCbound[idx] =
1027  theLCbound[idx] = leavebound;
1028  objChange += maxObj(idx) * leavebound;
1030  break;
1031 
1033  assert(rep() == COLUMN);
1034  leavebound = theLBbound[leaveIdx];
1035  theLCbound[idx] = leavebound;
1036  objChange += maxObj(idx) * leavebound;
1038  break;
1039 
1041  assert(rep() == COLUMN);
1042  leavebound = theUBbound[leaveIdx];
1043  theUCbound[idx] = leavebound;
1044  objChange += maxObj(idx) * leavebound;
1046  break;
1047 
1050  assert(rep() == COLUMN);
1051 
1052  if(enterMax * theFvec->delta()[leaveIdx] < 0)
1053  {
1054  leavebound = theUBbound[leaveIdx];
1055  theUCbound[idx] = leavebound;
1056  objChange += maxObj(idx) * leavebound;
1058  }
1059  else
1060  {
1061  leavebound = theLBbound[leaveIdx];
1062  theLCbound[idx] = leavebound;
1063  objChange += maxObj(idx) * leavebound;
1065  }
1066 
1067  break;
1068 
1069  default:
1070  throw SPxInternalCodeException("XENTER09 This should never happen.");
1071  }
1072 
1073  MSG_DEBUG(std::cout << "DENTER07 SPxSolver::getEnterVals2(): col "
1074  << idx << ": " << leaveStat
1075  << " -> " << ds.colStatus(idx)
1076  << " objChange: " << objChange
1077  << std::endl;)
1078  }
1079 }
1080 
1081 
1082 void
1084  SPxId enterId,
1085  SPxBasis::Desc::Status enterStat,
1086  Real leaveVal,
1087  const SVector& vec,
1088  StableSum<Real>& objChange
1089 )
1090 {
1091  assert(rep() == COLUMN);
1092  int enterIdx;
1093  SPxBasis::Desc& ds = desc();
1094 
1095  if(enterId.isSPxColId())
1096  {
1097  enterIdx = number(SPxColId(enterId));
1098 
1099  if(enterStat == SPxBasis::Desc::P_ON_UPPER)
1100  {
1101  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
1102  objChange += theLCbound[enterIdx] * maxObj(enterIdx);
1103  }
1104  else
1105  {
1106  ds.colStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
1107  objChange += theUCbound[enterIdx] * maxObj(enterIdx);
1108  }
1109 
1110  theFrhs->multAdd(leaveVal, vec);
1111  }
1112  else
1113  {
1114  enterIdx = number(SPxRowId(enterId));
1115  assert(enterId.isSPxRowId());
1116 
1117  if(enterStat == SPxBasis::Desc::P_ON_UPPER)
1118  {
1119  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_LOWER;
1120  objChange += (theURbound[enterIdx]) * maxRowObj(enterIdx);
1121  }
1122  else
1123  {
1124  ds.rowStatus(enterIdx) = SPxBasis::Desc::P_ON_UPPER;
1125  objChange += (theLRbound[enterIdx]) * maxRowObj(enterIdx);
1126  }
1127 
1128  (*theFrhs)[enterIdx] += leaveVal;
1129  }
1130 
1131  if(isId(enterId))
1132  {
1133  theTest[enterIdx] = 0;
1135  }
1136  else
1137  {
1138  theCoTest[enterIdx] = 0;
1140  }
1141 }
1142 
1144  SPxId enterId,
1145  Real enterTest,
1146  SPxBasis::Desc::Status enterStat
1147 )
1148 {
1149  int enterIdx = number(enterId);
1150 
1151  if(isId(enterId))
1152  {
1153  theTest[enterIdx] = enterTest;
1154  desc().status(enterIdx) = enterStat;
1155  }
1156  else
1157  {
1158  theCoTest[enterIdx] = enterTest;
1159  desc().coStatus(enterIdx) = enterStat;
1160  }
1161 }
1162 
1163 
1165 {
1166  Real sign = (direction > 0 ? 1.0 : -1.0);
1167 
1168  primalRay.clear();
1169  primalRay.setMax(fVec().delta().size() + 1);
1170 
1171  for(int j = 0; j < fVec().delta().size(); ++j)
1172  {
1173  SPxId i = baseId(fVec().idx().index(j));
1174 
1175  if(i.isSPxColId())
1176  primalRay.add(number(SPxColId(i)), sign * fVec().delta().value(j));
1177  }
1178 
1179  if(enterId.isSPxColId())
1180  primalRay.add(number(SPxColId(enterId)), -sign);
1181 }
1182 
1183 
1185 {
1186  Real sign = (direction > 0 ? -1.0 : 1.0);
1187 
1188  dualFarkas.clear();
1189  dualFarkas.setMax(fVec().delta().size() + 1);
1190 
1191  for(int j = 0; j < fVec().delta().size(); ++j)
1192  {
1193  SPxId spxid = baseId(fVec().idx().index(j));
1194 
1195  if(spxid.isSPxRowId())
1196  dualFarkas.add(number(SPxRowId(spxid)), sign * fVec().delta().value(j));
1197  }
1198 
1199  if(enterId.isSPxRowId())
1200  dualFarkas.add(number(SPxRowId(enterId)), -sign);
1201 }
1202 
1203 
1204 bool SPxSolver::enter(SPxId& enterId, bool polish)
1205 {
1206  assert(enterId.isValid());
1207  assert(type() == ENTER);
1208  assert(initialized);
1209 
1210  SPxId none; // invalid id used when enter fails
1211  Real enterTest; // correct test value of entering var
1212  Real enterUB; // upper bound of entering variable
1213  Real enterLB; // lower bound of entering variable
1214  Real enterVal; // current value of entering variable
1215  Real enterMax; // maximum value for entering shift
1216  Real enterPric; // priced value of entering variable
1217  SPxBasis::Desc::Status enterStat; // status of entering variable
1218  Real enterRO; // rhs/obj of entering variable
1219  StableSum<Real> objChange;
1220  const SVector* enterVec = enterVector(enterId);
1221 
1222  bool instable = instableEnter;
1223  assert(!instable || instableEnterId.isValid());
1224 
1225  getEnterVals(enterId, enterTest, enterUB, enterLB,
1226  enterVal, enterMax, enterPric, enterStat, enterRO, objChange);
1227 
1228  if(!polish && enterTest > -epsilon())
1229  {
1230  rejectEnter(enterId, enterTest, enterStat);
1231  change(-1, none, 0);
1232 
1233  MSG_DEBUG(std::cout << "DENTER08 rejecting false enter pivot" << std::endl;)
1234 
1235  return false;
1236  }
1237 
1238  /* Before performing the actual basis update, we must determine, how this
1239  is to be accomplished.
1240  */
1241  // BH 2005-11-15: Obviously solve4update() is only called if theFvec.delta()
1242  // is setup (i.e. the indices of the NZEs are stored within it) and there are
1243  // 0 NZEs (???).
1244  // In that case theFvec->delta() is set such that
1245  // Base * theFvec->delta() = enterVec
1246  if(theFvec->delta().isSetup() && theFvec->delta().size() == 0)
1247  SPxBasis::solve4update(theFvec->delta(), *enterVec);
1248 
1249 #ifdef ENABLE_ADDITIONAL_CHECKS
1250  else
1251  {
1252  // BH 2005-11-29: This code block seems to check the assertion
1253  // || Base * theFvec->delta() - enterVec ||_2 <= entertol()
1254  DVector tmp(dim());
1255  // BH 2005-11-15: This cast is necessary since SSVector inherits protected from DVector.
1256  tmp = reinterpret_cast<DVector&>(theFvec->delta());
1257  multBaseWith(tmp);
1258  tmp -= *enterVec;
1259 
1260  if(tmp.length() > entertol())
1261  {
1262  // This happens frequently and does usually not hurt, so print these
1263  // warnings only with verbose level INFO2 and higher.
1264  MSG_INFO2((*spxout), (*spxout) << "WENTER09 fVec updated error = "
1265  << tmp.length() << std::endl;)
1266  }
1267  }
1268 
1269 #endif // ENABLE_ADDITIONAL_CHECKS
1270 
1271  if(!polish && m_numCycle > m_maxCycle)
1272  {
1273  if(-enterMax > 0)
1274  perturbMaxEnter();
1275  else
1276  perturbMinEnter();
1277  }
1278 
1279  Real leaveVal = -enterMax;
1280 
1281  boundflips = 0;
1282  int leaveIdx = theratiotester->selectLeave(leaveVal, enterTest, polish);
1283 
1284  /* in row representation, fixed columns and rows should not leave the basis */
1285  assert(leaveIdx < 0 || !baseId(leaveIdx).isSPxColId()
1286  || desc().colStatus(number(SPxColId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1287  assert(leaveIdx < 0 || !baseId(leaveIdx).isSPxRowId()
1288  || desc().rowStatus(number(SPxRowId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1289 
1290  instableEnterVal = 0;
1291  instableEnterId = SPxId();
1292  instableEnter = false;
1293 
1294  /*
1295  We now tried to find a variable to leave the basis. If one has been
1296  found, a regular basis update is to be performed.
1297  */
1298  if(leaveIdx >= 0)
1299  {
1300  if(spxAbs(leaveVal) < entertol())
1301  {
1302  if(NE(theUBbound[leaveIdx], theLBbound[leaveIdx])
1303  && enterStat != Desc::P_FREE && enterStat != Desc::D_FREE)
1304  {
1305  m_numCycle++;
1306  enterCycles++;
1307  }
1308  }
1309  else
1310  m_numCycle /= 2;
1311 
1312  // setup for updating the copricing vector
1314  {
1315  assert(coSolveVector2->isConsistent());
1316  assert(coSolveVector2rhs->isSetup());
1317  assert(coSolveVector3->isConsistent());
1318  assert(coSolveVector3rhs->isSetup());
1319  assert(boundflips > 0);
1321  , unitVecs[leaveIdx], *coSolveVector2rhs, *coSolveVector3rhs);
1322  (*theCoPvec) -= (*coSolveVector3);
1323  }
1324  else if(coSolveVector3)
1325  {
1326  assert(coSolveVector3->isConsistent());
1327  assert(coSolveVector3rhs->isSetup());
1328  assert(boundflips > 0);
1330  (*theCoPvec) -= (*coSolveVector3);
1331  }
1332  else if(coSolveVector2)
1334  else
1335  SPxBasis::coSolve(theCoPvec->delta(), unitVecs[leaveIdx]);
1336 
1337  if(boundflips > 0)
1338  {
1339  for(int i = coSolveVector3->dim() - 1; i >= 0; --i)
1340  {
1341  if(spxAbs((*coSolveVector3)[i]) > epsilon())
1342  (*thePvec).multAdd(-(*coSolveVector3)[i], (*thecovectors)[i]);
1343  }
1344 
1345  // we need to update enterPric in case it was changed by bound flips
1346  if(enterId.isSPxColId())
1347  enterPric = (*theCoPvec)[number(SPxColId(enterId))];
1348  else
1349  enterPric = (*thePvec)[number(SPxRowId(enterId))];
1350 
1351  MSG_DEBUG(std::cout << "IEBFRT02 breakpoints passed / bounds flipped = " << boundflips << std::endl;
1352  )
1354  }
1355 
1356  (*theCoPrhs)[leaveIdx] = enterRO;
1357  theCoPvec->value() = (enterRO - enterPric) / theFvec->delta()[leaveIdx];
1358 
1359  if(theCoPvec->value() > epsilon() || theCoPvec->value() < -epsilon())
1360  {
1361  if(pricing() == FULL)
1362  {
1363  thePvec->value() = theCoPvec->value();
1364  setupPupdate();
1365  }
1366 
1367  doPupdate();
1368  }
1369 
1370  assert(thePvec->isConsistent());
1371  assert(theCoPvec->isConsistent());
1372 
1373  assert(!baseId(leaveIdx).isSPxRowId()
1374  || desc().rowStatus(number(SPxRowId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1375  assert(!baseId(leaveIdx).isSPxColId()
1376  || desc().colStatus(number(SPxColId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1377 
1378  Real leavebound; // bound on which leaving variable moves
1379 
1380  try
1381  {
1382  getEnterVals2(leaveIdx, enterMax, leavebound, objChange);
1383  }
1384  catch(const SPxException& F)
1385  {
1386  rejectEnter(enterId, enterTest, enterStat);
1387  change(-1, none, 0);
1388  throw F;
1389  }
1390 
1391  // process entering variable
1392  theUBbound[leaveIdx] = enterUB;
1393  theLBbound[leaveIdx] = enterLB;
1394 
1395  // compute tests:
1396  updateCoTest();
1397 
1398  if(pricing() == FULL)
1399  updateTest();
1400 
1401  // update feasibility vectors
1402  theFvec->value() = leaveVal;
1403  theFvec->update();
1404  (*theFvec)[leaveIdx] = enterVal - leaveVal;
1405 
1406  if(leavebound > epsilon() || leavebound < -epsilon())
1407  theFrhs->multAdd(-leavebound, baseVec(leaveIdx));
1408 
1409  if(enterVal > epsilon() || enterVal < -epsilon())
1410  theFrhs->multAdd(enterVal, *enterVec);
1411 
1412  // update objective funtion value
1413  updateNonbasicValue(objChange);
1414 
1415  // change basis matrix
1416  change(leaveIdx, enterId, enterVec, &(theFvec->delta()));
1417 
1418  return true;
1419  }
1420  /* No leaving vector could be found that would yield a stable pivot step.
1421  */
1422  else if(NE(leaveVal, -enterMax))
1423  {
1424  /* In the ENTER algorithm, when for a selected entering variable we find only
1425  an instable leaving variable, then the basis change is not conducted.
1426  Instead, we save the entering variable's id in instableEnterId and set
1427  the test value to zero, hoping to find a different leaving
1428  variable with a stable leavingvariable.
1429  If this fails, however, and no more entering variable is found, we have to
1430  perform the instable basis change using instableEnterId. In this (and only
1431  in this) case, the flag instableEnter is set to true.
1432 
1433  leaveVal != enterMax is the case that selectLeave has found only an instable leaving
1434  variable. We store this leaving variable for later if we are not already in the
1435  instable case */
1436 
1437  if(!instable)
1438  {
1439  instableEnterId = enterId;
1440  instableEnterVal = enterTest;
1441 
1442  MSG_DEBUG(std::cout << "DENTER09 rejecting enter pivot and looking for others" << std::endl;)
1443 
1444  rejectEnter(enterId, enterTest / 10.0, enterStat);
1445  change(-1, none, 0);
1446  }
1447  else
1448  {
1449  MSG_DEBUG(std::cout << "DENTER10 rejecting enter pivot in instable state, resetting values" <<
1450  std::endl;)
1451  rejectEnter(enterId, enterTest, enterStat);
1452  change(-1, none, 0);
1453  }
1454 
1455  return false;
1456  }
1457  /* No leaving vector has been selected from the basis. However, if the
1458  shift amount for |fVec| is bounded, we are in the case, that the
1459  entering variable is moved from one bound to its other, before any of
1460  the basis feasibility variables reaches their bound. This may only
1461  happen in primal/columnwise case with upper and lower bounds on
1462  variables.
1463  */
1464  else if(!polish && leaveVal < infinity && leaveVal > -infinity)
1465  {
1466  assert(rep() == COLUMN);
1467  assert(leaveVal == -enterMax);
1468 
1469  change(-1, enterId, enterVec);
1470 
1471  theFvec->value() = leaveVal;
1472  theFvec->update();
1473 
1474  ungetEnterVal(enterId, enterStat, leaveVal, *enterVec, objChange);
1475 
1476  // update objective funtion value
1477  updateNonbasicValue(objChange);
1478 
1479  MSG_DEBUG(std::cout << "DENTER11 moving entering variable from one bound to the other" << std::endl;
1480  )
1481 
1482  return false;
1483  }
1484  /* No variable could be selected to leave the basis and even the entering
1485  variable is unbounded --- this is a failure.
1486  */
1487  else
1488  {
1489  /* The following line originally was in the "lastUpdate() > 1" case;
1490  we need it in the INFEASIBLE/UNBOUNDED case, too, to have the
1491  basis descriptor at the correct size.
1492  */
1493  rejectEnter(enterId, enterTest, enterStat);
1494  change(-1, none, 0);
1495 
1496  if(polish)
1497  return false;
1498 
1499  else if(lastUpdate() > 1)
1500  {
1501  MSG_INFO3((*spxout), (*spxout) << "IENTER01 factorization triggered in "
1502  << "enter() for feasibility test" << std::endl;)
1503 
1504  try
1505  {
1506  factorize();
1507  }
1508  catch(const SPxStatusException& E)
1509  {
1510  // don't exit immediately but handle the singularity correctly
1511  assert(SPxBasis::status() == SPxBasis::SINGULAR);
1512  MSG_INFO3((*spxout), (*spxout) << "Caught exception in factorization: " << E.what() << std::endl;)
1513  }
1514 
1515  /* after a factorization, the entering column/row might not be infeasible or suboptimal anymore, hence we do
1516  * not try to call leave(leaveIdx), but rather return to the main solving loop and call the pricer again
1517  */
1518  return false;
1519  }
1520 
1521  /* do not exit with status infeasible or unbounded if there is only a very small violation
1522  * ROW: recompute the primal variables and activities for another, more precise, round of pricing
1523  */
1524  else if(!recomputedVectors && spxAbs(enterTest) < entertol())
1525  {
1526  MSG_INFO3((*spxout), (*spxout) << "IENTER11 clean up step to reduce numerical errors" << std::endl;)
1527 
1529  computePvec();
1530  computeCoTest();
1531  computeTest();
1532 
1533  /* only do this once per solve */
1534  recomputedVectors = true;
1535 
1536  return false;
1537  }
1538 
1539  MSG_INFO3((*spxout), (*spxout) << "IENTER02 unboundedness/infeasibility found in "
1540  << "enter()" << std::endl;)
1541 
1542  if(rep() == ROW)
1543  {
1544  computeDualfarkas4Row(leaveVal, enterId);
1546  }
1547  /**@todo if shift() is not zero, we must not conclude primal unboundedness */
1548  else
1549  {
1550  computePrimalray4Col(leaveVal, enterId);
1552  }
1553 
1554  return false;
1555  }
1556 }
1557 } // 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
virtual void ungetEnterVal(SPxId enterId, SPxBasis::Desc::Status enterStat, Real leaveVal, const SVector &vec, StableSum< Real > &objChange)
Definition: enter.cpp:1083
bool enter(SPxId &id, bool polish=false)
Definition: enter.cpp:1204
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
Status & coStatus(int i)
Definition: spxbasis.h:284
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:121
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:730
primal variable is fixed to both bounds
Definition: spxbasis.h:190
int boundflips
number of performed bound flips
Definition: spxsolver.h:392
primal or dual variable is undefined
Definition: spxbasis.h:195
const VectorBase< Real > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:461
Desc::Status dualColStatus(int i) const
dual Status for the i&#39;th column variable of the loaded LP.
Definition: spxbasis.cpp:69
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:435
SPxOut * spxout
message handler
Definition: spxsolver.h:463
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
int max() const
returns the maximal number of indices which can be stored in IdxSet.
Definition: idxset.h:129
Pricing pricing() const
return current Pricing.
Definition: spxsolver.h:518
virtual void rejectEnter(SPxId enterId, Real enterTest, SPxBasis::Desc::Status enterStat)
Definition: enter.cpp:1143
DVector theCoTest
Definition: spxsolver.h:381
Abstract pricer base class.
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:796
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:108
Exception classes for SoPlex.
Status & rowStatus(int i)
Definition: spxbasis.h:239
virtual void getEnterVals2(int leaveIdx, Real enterMax, Real &leaveBound, StableSum< Real > &objChange)
Definition: enter.cpp:766
bool sparsePricingEnterCo
true if sparsePricing is turned on in the entering Simplex
Definition: spxsolver.h:450
Abstract ratio test base class.
void computePrimalray4Col(Real direction, SPxId enterId)
Definition: enter.cpp:1164
int m_maxCycle
maximum steps before cycling is detected.
Definition: spxsolver.h:270
DataArray< int > isInfeasible
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:443
bool NE(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| > eps
Definition: spxdefines.h:382
Real length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: vectorbase.h:399
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:527
void clear()
removes all indices.
Definition: idxset.h:184
bool isId(const SPxId &p_id) const
Is p_id an SPxId ?
Definition: spxsolver.h:1135
virtual void perturbMinEnter(void)
Definition: spxshift.cpp:312
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:540
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1075
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:1023
Real sparsePricingFactor
enable sparse pricing when viols < factor * dim()
Definition: spxsolver.h:314
Ids for LP columns.Class SPxColId provides DataKeys for the column indices of an SPxLP.
Definition: spxid.h:36
virtual void perturbMaxEnter(void)
perturb basis bounds.
Definition: spxshift.cpp:321
int sign(const Rational &r)
Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
Definition: rational.cpp:4115
virtual void doPupdate(void)
Definition: spxvecs.cpp:554
virtual Real value()
current objective value.
Definition: spxsolver.cpp:939
rowwise representation.
Definition: spxsolver.h:107
Basis is singular.
Definition: spxbasis.h:93
Desc::Status dualRowStatus(int i) const
dual Status for the i&#39;th row variable of the loaded LP.
Definition: spxbasis.cpp:46
virtual const std::string what() const
returns exception message
Definition: exceptions.h:57
dual variable is left free, but unset
Definition: spxbasis.h:191
Wrapper for different output streams and verbosity levels.
void add(const SVectorBase< S > &vec)
Append nonzeros of sv.
Definition: dsvectorbase.h:218
int dim() const
Dimension of VectorBase.
Definition: ssvectorbase.h:563
Entering Simplex.
Definition: spxsolver.h:134
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:271
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
const SVector & baseVec(int i) const
returns the i&#39;th basic vector.
Definition: spxbasis.h:515
bool m_pricingViolCoUpToDate
true, if the stored violation in coDim is up to date
Definition: spxsolver.h:264
virtual void getEnterVals(SPxId id, Real &enterTest, Real &enterUB, Real &enterLB, Real &enterVal, Real &enterMax, Real &enterPric, SPxBasis::Desc::Status &enterStat, Real &enterRO, StableSum< Real > &objChange)
Definition: enter.cpp:441
double Real
Definition: spxdefines.h:218
SSVector * coSolveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:287
DVector * theFrhs
Definition: spxsolver.h:360
#define MSG_DEBUG(x)
Definition: spxdefines.h:132
virtual const SVector * enterVector(const SPxId &p_id)
Get pointer to the id &#39;th vector.
Definition: spxsolver.h:1896
Real m_pricingViol
maximal feasibility violation of current solution
Definition: spxsolver.h:260
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:789
UpdateVector * thePvec
Definition: spxsolver.h:368
void update()
Perform the update.
Definition: updatevector.h:147
int size() const
returns the number of used indices.
Definition: idxset.h:124
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:120
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:114
const SVSet * thecovectors
the LP coVectors according to representation
Definition: spxsolver.h:338
int size() const
Returns number of elements.
Definition: classarray.h:208
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
dual variable is set to its upper bound
Definition: spxbasis.h:192
DVector theLBbound
Lower Basic Feasibility bound.
Definition: spxsolver.h:357
virtual void setupPupdate(void)
Definition: spxvecs.cpp:534
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:79
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1263
Real delta() const
guaranteed primal and dual bound violation for optimal solution, returning the maximum of feastol() a...
Definition: spxsolver.h:819
primal variable is left free, but unset
Definition: spxbasis.h:189
const VectorBase< R > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:255
SSVector * coSolveVector3rhs
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:289
bool updateNonbasicValue(Real objChange)
Definition: spxsolver.cpp:962
void updateTest()
recompute test vector.
Definition: enter.cpp:322
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:346
bool isConsistent() const
consistency check.
Definition: ssvectorbase.h:620
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:449
int remainingRoundsEnterCo
Definition: spxsolver.h:456
const VectorBase< R > & maxRowObj() const
Definition: spxlpbase.h:300
const Vector & test() const
Violations of pVec.
Definition: spxsolver.h:1531
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:504
DVector theUBbound
Upper Basic Feasibility bound.
Definition: spxsolver.h:356
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:122
virtual void change(int i, SPxId &id, const SVector *enterVec, const SSVector *eta=0)
performs basis update.
Definition: spxbasis.cpp:773
Real m_pricingViolCo
maximal feasibility violation of current solution in coDim
Definition: spxsolver.h:263
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:784
Debugging, floating point type and parameter definitions.
int totalboundflips
total number of bound flips
Definition: spxsolver.h:393
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
Definition: spxdefines.h:376
Full pricing.
Definition: spxsolver.h:160
DIdxSet infeasibilities
Definition: spxsolver.h:429
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:347
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:348
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:412
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:200
int remainingRoundsEnter
Definition: spxsolver.h:455
Everything should be within this namespace.
const IdxSet & idx() const
nonzero indices of update vector
Definition: updatevector.h:133
void clear()
Remove all indices.
Definition: svectorbase.h:431
UpdateVector * theFvec
Definition: spxsolver.h:362
void solve4update(SSVector &x, const SVector &rhs)
solves linear system with basis matrix.
Definition: spxbasis.h:669
SSVector * coSolveVector2rhs
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:285
void updateCoTest()
recompute coTest vector.
Definition: enter.cpp:377
primal variable is set to its lower bound
Definition: spxbasis.h:187
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:434
std::streamsize precision() const
Definition: spxout.h:139
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
Real & value()
update multiplicator , writeable
Definition: updatevector.h:111
const Vector & coTest() const
violations of coPvec.
Definition: spxsolver.h:1465
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:161
SPxRatioTester * theratiotester
Definition: spxsolver.h:403
DVector * theCoPrhs
Definition: spxsolver.h:365
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:151
#define DENSEROUNDS
Definition: spxsolver.h:41
dual variable is set to its lower bound
Definition: spxbasis.h:193
int enterCycles
the number of degenerate steps during the entering algorithm
Definition: spxsolver.h:395
DSVector primalRay
stores primal ray in case of unboundedness
Definition: spxsolver.h:384
Type type() const
return current Type.
Definition: spxsolver.h:512
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:445
int coDim() const
codimension.
Definition: spxsolver.h:1080
virtual int selectLeave(Real &val, Real enterTest, bool polish=false)=0
selects index to leave the basis.
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:452
bool isConsistent() const
DSVector dualFarkas
stores dual farkas proof in case of infeasibility
Definition: spxsolver.h:385
Array< UnitVector > unitVecs
array of unit vectors
Definition: spxsolver.h:336
dual variable has two bounds
Definition: spxbasis.h:194
bool recomputedVectors
flag to perform clean up step to reduce numerical errors only once
Definition: spxsolver.h:310
Exception class for status exceptions during the computationsThis class is derived from the SoPlex ex...
Definition: exceptions.h:89
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
bool initialized
true, if all vectors are setup.
Definition: spxsolver.h:272
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1157
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
DIdxSet updateViolsCo
Definition: spxsolver.h:436
bool m_pricingViolUpToDate
true, if the stored violation is up to date
Definition: spxsolver.h:261
int index(int n) const
access n &#39;th index.
Definition: idxset.h:118
Status & status(int i)
Definition: spxbasis.h:269
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:526
UpdateVector * theCoPvec
Definition: spxsolver.h:366
void computeDualfarkas4Row(Real direction, SPxId enterId)
Definition: enter.cpp:1184
Status
Status of a variable.
Definition: spxbasis.h:185
SSVector * coSolveVector2
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:283
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:432
const VectorBase< Real > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:488
const Desc & desc() const
Definition: spxbasis.h:464
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:506
Set of indices.Class IdxSet provides a set of indices. At construction it must be given an array of i...
Definition: idxset.h:56
columnwise representation.
Definition: spxsolver.h:108
virtual void factorize()
Factorize basis matrix.
Definition: spxsolver.cpp:557
void setBasisStatus(SPxBasis::SPxStatus stat)
set the lp solver&#39;s basis status.
Definition: spxsolver.h:2051
void setMax(int newmax=1)
Reset nonzero memory to >= newmax.
Definition: dsvectorbase.h:250
LP has been proven to be primal infeasible.
Definition: spxbasis.h:99
void computeCoTest()
compute coTest vector.
Definition: enter.cpp:243