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