Scippy

SoPlex

Sequential object-oriented simPlex

changesoplex.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 #include <assert.h>
17 #include <iostream>
18 
19 #include "spxdefines.h"
20 #include "spxsolver.h"
21 #include "spxpricer.h"
22 #include "spxratiotester.h"
23 #include "exceptions.h"
24 
25 namespace soplex
26 {
27 
28 #if 0
29 void SPxSolver::localAddRows(int start)
30 {
31  assert( start <= SPxLP::nRows() );
32 
33  /**@todo This method seems to be called, to update
34  * theFvec, theFrhs, ..., but a resolve after
35  * adding a row results in a failure.
36  * To fix this, we call unInit() so that init() is called before solving
37  * in spxsolve.cpp:solve(). In init(), the
38  * vectors are set up, so there is no need
39  * to update them here.
40  */
41  if( start == SPxLP::nRows() )
42  return;
43 
44  const SPxBasis::Desc& ds = desc();
45 
46  if (type() == ENTER)
47  {
48  if (rep() == COLUMN)
49  {
50  int i;
51  for (i = start; i < SPxLP::nRows(); ++i)
52  {
53  theURbound[i] = -lhs(i);
54  theLRbound[i] = -rhs(i);
55  setEnterBound4Row(i, i);
57  // init #theFrhs[i]#:
58  Real& v_rhs = (*theFrhs)[i];
59  const SVector& row = rowVector(i);
60  v_rhs = 0;
61  for (int j = row.size() - 1; j >= 0; --j)
62  {
63  int idx = row.index(j);
64  switch (ds.colStatus(idx))
65  {
66  case Desc::P_ON_UPPER:
67  v_rhs += row.value(j) * theUCbound[idx];
68  break;
69  case Desc::P_ON_LOWER:
70  case Desc::P_FIXED:
71  v_rhs += row.value(j) * theLCbound[idx];
72  break;
73  default:
74  break;
75  }
76  }
77  }
80  for (i = start; i < SPxLP::nRows(); ++i)
81  {
82  /* we need to compare with tolerance (rep() == COLUMN) ? feastol() : opttol() because theFvec is the primal
83  * vector in COLUMN and the dual vector in ROW representation; this is equivalent to entertol(); this also
84  * fits because we are within the "type() == ENTER" case
85  */
86  if (theUBbound[i] + entertol() < (*theFvec)[i])
87  shiftUBbound(i, (*theFvec)[i]);
88  else if ((*theFvec)[i] < theLBbound[i] - entertol())
89  shiftLBbound(i, (*theFvec)[i]);
90  }
91  computePvec();
92  computeCoTest();
93  computeTest();
94  }
95  else
96  {
97  assert(rep() == ROW);
98  for (int i = start; i < SPxLP::nRows(); ++i)
99  {
100  theURbound[i] = theLRbound[i] = maxRowObj(i);
102  theURbound[i], theLRbound[i]);
103  (*thePvec)[i] = vector(i) * (*theCoPvec);
104  theTest[i] = test(i, ds.status(i));
105  }
106  }
107  }
108  else
109  {
110  assert(type() == LEAVE);
111  if (rep() == ROW)
112  {
113  for (int i = start; i < SPxLP::nRows(); ++i)
114  {
115  theURbound[i] = rhs(i);
116  theLRbound[i] = lhs(i);
117  (*thePvec)[i] = vector(i) * (*theCoPvec);
118 
119  /* we need to compare with tolerance (rep() == ROW) ? feastol() : opttol() because thePvec is the primal
120  * vector in ROW and the dual vector in COLUMN representation; this is equivalent to leavetol(); this also
121  * fits because we are within the "type() == LEAVE" case
122  */
123  if (theURbound[i] + leavetol() < (*thePvec)[i])
124  shiftUPbound(i, (*thePvec)[i]);
125  else if ((*thePvec)[i] < theLRbound[i] - leavetol())
126  shiftLPbound(i, (*thePvec)[i]);
127  }
128  }
129  else
130  {
131  assert(rep() == COLUMN);
132  int i;
133  for (i = start; i < SPxLP::nRows(); ++i)
134  {
135  theURbound[i] = theLRbound[i] = maxRowObj(i);
136  clearDualBounds(ds.rowStatus(i),
137  theURbound[i], theLRbound[i]);
138  setLeaveBound4Row(i, i);
140  // init #theFrhs[i]#
141  Real& v_rhs = (*theFrhs)[i];
142  const SVector& row = rowVector(i);
143  v_rhs = 0;
144  for (int j = row.size() - 1; j >= 0; --j)
145  {
146  int idx = row.index(j);
147  switch (ds.colStatus(idx))
148  {
149  case Desc::P_ON_UPPER:
150  v_rhs += row.value(j) * SPxLP::upper(idx);
151  break;
152  case Desc::P_ON_LOWER:
153  case Desc::P_FIXED:
154  v_rhs += row.value(j) * SPxLP::lower(idx);
155  break;
156  default:
157  break;
158  }
159  }
160  }
163  for (i = start; i < SPxLP::nRows(); ++i)
164  {
165  if ((*theFvec)[i] > theUBbound[i])
166  theCoTest[i] = theUBbound[i] - (*theFvec)[i];
167  else
168  theCoTest[i] = (*theFvec)[i] - theLBbound[i];
169  }
170  }
171  }
172 }
173 
174 void SPxSolver::addedRows(int n)
175 {
176 
177  SPxLP::addedRows(n);
178 
179  if( n > 0 )
180  {
181  reDim();
182 
184  {
186 
187  if (isInitialized())
188  {
189  localAddRows(nRows() - n);
190 
191  assert(thepricer != 0);
192 
193  if (rep() == ROW)
194  thepricer->addedVecs(n);
195  else
196  thepricer->addedCoVecs(n);
197  }
198  }
199  }
200 
201  /* we must not assert consistency here, since addedCols() might be still necessary to obtain a consistent basis */
202 }
203 #endif //0
204 
206 {
207 
208  if( n > 0 )
209  {
210  SPxLP::addedRows(n);
211 
212  unInit();
213  reDim();
214 
217  }
218 
219  /* we must not assert consistency here, since addedCols() might be still necessary to obtain a consistent basis */
220 }
221 
222 #if 0
223 void SPxSolver::localAddCols(int start)
224 {
225  assert( start <= SPxLP::nCols() );
226 
227  /**@todo This method seems to be called, to update
228  * theFvec, theFrhs, ..., but a resolve after
229  * adding a row results in a failure.
230  * To fix this, we call unIinit() so that init() is called before solving
231  * in spxsolve.cpp:solve(). In init(), the
232  * vectors are set up, so there is no need
233  * to update them here.
234  */
235  if( start == SPxLP::nCols() )
236  return;
237 
238  const SPxBasis::Desc& ds = desc();
239 
240  if (type() == ENTER)
241  {
242  if (rep() == COLUMN)
243  {
244  int reSolve = 0;
245  int i;
246  Real x;
247  for (i = start; i < SPxLP::nCols(); ++i)
248  {
249  (*thePvec)[i] = vector(i) * (*theCoPvec);
250  theTest[i] = test(i, ds.colStatus(i));
251  theUCbound[i] = SPxLP::upper(i);
252  theLCbound[i] = SPxLP::lower(i);
253  switch (ds.colStatus(i))
254  {
256  assert(SPxLP::lower(i) == SPxLP::upper(i));
257  /*FALLTHROUGH*/
259  x = SPxLP::upper(i);
260  break;
262  x = SPxLP::lower(i);
263  break;
264  default:
265  x = 0;
266  break;
267  }
268  if (x)
269  {
270  theFrhs->multAdd(-x, vector(i));
271  reSolve = 1;
272  }
273  }
274  if (reSolve)
275  {
277  shiftFvec();
278  }
279  }
280  else
281  {
282  int i;
283  for (i = start; i < SPxLP::nCols(); ++i)
284  {
285  theUCbound[i] = theLCbound[i] = 0;
286  (*theFrhs)[i] = SPxLP::spxSense() * SPxLP::obj(i);
288  theUCbound[i], theLCbound[i]);
289  setEnterBound4Col(i, i);
291  }
293  computePvec();
294  computeCoTest();
295  computeTest();
297  for (i = start; i < SPxLP::nCols(); ++i)
298  {
299  /* we need to compare with tolerance (rep() == COLUMN) ? feastol() : opttol() because theFvec is the primal
300  * vector in COLUMN and the dual vector in ROW representation; this is equivalent to entertol(); this also
301  * fits because we are within the "type() == ENTER" case
302  */
303  if (theUBbound[i] + entertol() < (*theFvec)[i])
304  shiftUBbound(i, (*theFvec)[i]);
305  if ((*theFvec)[i] < theLBbound[i] - entertol())
306  shiftLBbound(i, (*theFvec)[i]);
307  }
308  }
309  }
310  else
311  {
312  if (rep() == ROW)
313  {
314  int i;
315  for (i = start; i < SPxLP::nCols(); ++i)
316  {
317  theUCbound[i] = SPxLP::upper(i);
318  theLCbound[i] = SPxLP::lower(i);
319  (*theFrhs)[i] = SPxLP::spxSense() * SPxLP::obj(i);
320  setLeaveBound4Col(i, i);
322  }
324  computePvec();
325  // shiftPvec();
327  for (i = start; i < SPxLP::nCols(); ++i)
328  {
329  if ((*theFvec)[i] > theUBbound[i])
330  theCoTest[i] = theUBbound[i] - (*theFvec)[i];
331  else
332  theCoTest[i] = (*theFvec)[i] - theLBbound[i];
333  }
334  }
335  else
336  {
337  Real x;
338  int i;
339  int reSolve = 0;
340  for (i = start; i < SPxLP::nCols(); ++i)
341  {
342  theUCbound[i] = theLCbound[i] = -maxObj(i);
344  theLCbound[i], theUCbound[i]);
345  theUCbound[i] *= -1;
346  theLCbound[i] *= -1;
347 
348  (*thePvec)[i] = vector(i) * (*theCoPvec);
349 
350  /* we need to compare with tolerance (rep() == ROW) ? feastol() : opttol() because thePvec is the primal
351  * vector in ROW and the dual vector in COLUMN representation; this is equivalent to leavetol(); this also
352  * fits because we are within the "type() == LEAVE" case
353  */
354  if (theUCbound[i] + leavetol() < (*thePvec)[i])
355  shiftUPbound(i, (*thePvec)[i]);
356  if (theLCbound[i] - leavetol() > (*thePvec)[i])
357  shiftLPbound(i, (*thePvec)[i]);
358 
359  switch (ds.colStatus(i))
360  {
362  assert(SPxLP::lower(i) == SPxLP::upper(i));
363  /*FALLTHROUGH*/
365  x = SPxLP::upper(i);
366  break;
368  x = SPxLP::lower(i);
369  break;
370  default:
371  x = 0;
372  break;
373  }
374  if (x)
375  {
376  theFrhs->multAdd(-x, vector(i));
377  reSolve = 1;
378  }
379  }
380  if (reSolve)
381  {
383  computeFtest();
384  }
385  }
386  }
387 }
388 
389 void SPxSolver::addedCols(int n)
390 {
391  SPxLP::addedCols(n);
392 
393  if( n > 0 )
394  {
395  reDim();
396 
398  {
400  if (isInitialized())
401  {
402  localAddCols(nCols() - n);
403  assert(thepricer != 0);
404  if (rep() == COLUMN)
405  thepricer->addedVecs(n);
406  else
408  }
409  }
410  }
411 
412  /* we must not assert consistency here, since addedRows() might be still necessary to obtain a consistent basis */
413 }
414 #endif //0
415 
417 {
418 
419  if( n > 0 )
420  {
421  SPxLP::addedCols(n);
422 
423  unInit();
424  reDim();
425 
428  }
429 
430  /* we must not assert consistency here, since addedRows() might be still necessary to obtain a consistent basis */
431 }
432 
434 {
435 
437 
438  unInit();
439 
441  {
442  removedRow(i);
443 
444 #if 0
445  if (isInitialized())
446  {
447  int n = SPxLP::nRows();
448 
449  theURbound[i] = theURbound[n];
450  theLRbound[i] = theLRbound[n];
451 
452  if (rep() == ROW)
453  {
454  (*thePvec)[i] = (*thePvec)[n];
455  if (type() == ENTER)
456  theTest[i] = theTest[n];
457  reDim();
458  assert(thepricer != 0);
459  thepricer->removedVec(i);
460  }
461  else
462  {
463  unInit();
464  }
465  }
466 #endif // 0
467 
468  switch (SPxBasis::status())
469  {
470  case SPxBasis::DUAL:
473  break;
474  case SPxBasis::OPTIMAL:
476  break;
477  default:
478  break;
479  }
480  }
481 }
482 
483 void SPxSolver::doRemoveRows(int perm[])
484 {
485 
486  SPxLP::doRemoveRows(perm);
487 
488  unInit();
489 
491  {
492  removedRows(perm);
493 #if 0
494  if (isInitialized())
495  {
496  int n = SPxLP::nRows();
497 
498  if (rep() == ROW)
499  {
500  if (type() == ENTER)
501  {
502  for (int i = 0; i < n; ++i)
503  if (perm[i] >= 0)
504  {
505  theURbound[perm[i]] = theURbound[i];
506  theLRbound[perm[i]] = theLRbound[i];
507  (*thePvec)[perm[i]] = (*thePvec)[i];
508  theTest[perm[i]] = theTest[i];
509  }
510  }
511  else
512  {
513  for (int i = 0; i < n; ++i)
514  if (perm[i] >= 0)
515  {
516  theURbound[perm[i]] = theURbound[i];
517  theLRbound[perm[i]] = theLRbound[i];
518  (*thePvec)[perm[i]] = (*thePvec)[i];
519  }
520  }
521  assert(thepricer != 0);
522  thepricer->removedVecs(perm);
523  reDim();
524  }
525  else
526  {
527  unInit();
528  }
529  }
530 #endif
531  switch (SPxBasis::status())
532  {
533  case SPxBasis::DUAL:
536  break;
537  case SPxBasis::OPTIMAL:
539  break;
540  default:
541  break;
542  }
543  }
544 }
545 
547 {
549 
551 
552  unInit();
553 
555  {
556  removedCol(i);
557 
558 #if 0
559  if (isInitialized())
560  {
561  int n = SPxLP::nCols();
562 
563  theUCbound[i] = theUCbound[n];
564  theLCbound[i] = theLCbound[n];
565  if (rep() == COLUMN)
566  {
567  (*thePvec)[i] = (*thePvec)[n];
568  if (type() == ENTER)
569  theTest[i] = theTest[n];
570  assert(thepricer != 0);
571  thepricer->removedVec(i);
572  reDim();
573  }
574  else
575  {
576  unInit();
577  }
578  }
579 #endif //0
580  switch (SPxBasis::status())
581  {
582  case SPxBasis::PRIMAL:
583  case SPxBasis::UNBOUNDED:
585  break;
586  case SPxBasis::OPTIMAL:
588  break;
589  default:
590  break;
591  }
592  }
593 }
594 
595 void SPxSolver::doRemoveCols(int perm[])
596 {
598 
599  SPxLP::doRemoveCols(perm);
600 
601  unInit();
602 
604  {
605  removedCols(perm);
606 
607 #if 0
608  if (isInitialized())
609  {
610  int n = SPxLP::nCols();
611 
612  if (rep() == COLUMN)
613  {
614  if (type() == ENTER)
615  {
616  for (int i = 0; i < n; ++i)
617  if (perm[i] >= 0)
618  {
619  theUCbound[perm[i]] = theUCbound[i];
620  theLCbound[perm[i]] = theLCbound[i];
621  (*thePvec)[perm[i]] = (*thePvec)[i];
622  theTest[perm[i]] = theTest[i];
623  }
624  }
625  else
626  {
627  for (int i = 0; i < n; ++i)
628  if (perm[i] >= 0)
629  {
630  theUCbound[perm[i]] = theUCbound[i];
631  theLCbound[perm[i]] = theLCbound[i];
632  (*thePvec)[perm[i]] = (*thePvec)[i];
633  }
634  }
635  assert(thepricer != 0);
636  thepricer->removedVecs(perm);
637  reDim();
638  }
639  else
640  {
641  unInit();
642  }
643  }
644 #endif //0
645  switch (SPxBasis::status())
646  {
647  case SPxBasis::PRIMAL:
648  case SPxBasis::UNBOUNDED:
650  break;
651  case SPxBasis::OPTIMAL:
653  break;
654  default:
655  break;
656  }
657  }
658 }
659 
660 void SPxSolver::changeObj(const Vector& newObj, bool scale)
661 {
663 
664  SPxLP::changeObj(newObj, scale);
665 
666  /**@todo Factorization remains valid, we do not need a reDim()
667  * pricing vectors should be recomputed.
668  */
669  unInit();
670 }
671 
672 void SPxSolver::changeObj(int i, const Real& newVal, bool scale)
673 {
675 
676  SPxLP::changeObj(i, newVal, scale);
677 
678 
679  /**@todo Factorization remains valid, we do not need a reDim()
680  * pricing vectors should be recomputed.
681  */
682  unInit();
683 }
684 
685 void SPxSolver::changeMaxObj(const Vector& newObj, bool scale)
686 {
688 
689  SPxLP::changeMaxObj(newObj, scale);
690 
691  /**@todo Factorization remains valid, we do not need a reDim()
692  * pricing vectors should be recomputed.
693  */
694  unInit();
695 }
696 
697 void SPxSolver::changeMaxObj(int i, const Real& newVal, bool scale)
698 {
700 
701  SPxLP::changeMaxObj(i, newVal, scale);
702 
703  /**@todo Factorization remains valid, we do not need a reDim()
704  * pricing vectors should be recomputed.
705  */
706  unInit();
707 }
708 
709 void SPxSolver::changeRowObj(const Vector& newObj, bool scale)
710 {
712 
713  SPxLP::changeRowObj(newObj, scale);
714 
715  /**@todo Factorization remains valid, we do not need a reDim()
716  * pricing vectors should be recomputed.
717  */
718  unInit();
719 }
720 
721 void SPxSolver::changeRowObj(int i, const Real& newVal, bool scale)
722 {
724 
725  SPxLP::changeRowObj(i, newVal, scale);
726 
727  /**@todo Factorization remains valid, we do not need a reDim()
728  * pricing vectors should be recomputed.
729  */
730  unInit();
731 }
732 
733 void SPxSolver::changeLowerStatus(int i, Real newLower, Real oldLower)
734 {
736  Real currUpper = upper(i);
737  Real objChange = 0.0;
738 
739  MSG_DEBUG( std::cout << "DCHANG01 changeLowerStatus(): col " << i
740  << "[" << newLower << ":" << currUpper << "] " << stat; )
741 
742  switch (stat)
743  {
745  if (newLower <= -infinity)
746  {
747  if (currUpper >= infinity)
748  {
749  stat = SPxBasis::Desc::P_FREE;
750  if( m_nonbasicValueUpToDate && rep() == COLUMN )
751  objChange = -theLCbound[i] * oldLower;
752  }
753  else
754  {
756  if( m_nonbasicValueUpToDate && rep() == COLUMN )
757  objChange = (theUCbound[i] * currUpper) - (theLCbound[i] * oldLower);
758  }
759  }
760  else if (EQ(newLower, currUpper))
761  {
763  if( m_nonbasicValueUpToDate && rep() == COLUMN )
764  objChange = maxObj(i) * (newLower - oldLower);
765  }
766  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
767  objChange = theLCbound[i] * (newLower - oldLower);
768  break;
770  if (newLower == currUpper)
772  break;
774  if (newLower > -infinity)
775  {
777  if( m_nonbasicValueUpToDate && rep() == COLUMN )
778  objChange = theLCbound[i] * newLower;
779  }
780  break;
782  if (NE(newLower, currUpper))
784  break;
790  if( rep() == ROW && theShift > 0.0 )
792  stat = dualColStatus(i);
793  break;
794  default:
795  throw SPxInternalCodeException("XCHANG01 This should never happen.");
796  }
797 
798  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
799 
800  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
801  if( rep() == COLUMN )
802  updateNonbasicValue(objChange);
803 }
804 
805 void SPxSolver::changeLower(const Vector& newLower, bool scale)
806 {
807  // we better recompute the nonbasic value when changing all lower bounds
809 
810  SPxLP::changeLower(newLower, scale);
811 
813  {
814  for (int i = 0; i < newLower.dim(); ++i)
815  changeLowerStatus(i, lower(i));
816 
817  unInit();
818  }
819 }
820 
821 void SPxSolver::changeLower(int i, const Real& newLower, bool scale)
822 {
823  if( NE(newLower, lowerUnscaled(i)) )
824  {
825  Real oldLower = lower(i);
826  // This has to be done before calling changeLowerStatus() because that is calling
827  // basis.dualColStatus() which calls lower() and needs the changed value.
828  SPxLP::changeLower(i, newLower, scale);
829 
831  {
832  changeLowerStatus(i, lower(i), oldLower);
833  unInit();
834  }
835  }
836 }
837 
838 void SPxSolver::changeUpperStatus(int i, Real newUpper, Real oldUpper)
839 {
841  Real currLower = lower(i);
842  Real objChange = 0.0;
843 
844  MSG_DEBUG( std::cout << "DCHANG02 changeUpperStatus(): col " << i
845  << "[" << currLower << ":" << newUpper << "] " << stat; )
846 
847  switch (stat)
848  {
850  if (newUpper == currLower)
852  break;
854  if (newUpper >= infinity)
855  {
856  if (currLower <= -infinity)
857  {
858  stat = SPxBasis::Desc::P_FREE;
859  if( m_nonbasicValueUpToDate && rep() == COLUMN )
860  objChange = -theUCbound[i] * oldUpper;
861  }
862  else
863  {
865  if( m_nonbasicValueUpToDate && rep() == COLUMN )
866  objChange = (theLCbound[i] * currLower) - (theUCbound[i] * oldUpper);
867  }
868  }
869  else if (newUpper == currLower)
870  {
872  if( m_nonbasicValueUpToDate && rep() == COLUMN )
873  objChange = maxObj(i) * (newUpper - oldUpper);
874  }
875  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
876  objChange = theUCbound[i] * (newUpper - oldUpper);
877  break;
879  if (newUpper < infinity)
880  {
882  if( m_nonbasicValueUpToDate && rep() == COLUMN )
883  objChange = theUCbound[i] * newUpper;
884  }
885  break;
887  if (newUpper != currLower)
889  break;
895  if( rep() == ROW && theShift > 0.0 )
897  stat = dualColStatus(i);
898  break;
899  default:
900  throw SPxInternalCodeException("XCHANG02 This should never happen.");
901  }
902  MSG_DEBUG( std::cout << " -> " << stat << std::endl; );
903 
904  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
905  if( rep() == COLUMN )
906  updateNonbasicValue(objChange);
907 }
908 
909 void SPxSolver::changeUpper(const Vector& newUpper, bool scale)
910 {
911  // we better recompute the nonbasic value when changing all upper bounds
913 
914  SPxLP::changeUpper(newUpper, scale);
915 
917  {
918  for (int i = 0; i < newUpper.dim(); ++i)
919  changeUpperStatus(i, upper(i));
920 
921  unInit();
922  }
923 }
924 
925 void SPxSolver::changeUpper(int i, const Real& newUpper, bool scale)
926 {
927  if( newUpper != upperUnscaled(i) )
928  {
929  Real oldUpper = upper(i);
930  SPxLP::changeUpper(i, newUpper, scale);
931 
933  {
934  changeUpperStatus(i, upper(i), oldUpper);
935  unInit();
936  }
937  }
938 }
939 
940 void SPxSolver::changeBounds(const Vector& newLower, const Vector& newUpper, bool scale)
941 {
942  changeLower(newLower, scale);
943  changeUpper(newUpper, scale);
944 }
945 
946 void SPxSolver::changeBounds(int i, const Real& newLower, const Real& newUpper, bool scale)
947 {
948  changeLower(i, newLower, scale);
949  changeUpper(i, newUpper, scale);
950 }
951 
952 void SPxSolver::changeLhsStatus(int i, Real newLhs, Real oldLhs)
953 {
955  Real currRhs = rhs(i);
956  Real objChange = 0.0;
957 
958  MSG_DEBUG( std::cout << "DCHANG03 changeLhsStatus() : row " << i
959  << ": " << stat; )
960  switch (stat)
961  {
963  if (newLhs <= -infinity)
964  {
965  if (currRhs >= infinity)
966  {
967  stat = SPxBasis::Desc::P_FREE;
968  if( m_nonbasicValueUpToDate && rep() == COLUMN )
969  objChange = -theURbound[i] * oldLhs;
970  }
971  else
972  {
974  if( m_nonbasicValueUpToDate && rep() == COLUMN )
975  objChange = (theLRbound[i] * currRhs) - (theURbound[i] * oldLhs);
976  }
977  }
978  else if (newLhs == currRhs)
979  {
981  if( m_nonbasicValueUpToDate && rep() == COLUMN )
982  objChange = maxRowObj(i) * (newLhs - oldLhs);
983  }
984  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
985  objChange = theURbound[i] * (newLhs - oldLhs);
986  break;
988  if (newLhs == currRhs)
990  break;
992  if (newLhs > -infinity)
993  {
995  if( m_nonbasicValueUpToDate && rep() == COLUMN )
996  objChange = theURbound[i] * newLhs;
997  }
998  break;
1000  if (newLhs != currRhs)
1002  break;
1008  if( rep() == ROW && theShift > 0.0 )
1010  stat = dualRowStatus(i);
1011  break;
1012  default:
1013  throw SPxInternalCodeException("XCHANG03 This should never happen.");
1014  }
1015  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
1016 
1017  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
1018  if( rep() == COLUMN )
1019  updateNonbasicValue(objChange);
1020 }
1021 
1022 void SPxSolver::changeLhs(const Vector& newLhs, bool scale)
1023 {
1024  // we better recompute the nonbasic value when changing all lhs
1026 
1027  SPxLP::changeLhs(newLhs, scale);
1028 
1030  {
1031  for (int i = 0; i < nRows(); ++i)
1032  changeLhsStatus(i, lhs(i));
1033 
1034  unInit();
1035  }
1036 }
1037 
1038 void SPxSolver::changeLhs(int i, const Real& newLhs, bool scale)
1039 {
1040  if( newLhs != lhsUnscaled(i) )
1041  {
1042  Real oldLhs = lhs(i);
1043  SPxLP::changeLhs(i, newLhs, scale);
1044 
1046  {
1047  changeLhsStatus(i, lhs(i), oldLhs);
1048  unInit();
1049  }
1050  }
1051 }
1052 
1053 void SPxSolver::changeRhsStatus(int i, Real newRhs, Real oldRhs)
1054 {
1055  SPxBasis::Desc::Status& stat = desc().rowStatus(i);
1056  Real currLhs = lhs(i);
1057  Real objChange = 0.0;
1058 
1059  MSG_DEBUG( std::cout << "DCHANG04 changeRhsStatus() : row " << i
1060  << ": " << stat; )
1061  switch (stat)
1062  {
1064  if (newRhs >= infinity)
1065  {
1066  if (currLhs <= -infinity)
1067  {
1068  stat = SPxBasis::Desc::P_FREE;
1069  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1070  objChange = -theLRbound[i] * oldRhs;
1071  }
1072  else
1073  {
1075  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1076  objChange = (theURbound[i] * currLhs) - (theLRbound[i] * oldRhs);
1077  }
1078  }
1079  else if (newRhs == currLhs)
1080  {
1081  stat = SPxBasis::Desc::P_FIXED;
1082  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1083  objChange = maxRowObj(i) * (newRhs - oldRhs);
1084  }
1085  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
1086  objChange = theLRbound[i] * (newRhs - oldRhs);
1087  break;
1089  if (newRhs == currLhs)
1090  stat = SPxBasis::Desc::P_FIXED;
1091  break;
1093  if (newRhs < infinity)
1094  {
1096  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1097  objChange = theLRbound[i] * newRhs;
1098  }
1099  break;
1101  if (newRhs != currLhs)
1103  break;
1109  if( rep() == ROW && theShift > 0.0 )
1111  stat = dualRowStatus(i);
1112  break;
1113  default:
1114  throw SPxInternalCodeException("XCHANG04 This should never happen.");
1115  }
1116  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
1117 
1118  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
1119  if( rep() == COLUMN )
1120  updateNonbasicValue(objChange);
1121 }
1122 
1123 
1124 void SPxSolver::changeRhs(const Vector& newRhs, bool scale)
1125 {
1126  // we better recompute the nonbasic value when changing all rhs
1128 
1129  SPxLP::changeRhs(newRhs, scale);
1130 
1132  {
1133  for (int i = 0; i < nRows(); ++i)
1134  changeRhsStatus(i, rhs(i));
1135  unInit();
1136  }
1137 }
1138 
1139 void SPxSolver::changeRhs(int i, const Real& newRhs, bool scale)
1140 {
1141  if( newRhs != rhsUnscaled(i) )
1142  {
1143  Real oldRhs = rhs(i);
1144  SPxLP::changeRhs(i, newRhs, scale);
1145 
1147  {
1148  changeRhsStatus(i, rhs(i), oldRhs);
1149  unInit();
1150  }
1151  }
1152 }
1153 
1154 void SPxSolver::changeRange(const Vector& newLhs, const Vector& newRhs, bool scale)
1155 {
1156  // we better recompute the nonbasic value when changing all ranges
1158 
1159  SPxLP::changeLhs(newLhs, scale);
1160  SPxLP::changeRhs(newRhs, scale);
1162  {
1163  for (int i = nRows() - 1; i >= 0; --i)
1164  {
1165  changeLhsStatus(i, lhs(i));
1166  changeRhsStatus(i, rhs(i));
1167  }
1168  unInit();
1169  }
1170 }
1171 
1172 void SPxSolver::changeRange(int i, const Real& newLhs, const Real& newRhs, bool scale)
1173 {
1174  Real oldLhs = lhs(i);
1175  Real oldRhs = rhs(i);
1176 
1177  SPxLP::changeLhs(i, newLhs, scale);
1178  SPxLP::changeRhs(i, newRhs, scale);
1179 
1181  {
1182  changeLhsStatus(i, lhs(i), oldLhs);
1183  changeRhsStatus(i, rhs(i), oldRhs);
1184  unInit();
1185  }
1186 }
1187 
1188 void SPxSolver::changeRow(int i, const LPRow& newRow, bool scale)
1189 {
1191 
1192  SPxLP::changeRow(i, newRow, scale);
1194  SPxBasis::changedRow( i );
1195  unInit();
1196 }
1197 
1198 void SPxSolver::changeCol(int i, const LPCol& newCol, bool scale)
1199 {
1200  if( i < 0 )
1201  return;
1202 
1204 
1205  SPxLP::changeCol(i, newCol, scale);
1207  SPxBasis::changedCol( i );
1208  unInit();
1209 }
1210 
1211 void SPxSolver::changeElement(int i, int j, const Real& val, bool scale)
1212 {
1213  if( i < 0 || j < 0 )
1214  return;
1215 
1217 
1218  SPxLP::changeElement(i, j, val, scale);
1220  SPxBasis::changedElement( i, j );
1221  unInit();
1222 }
1223 
1225 {
1226 
1227  SPxLP::changeSense(sns);
1228  unInit();
1229 }
1230 } // namespace soplex
const VectorBase< Real > & rhs() const
Returns right hand side vector.
Definition: spxlpbase.h:219
void computeFtest()
compute basis feasibility test vector.
Definition: leave.cpp:38
virtual void addedRows(int n)
virtual void changeRow(int i, const LPRow &newRow, bool scale=false)
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
Definition: exceptions.h:109
void addedRows(int n)
inform SPxBasis, that n new rows had been added.
void setEnterBound4Col(int, int)
Definition: spxbounds.cpp:187
Basis is dual feasible.
Definition: spxbasis.h:95
Basis is not known to be dual nor primal feasible.
Definition: spxbasis.h:94
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:712
primal variable is fixed to both bounds
Definition: spxbasis.h:190
virtual void changeLower(const Vector &newLower, bool scale=false)
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
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
void removedCols(const int perm[])
inform SPxBasis that columns in perm with negative entry were removed.
DVector theCoTest
Definition: spxsolver.h:358
Abstract pricer base class.
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:769
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:102
virtual void removedVecs(const int *)
vectors given by perm have been removed from loaded LP.
Definition: spxpricer.h:237
virtual void reDim()
reset dimensions of vectors according to loaded LP.
Definition: spxsolver.cpp:462
Basis is optimal, i.e. dual and primal feasible.
Definition: spxbasis.h:97
Exception classes for SoPlex.
Status & rowStatus(int i)
Definition: spxbasis.h:239
Real rhsUnscaled(int i) const
Returns unscaled right hand side of row number i.
virtual void changeCol(int n, const LPColBase< Real > &newCol, bool scale=false)
Replaces i &#39;th column of LP with newCol. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1586
virtual void addedCols(int newcols)
Called after the last n columns have just been added.
Definition: spxlpbase.h:2021
void localAddCols(int start)
Abstract ratio test base class.
void clearDualBounds(SPxBasis::Desc::Status, Real &, Real &) const
Definition: spxbounds.cpp:76
virtual void changeUpper(const Vector &newUpper, bool scale=false)
bool NE(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| > eps
Definition: spxdefines.h:392
void changedCol(int)
inform SPxBasis that a column had been changed.
virtual void addedCols(int n)
void shiftLBbound(int i, Real to)
shift i &#39;th lbBound to to.
Definition: spxsolver.h:1543
void setLeaveBound4Col(int i, int n)
Definition: spxbounds.cpp:260
virtual void changeCol(int i, const LPCol &newCol, bool scale=false)
void changedElement(int, int)
inform SPxBasis that a matrix entry had been changed.
rowwise representation.
Definition: spxsolver.h:107
Desc::Status dualRowStatus(int i) const
dual Status for the i&#39;th row variable of the loaded LP.
Definition: spxbasis.cpp:46
void changedRow(int)
inform SPxBasis that a row had been changed.
dual variable is left free, but unset
Definition: spxbasis.h:191
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:151
void removedCol(int i)
inform SPxBasis that column i had been removed.
virtual void changeRhs(const Vector &newRhs, bool scale=false)
Entering Simplex.
Definition: spxsolver.h:134
primal variable is set to its upper bound
Definition: spxbasis.h:188
virtual void addedCoVecs(int)
n covectors have been added to loaded LP.
Definition: spxpricer.h:226
virtual void changeBounds(const Vector &newLower, const Vector &newUpper, bool scale=false)
Leaving Simplex.
Definition: spxsolver.h:143
virtual void changeLhsStatus(int i, Real newLhs, Real oldLhs=0.0)
SPxSense
Optimization sense.
Definition: spxlpbase.h:97
virtual void doRemoveRow(int i)
virtual void changeRowObj(const Vector &newObj, bool scale=false)
SPxStatus status() const
returns current SPxStatus.
Definition: spxbasis.h:425
double Real
Definition: spxdefines.h:214
virtual void doRemoveRows(int perm[])
Internal helper method.
Definition: spxlpbase.h:1945
void removedRows(const int perm[])
inform SPxBasis that rows in perm with negative entry were removed.
DVector * theFrhs
Definition: spxsolver.h:340
void localAddRows(int start)
virtual void doRemoveCols(int perm[])
#define MSG_DEBUG(x)
Definition: spxdefines.h:128
void shiftLPbound(int i, Real to)
shift i &#39;th lpBound to to.
Definition: spxsolver.h:1557
virtual void addedVecs(int)
n vectors have been added to loaded LP.
Definition: spxpricer.h:223
SPxSense spxSense() const
Returns the optimization sense.
Definition: spxlpbase.h:510
virtual void changeMaxObj(const VectorBase< Real > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1289
virtual void unInit()
uninitialize data structures.
Definition: spxsolver.h:1813
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:762
UpdateVector * thePvec
Definition: spxsolver.h:345
Real upperUnscaled(int i) const
Returns unscaled upper bound of column i.
virtual void changeSense(SPxSense sns)
SPxPricer * thepricer
Definition: spxsolver.h:379
virtual void changeElement(int i, int j, const Real &val, bool scale=false)
void computeEnterCoPrhs4Col(int i, int n)
Definition: spxvecs.cpp:367
dual variable is set to its upper bound
Definition: spxbasis.h:192
DVector theLBbound
Lower Basic Feasibility bound.
Definition: spxsolver.h:338
main LP solver class
virtual void changeLhs(const Vector &newLhs, bool scale=false)
primal variable is left free, but unset
Definition: spxbasis.h:189
virtual void changeLower(const VectorBase< Real > &newLower, bool scale=false)
Changes vector of lower bounds to newLower. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1325
virtual void changeRhs(const VectorBase< Real > &newRhs, bool scale=false)
Changes right hand side vector for constraints to newRhs. scale determines whether the new data shoul...
Definition: spxlpbase.h:1460
const VectorBase< Real > & lhs() const
Returns left hand side vector.
Definition: spxlpbase.h:253
bool updateNonbasicValue(Real objChange)
Definition: spxsolver.cpp:912
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:327
virtual void changeLowerStatus(int i, Real newLower, Real oldLower=0.0)
const VectorBase< Real > & maxRowObj() const
Definition: spxlpbase.h:297
Real lhsUnscaled(int i) const
Returns unscaled left hand side of row number i.
const Vector & test() const
Violations of pVec.
Definition: spxsolver.h:1491
void shiftUBbound(int i, Real to)
shift i &#39;th ubBound to to.
Definition: spxsolver.h:1536
Status & colStatus(int i)
Definition: spxbasis.h:254
(In)equality for LPs.Class LPRowBase provides constraints for linear programs in the form where a is...
Definition: lprowbase.h:45
DVector theUBbound
Upper Basic Feasibility bound.
Definition: spxsolver.h:337
virtual void changeRow(int n, const LPRowBase< Real > &newRow, bool scale=false)
Replaces i &#39;th row of LP with newRow. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1546
virtual void changeRhsStatus(int i, Real newRhs, Real oldRhs=0.0)
virtual void changeUpper(const VectorBase< Real > &newUpper, bool scale=false)
Changes vector of upper bounds to newUpper. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1361
virtual void changeMaxObj(const Vector &newObj, bool scale=false)
Debugging, floating point type and parameter definitions.
SVectorBase< Real > SVector
Definition: svector.h:29
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
Definition: spxdefines.h:386
virtual void changeObj(const VectorBase< Real > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1257
DVector theLRbound
Lower Row Feasibility bound.
Definition: spxsolver.h:328
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:329
bool isInitialized() const
has the internal data been initialized?
Definition: spxsolver.h:1804
void computeLeaveCoPrhs4Col(int i, int n)
Definition: spxvecs.cpp:448
VectorBase< R > & multAdd(const S &x, const VectorBase< T > &vec)
Addition of scaled vector.
Definition: vectorbase.h:410
void computeEnterCoPrhs4Row(int i, int n)
Definition: spxvecs.cpp:336
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
virtual void doRemoveCols(int perm[])
Internal helper method.
Definition: spxlpbase.h:1995
Everything should be within this namespace.
void shiftUPbound(int i, Real to)
shift i &#39;th upBound to to.
Definition: spxsolver.h:1550
virtual void changeRange(const Vector &newLhs, const Vector &newRhs, bool scale=false)
void computeLeaveCoPrhs4Row(int i, int n)
Definition: spxvecs.cpp:419
UpdateVector * theFvec
Definition: spxsolver.h:341
Real lowerUnscaled(int i) const
Returns unscaled lower bound of column i.
primal variable is set to its lower bound
Definition: spxbasis.h:187
bool m_nonbasicValueUpToDate
true, if the stored objValue is up to date
Definition: spxsolver.h:257
const VectorBase< Real > & maxObj() const
Returns objective vector for maximization problem.
Definition: spxlpbase.h:429
void setEnterBound4Row(int, int)
Definition: spxbounds.cpp:165
DVector theLCbound
Lower Column Feasibility bound.
Definition: spxsolver.h:330
const SVectorBase< Real > & rowVector(int i) const
Gets row vector of row i.
Definition: spxlpbase.h:204
virtual void changeRowObj(const VectorBase< Real > &newRowObj, bool scale=false)
Changes row objective function vector to newRowObj. scale determines whether the new data should be s...
Definition: spxlpbase.h:1515
virtual void removedVec(int)
vector i was removed from loaded LP.
Definition: spxpricer.h:234
virtual void changeUpperStatus(int i, Real newUpper, Real oldLower=0.0)
void removedRow(int i)
inform SPxBasis that row i had been removed.
void shiftFvec()
Perform initial shifting to optain an feasible or pricable basis.
Definition: spxshift.cpp:25
DVector * theCoPrhs
Definition: spxsolver.h:343
dual variable is set to its lower bound
Definition: spxbasis.h:193
virtual void changeSense(SPxSense sns)
Changes optimization sense to sns.
Definition: spxlpbase.h:1706
Type type() const
return current Type.
Definition: spxsolver.h:474
Real theShift
sum of all shifts applied to any bound.
Definition: spxsolver.h:266
virtual void doRemoveCol(int i)
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:157
virtual void changeElement(int i, int j, const Real &val, bool scale=false)
Changes LP element (i, j) to val. scale determines whether the new data should be scaled...
Definition: spxlpbase.h:1626
virtual void changeLhs(const VectorBase< Real > &newLhs, bool scale=false)
Changes left hand side vector for constraints to newLhs. scale determines whether the new data should...
Definition: spxlpbase.h:1428
dual variable has two bounds
Definition: spxbasis.h:194
virtual void doRemoveRow(int j)
Internal helper method.
Definition: spxlpbase.h:1917
virtual void doRemoveRows(int perm[])
virtual void addedRows(int newrows)
Called after the last n rows have just been added.
Definition: spxlpbase.h:2017
void forceRecompNonbasicValue()
Definition: spxsolver.h:632
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:624
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1117
void computePvec()
compute entire pVec().
Definition: spxvecs.cpp:498
virtual void doRemoveCol(int j)
Internal helper method.
Definition: spxlpbase.h:1966
UpdateVector * theCoPvec
Definition: spxsolver.h:344
Status
Status of a variable.
Definition: spxbasis.h:185
virtual void changeObj(const Vector &newObj, bool scale=false)
scale determines whether the new data needs to be scaled according to the existing LP (persistent sca...
void setLeaveBound4Row(int i, int n)
Definition: spxbounds.cpp:229
const VectorBase< Real > & obj() const
Returns the vector of objective coefficients.
Definition: lprowsetbase.h:167
LP has been proven to be primal unbounded.
Definition: spxbasis.h:98
const VectorBase< Real > & lower() const
Returns (internal and possibly scaled) lower bound vector.
Definition: spxlpbase.h:483
LP column.Class LPColBase provides a datatype for storing the column of an LP a the form similar to ...
Definition: lpcolbase.h:45
const Desc & desc() const
Definition: spxbasis.h:463
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:468
columnwise representation.
Definition: spxsolver.h:108
Basis is primal feasible.
Definition: spxbasis.h:96
void setBasisStatus(SPxBasis::SPxStatus stat)
set the lp solver&#39;s basis status.
Definition: spxsolver.h:2004
void addedCols(int n)
inform SPxBasis that n new columns had been added.
LP has been proven to be primal infeasible.
Definition: spxbasis.h:99
No Problem has been loaded to the basis.
Definition: spxbasis.h:92
void computeCoTest()
compute coTest vector.
Definition: enter.cpp:228