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-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /* \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)
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 (enterTest > -epsilon())
1116  {
1117  rejectEnter(enterId, enterTest, enterStat);
1118  change(-1, none, 0);
1119  objChange = 0.0; // the nonbasicValue is not supposed to be updated in this case
1120 
1121  MSG_DEBUG( std::cout << "DENTER08 rejecting false enter pivot" << std::endl; )
1122 
1123  return true;
1124  }
1125 
1126  /* Before performing the actual basis update, we must determine, how this
1127  is to be accomplished.
1128  */
1129  // BH 2005-11-15: Obviously solve4update() is only called if theFvec.delta()
1130  // is setup (i.e. the indices of the NZEs are stored within it) and there are
1131  // 0 NZEs (???).
1132  // In that case theFvec->delta() is set such that
1133  // Base * theFvec->delta() = enterVec
1134  if (theFvec->delta().isSetup() && theFvec->delta().size() == 0)
1135  SPxBasis::solve4update(theFvec->delta(), *enterVec);
1136 #ifdef ENABLE_ADDITIONAL_CHECKS
1137  else
1138  {
1139  // BH 2005-11-29: This code block seems to check the assertion
1140  // || Base * theFvec->delta() - enterVec ||_2 <= entertol()
1141  DVector tmp(dim());
1142  // BH 2005-11-15: This cast is necessary since SSVector inherits protected from DVector.
1143  tmp = reinterpret_cast<DVector&>(theFvec->delta());
1144  multBaseWith(tmp);
1145  tmp -= *enterVec;
1146  if (tmp.length() > entertol()) {
1147  // This happens frequently and does usually not hurt, so print these
1148  // warnings only with verbose level INFO2 and higher.
1149  MSG_INFO2( (*spxout), (*spxout) << "WENTER09 fVec updated error = "
1150  << tmp.length() << std::endl; )
1151  }
1152  }
1153 #endif // ENABLE_ADDITIONAL_CHECKS
1154 
1155  if (m_numCycle > m_maxCycle)
1156  {
1157  if (-enterMax > 0)
1158  perturbMaxEnter();
1159  else
1160  perturbMinEnter();
1161  }
1162 
1163  Real leaveVal = -enterMax;
1164 
1165  boundflips = 0;
1166  int leaveIdx = theratiotester->selectLeave(leaveVal, enterTest);
1167 
1168  /* in row representation, fixed columns and rows should not leave the basis */
1169  assert(leaveIdx < 0 || !baseId(leaveIdx).isSPxColId() || desc().colStatus(number(SPxColId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1170  assert(leaveIdx < 0 || !baseId(leaveIdx).isSPxRowId() || desc().rowStatus(number(SPxRowId(baseId(leaveIdx)))) != SPxBasis::Desc::P_FIXED);
1171 
1172  instableEnterVal = 0;
1173  instableEnterId = SPxId();
1174  instableEnter = false;
1175 
1176  /*
1177  We now tried to find a variable to leave the basis. If one has been
1178  found, a regular basis update is to be performed.
1179  */
1180  if (leaveIdx >= 0)
1181  {
1182  if (spxAbs(leaveVal) < entertol())
1183  {
1184  if (NE(theUBbound[leaveIdx], theLBbound[leaveIdx])
1185  && enterStat != Desc::P_FREE && enterStat != Desc::D_FREE)
1186  m_numCycle++;
1187  }
1188  else
1189  m_numCycle /= 2;
1190 
1191  // setup for updating the copricing vector
1193  {
1194  assert(coSolveVector2->isConsistent());
1195  assert(coSolveVector2rhs->isSetup());
1196  assert(coSolveVector3->isConsistent());
1197  assert(coSolveVector3rhs->isSetup());
1198  assert(boundflips > 0);
1200  , unitVecs[leaveIdx], *coSolveVector2rhs, *coSolveVector3rhs);
1201  (*theCoPvec) -= (*coSolveVector3);
1202  }
1203  else if (coSolveVector3)
1204  {
1205  assert(coSolveVector3->isConsistent());
1206  assert(coSolveVector3rhs->isSetup());
1207  assert(boundflips > 0);
1209  (*theCoPvec) -= (*coSolveVector3);
1210  }
1211  else if (coSolveVector2)
1213  else
1214  SPxBasis::coSolve(theCoPvec->delta(), unitVecs[leaveIdx]);
1215 
1216  if( boundflips > 0 )
1217  {
1218  for( int i = coSolveVector3->dim()-1; i >= 0; --i)
1219  {
1220  if( spxAbs((*coSolveVector3)[i]) > epsilon() )
1221  (*thePvec).multAdd(-(*coSolveVector3)[i],(*thecovectors)[i]);
1222  }
1223  // we need to update enterPric in case it was changed by bound flips
1224  if( enterId.isSPxColId() )
1225  enterPric = (*theCoPvec)[number(SPxColId(enterId))];
1226  else
1227  enterPric = (*thePvec)[number(SPxRowId(enterId))];
1228  MSG_INFO3( (*spxout), (*spxout) << "IEBFRT02 "
1229  << "breakpoints passed / bounds flipped = " << boundflips
1230  << 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  /* No leaving vector could be found that would yield a stable pivot step.
1291  */
1292  else if (NE(leaveVal, -enterMax))
1293  {
1294  /* In the ENTER algorithm, when for a selected entering variable we find only
1295  an instable leaving variable, then the basis change is not conducted.
1296  Instead, we save the entering variable's id in instableEnterId and set
1297  the test value to zero, hoping to find a different leaving
1298  variable with a stable leavingvariable.
1299  If this fails, however, and no more entering variable is found, we have to
1300  perform the instable basis change using instableEnterId. In this (and only
1301  in this) case, the flag instableEnter is set to true.
1302 
1303  leaveVal != enterMax is the case that selectLeave has found only an instable leaving
1304  variable. We store this leaving variable for later if we are not already in the
1305  instable case */
1306 
1307  objChange = 0.0; // the nonbasicValue is not supposed to be updated in this 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 
1320  return true;
1321  }
1322  else
1323  {
1324  MSG_DEBUG( std::cout << "DENTER10 rejecting enter pivot in instable state, resetting values" << std::endl; )
1325  rejectEnter(enterId, enterTest, enterStat);
1326  change(-1, none, 0);
1327  }
1328  }
1329  /* No leaving vector has been selected from the basis. However, if the
1330  shift amount for |fVec| is bounded, we are in the case, that the
1331  entering variable is moved from one bound to its other, before any of
1332  the basis feasibility variables reaches their bound. This may only
1333  happen in primal/columnwise case with upper and lower bounds on
1334  variables.
1335  */
1336  else if (leaveVal < infinity && leaveVal > -infinity)
1337  {
1338  assert(rep() == COLUMN);
1339  assert(leaveVal == -enterMax);
1340 
1341  change(-1, enterId, enterVec);
1342 
1343  theFvec->value() = leaveVal;
1344  theFvec->update();
1345 
1346  ungetEnterVal(enterId, enterStat, leaveVal, *enterVec, objChange);
1347 
1348  // update objective funtion value
1349  updateNonbasicValue(objChange);
1350 
1351  MSG_DEBUG( std::cout << "DENTER11 moving entering variable from one bound to the other" << std::endl; )
1352  }
1353  /* No variable could be selected to leave the basis and even the entering
1354  variable is unbounded --- this is a failure.
1355  */
1356  else
1357  {
1358  /* The following line originally was in the "lastUpdate() > 1" case;
1359  we need it in the INFEASIBLE/UNBOUNDED case, too, to have the
1360  basis descriptor at the correct size.
1361  */
1362  rejectEnter(enterId, enterTest, enterStat);
1363  change(-1, none, 0);
1364 
1365  objChange = 0.0; // the nonbasicValue is not supposed to be updated in this case
1366 
1367  if (lastUpdate() > 1)
1368  {
1369  MSG_INFO3( (*spxout), (*spxout) << "IENTER01 factorization triggered in "
1370  << "enter() for feasibility test" << std::endl; )
1371  factorize();
1372 
1373  /* after a factorization, the entering column/row might not be infeasible or suboptimal anymore, hence we do
1374  * not try to call leave(leaveIdx), but rather return to the main solving loop and call the pricer again
1375  */
1376  return true;
1377  }
1378 
1379  /* do not exit with status infeasible or unbounded if there is only a very small violation
1380  * ROW: recompute the primal variables and activities for another, more precise, round of pricing
1381  */
1382  else if (spxAbs(enterTest) < entertol())
1383  {
1384  MSG_INFO3( (*spxout), (*spxout) << "IENTER11 clean up step to reduce numerical errors" << std::endl; )
1385 
1387  computePvec();
1388  computeCoTest();
1389  computeTest();
1390 
1391  return true;
1392  }
1393 
1394  MSG_INFO3( (*spxout), (*spxout) << "IENTER02 unboundedness/infeasibility found in "
1395  << "enter()" << std::endl; )
1396 
1397  if (rep() == ROW)
1398  {
1399  computeDualfarkas4Row(leaveVal, enterId);
1401  }
1402  /**@todo if shift() is not zero, we must not conclude primal unboundedness */
1403  else
1404  {
1405  computePrimalray4Col(leaveVal, enterId);
1407  }
1408  return false;
1409  }
1410  return true;
1411 }
1412 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3925
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:936
int coDim() const
codimension.
Definition: spxsolver.h:941
bool isSPxRowId() const
is id a row id?
Definition: spxid.h:160
Desc::Status dualRowStatus(int i) const
dual Status for the i&#39;th row variable of the loaded LP.
Definition: spxbasis.cpp:46
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
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:406
const IdxSet & idx() const
nonzero indices of update vector
Definition: updatevector.h:133
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:678
primal variable is fixed to both bounds
Definition: spxbasis.h:190
const VectorBase< Real > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:384
int boundflips
number of performed bound flips
Definition: spxsolver.h:337
primal or dual variable has no status
Definition: spxbasis.h:195
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:363
SPxOut * spxout
message handler
Definition: spxsolver.h:384
bool enter(SPxId &id)
Definition: enter.cpp:1091
virtual void rejectEnter(SPxId enterId, Real enterTest, SPxBasis::Desc::Status enterStat)
Definition: enter.cpp:1033
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:150
DVector theCoTest
Definition: spxsolver.h:327
Abstract pricer base class.
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:102
bool isSPxColId() const
is id a column id?
Definition: spxid.h:165
int size() const
Returns number of elements.
Definition: classarray.h:208
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:376
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:450
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:244
DataArray< int > isInfeasible
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:370
bool NE(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| > eps
Definition: spxdefines.h:377
void clear()
removes all indices.
Definition: idxset.h:184
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1184
const VectorBase< Real > & lower() const
Returns lower bound vector.
Definition: spxlpbase.h:420
virtual void perturbMinEnter(void)
Definition: spxshift.cpp:292
Real sparsePricingFactor
enable sparse pricing when viols < factor * dim()
Definition: spxsolver.h:277
bool isConsistent() const
consistency check.
Definition: ssvectorbase.h:589
Pricing pricing() const
return current Pricing.
Definition: spxsolver.h:418
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:301
int sign(const Rational &r)
Sign function; returns 1 if r > 0, 0 if r = 0, and -1 if r < 0.
Definition: rational.cpp:3938
virtual void doPupdate(void)
Definition: spxvecs.cpp:526
const VectorBase< Real > & upper() const
Returns upper bound vector.
Definition: spxlpbase.h:402
virtual Real value()
current objective value.
Definition: spxsolver.cpp:863
rowwise representation.
Definition: spxsolver.h:107
Real delta() const
guaranteed primal and dual bound violation for optimal solution, returning the maximum of feastol() a...
Definition: spxsolver.h:705
bool isId(const SPxId &p_id) const
Is p_id an SPxId ?
Definition: spxsolver.h:996
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 index(int n) const
access n &#39;th index.
Definition: idxset.h:118
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:245
bool m_pricingViolCoUpToDate
true, if the stored violation in coDim is up to date
Definition: spxsolver.h:238
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
Definition: spxdefines.h:115
SSVector * coSolveVector3
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:254
DVector * theFrhs
Definition: spxsolver.h:309
#define MSG_DEBUG(x)
Definition: spxdefines.h:127
const Vector & test() const
Violations of pVec.
Definition: spxsolver.h:1392
virtual const SVector * enterVector(const SPxId &p_id)
Get pointer to the id &#39;th vector.
Definition: spxsolver.h:1751
Real m_pricingViol
maximal feasibility violation of current solution
Definition: spxsolver.h:235
Desc::Status dualColStatus(int i) const
dual Status for the i&#39;th column variable of the loaded LP.
Definition: spxbasis.cpp:69
UpdateVector * thePvec
Definition: spxsolver.h:314
void update()
Perform the update.
Definition: updatevector.h:147
const SVSet * thecovectors
the LP coVectors according to representation
Definition: spxsolver.h:288
int size() const
returns the number of used indices.
Definition: idxset.h:124
SPxId instableEnterId
Definition: spxsolver.h:271
dual variable is set to its upper bound
Definition: spxbasis.h:192
DVector theLBbound
Lower Basic Feasibility bound.
Definition: spxsolver.h:307
virtual void setupPupdate(void)
Definition: spxvecs.cpp:506
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
primal variable is left free, but unset
Definition: spxbasis.h:189
int max() const
returns the maximal number of indices which can be stored in IdxSet.
Definition: idxset.h:129
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:109
SSVector * coSolveVector3rhs
when 3 systems are to be solved at a time; typically reserved for bound flipping ratio test (basic so...
Definition: spxsolver.h:255
bool updateNonbasicValue(Real objChange)
Definition: spxsolver.cpp:886
void updateTest()
recompute test vector.
Definition: enter.cpp:301
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:296
virtual void ungetEnterVal(SPxId enterId, SPxBasis::Desc::Status enterStat, Real leaveVal, const SVector &vec, Real &objChange)
Definition: enter.cpp:978
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:375
Type type() const
return current Type.
Definition: spxsolver.h:412
int remainingRoundsEnterCo
Definition: spxsolver.h:382
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:675
Status & colStatus(int i)
Definition: spxbasis.h:254
SPxId & baseId(int i)
Definition: spxbasis.h:497
DVector theUBbound
Upper Basic Feasibility bound.
Definition: spxsolver.h:306
const Vector & coTest() const
violations of coPvec.
Definition: spxsolver.h:1326
virtual void change(int i, SPxId &id, const SVector *enterVec, const SSVector *eta=0)
performs basis update.
Definition: spxbasis.cpp:715
Real m_pricingViolCo
maximal feasibility violation of current solution in coDim
Definition: spxsolver.h:237
Real length() const
Floating point approximation of euclidian norm (without any approximation guarantee).
Definition: vectorbase.h:356
Debugging, floating point type and parameter definitions.
bool isSetup() const
Returns setup status.
Definition: ssvectorbase.h:120
int totalboundflips
total number of bound flips
Definition: spxsolver.h:338
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
Definition: spxdefines.h:371
Full pricing.
Definition: spxsolver.h:160
DIdxSet infeasibilities
Definition: spxsolver.h:357
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:297
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:298
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:369
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
Definition: exceptions.h:32
int remainingRoundsEnter
Definition: spxsolver.h:381
const VectorBase< Real > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:242
Everything should be within this namespace.
void clear()
Remove all indices.
Definition: svectorbase.h:396
UpdateVector * theFvec
Definition: spxsolver.h:310
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:533
void solve4update(SSVector &x, const SVector &rhs)
solves linear system with basis matrix.
Definition: spxbasis.h:628
SSVector * coSolveVector2rhs
when 2 systems are to be solved at a time; typically for speepest edge weights
Definition: spxsolver.h:253
void updateCoTest()
recompute coTest vector.
Definition: enter.cpp:352
primal variable is set to its lower bound
Definition: spxbasis.h:187
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1018
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:299
Real & value()
update multiplicator , writeable
Definition: updatevector.h:111
Vector & multBaseWith(Vector &x) const
Basis-vector product.
Definition: spxbasis.cpp:931
std::streamsize precision() const
Definition: spxout.h:138
SPxRatioTester * theratiotester
Definition: spxsolver.h:341
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:670
DVector * theCoPrhs
Definition: spxsolver.h:312
#define DENSEROUNDS
Definition: spxsolver.h:40
dual variable is set to its lower bound
Definition: spxbasis.h:193
DSVector primalRay
stores primal ray in case of unboundedness
Definition: spxsolver.h:330
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:371
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
const Real infinity
Definition: spxdefines.cpp:26
int dim() const
Dimension of VectorBase.
Definition: ssvectorbase.h:532
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:378
const SVector & baseVec(int i) const
returns the i&#39;th basic vector.
Definition: spxbasis.h:508
const VectorBase< Real > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:224
bool isBasic(SPxBasis::Desc::Status stat) const
does stat describe a basic index ?
Definition: spxsolver.h:1124
DSVector dualFarkas
stores dual farkas proof in case of infeasibility
Definition: spxsolver.h:331
Array< UnitVector > unitVecs
array of unit vectors
Definition: spxsolver.h:286
dual variable has two bounds
Definition: spxbasis.h:194
Ids for LP rows.Class SPxRowId provides DataKeys for the row indices of an SPxLP. ...
Definition: spxid.h:55
bool initialized
true, if all vectors are setup.
Definition: spxsolver.h:246
const Desc & desc() const
Definition: spxbasis.h:457
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
DIdxSet updateViolsCo
Definition: spxsolver.h:364
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:117
bool m_pricingViolUpToDate
true, if the stored violation is up to date
Definition: spxsolver.h:236
Status & status(int i)
Definition: spxbasis.h:269
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:498
UpdateVector * theCoPvec
Definition: spxsolver.h:313
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:252
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:360
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:682
bool isConsistent() const
Set of indices.Class IdxSet provides a set of indices. At construction it must be given an array of i...
Definition: idxset.h:56
virtual int selectLeave(Real &val, Real enterTest)=0
selects index to leave the basis.
columnwise representation.
Definition: spxsolver.h:108
const VectorBase< Real > & maxRowObj() const
Definition: spxlpbase.h:286
int size() const
Returns the number of nonzeros.
Definition: ssvectorbase.h:199
virtual void factorize()
Factorize basis matrix.
Definition: spxsolver.cpp:525
void setBasisStatus(SPxBasis::SPxStatus stat)
set the lp solver&#39;s basis status.
Definition: spxsolver.h:1905
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