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( EQ(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) )
783  {
785  if( isInitialized() )
786  theUCbound[i] = maxObj(i);
787  }
788  break;
794  if( rep() == ROW && theShift > 0.0 )
796  stat = dualColStatus(i);
797  break;
798  default:
799  throw SPxInternalCodeException("XCHANG01 This should never happen.");
800  }
801 
802  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
803 
804  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
805  if( rep() == COLUMN )
806  updateNonbasicValue(objChange);
807 }
808 
809 void SPxSolver::changeLower(const Vector& newLower, bool scale)
810 {
811  // we better recompute the nonbasic value when changing all lower bounds
813 
814  SPxLP::changeLower(newLower, scale);
815 
817  {
818  for (int i = 0; i < newLower.dim(); ++i)
819  changeLowerStatus(i, lower(i));
820 
821  unInit();
822  }
823 }
824 
825 void SPxSolver::changeLower(int i, const Real& newLower, bool scale)
826 {
827  if( NE(newLower, lowerUnscaled(i)) )
828  {
829  Real oldLower = lower(i);
830  // This has to be done before calling changeLowerStatus() because that is calling
831  // basis.dualColStatus() which calls lower() and needs the changed value.
832  SPxLP::changeLower(i, newLower, scale);
833 
835  {
836  changeLowerStatus(i, lower(i), oldLower);
837  unInit();
838  }
839  }
840 }
841 
842 void SPxSolver::changeUpperStatus(int i, Real newUpper, Real oldUpper)
843 {
845  Real currLower = lower(i);
846  Real objChange = 0.0;
847 
848  MSG_DEBUG( std::cout << "DCHANG02 changeUpperStatus(): col " << i
849  << "[" << currLower << ":" << newUpper << "] " << stat; )
850 
851  switch (stat)
852  {
854  if (newUpper == currLower)
856  break;
858  if (newUpper >= infinity)
859  {
860  if (currLower <= -infinity)
861  {
862  stat = SPxBasis::Desc::P_FREE;
863  if( m_nonbasicValueUpToDate && rep() == COLUMN )
864  objChange = -theUCbound[i] * oldUpper;
865  }
866  else
867  {
869  if( m_nonbasicValueUpToDate && rep() == COLUMN )
870  objChange = (theLCbound[i] * currLower) - (theUCbound[i] * oldUpper);
871  }
872  }
873  else if (EQ(newUpper, currLower))
874  {
876  if( m_nonbasicValueUpToDate && rep() == COLUMN )
877  objChange = maxObj(i) * (newUpper - oldUpper);
878  }
879  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
880  objChange = theUCbound[i] * (newUpper - oldUpper);
881  break;
883  if (newUpper < infinity)
884  {
886  if( m_nonbasicValueUpToDate && rep() == COLUMN )
887  objChange = theUCbound[i] * newUpper;
888  }
889  break;
891  if( NE(newUpper, currLower) )
892  {
894  if( isInitialized() )
895  theLCbound[i] = maxObj(i);
896  }
897  break;
903  if( rep() == ROW && theShift > 0.0 )
905  stat = dualColStatus(i);
906  break;
907  default:
908  throw SPxInternalCodeException("XCHANG02 This should never happen.");
909  }
910  MSG_DEBUG( std::cout << " -> " << stat << std::endl; );
911 
912  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
913  if( rep() == COLUMN )
914  updateNonbasicValue(objChange);
915 }
916 
917 void SPxSolver::changeUpper(const Vector& newUpper, bool scale)
918 {
919  // we better recompute the nonbasic value when changing all upper bounds
921 
922  SPxLP::changeUpper(newUpper, scale);
923 
925  {
926  for (int i = 0; i < newUpper.dim(); ++i)
927  changeUpperStatus(i, upper(i));
928 
929  unInit();
930  }
931 }
932 
933 void SPxSolver::changeUpper(int i, const Real& newUpper, bool scale)
934 {
935  if( newUpper != upperUnscaled(i) )
936  {
937  Real oldUpper = upper(i);
938  SPxLP::changeUpper(i, newUpper, scale);
939 
941  {
942  changeUpperStatus(i, upper(i), oldUpper);
943  unInit();
944  }
945  }
946 }
947 
948 void SPxSolver::changeBounds(const Vector& newLower, const Vector& newUpper, bool scale)
949 {
950  changeLower(newLower, scale);
951  changeUpper(newUpper, scale);
952 }
953 
954 void SPxSolver::changeBounds(int i, const Real& newLower, const Real& newUpper, bool scale)
955 {
956  changeLower(i, newLower, scale);
957  changeUpper(i, newUpper, scale);
958 }
959 
960 void SPxSolver::changeLhsStatus(int i, Real newLhs, Real oldLhs)
961 {
963  Real currRhs = rhs(i);
964  Real objChange = 0.0;
965 
966  MSG_DEBUG( std::cout << "DCHANG03 changeLhsStatus() : row " << i
967  << ": " << stat; )
968  switch (stat)
969  {
971  if (newLhs <= -infinity)
972  {
973  if (currRhs >= infinity)
974  {
975  stat = SPxBasis::Desc::P_FREE;
976  if( m_nonbasicValueUpToDate && rep() == COLUMN )
977  objChange = -theURbound[i] * oldLhs;
978  }
979  else
980  {
982  if( m_nonbasicValueUpToDate && rep() == COLUMN )
983  objChange = (theLRbound[i] * currRhs) - (theURbound[i] * oldLhs);
984  }
985  }
986  else if( EQ(newLhs, currRhs) )
987  {
989  if( m_nonbasicValueUpToDate && rep() == COLUMN )
990  objChange = maxRowObj(i) * (newLhs - oldLhs);
991  }
992  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
993  objChange = theURbound[i] * (newLhs - oldLhs);
994  break;
996  if( EQ(newLhs, currRhs) )
998  break;
1000  if (newLhs > -infinity)
1001  {
1003  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1004  objChange = theURbound[i] * newLhs;
1005  }
1006  break;
1008  if( NE(newLhs, currRhs) )
1009  {
1011  if( isInitialized() )
1012  theLRbound[i] = maxRowObj(i);
1013  }
1014  break;
1020  if( rep() == ROW && theShift > 0.0 )
1022  stat = dualRowStatus(i);
1023  break;
1024  default:
1025  throw SPxInternalCodeException("XCHANG03 This should never happen.");
1026  }
1027  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
1028 
1029  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
1030  if( rep() == COLUMN )
1031  updateNonbasicValue(objChange);
1032 }
1033 
1034 void SPxSolver::changeLhs(const Vector& newLhs, bool scale)
1035 {
1036  // we better recompute the nonbasic value when changing all lhs
1038 
1039  SPxLP::changeLhs(newLhs, scale);
1040 
1042  {
1043  for (int i = 0; i < nRows(); ++i)
1044  changeLhsStatus(i, lhs(i));
1045 
1046  unInit();
1047  }
1048 }
1049 
1050 void SPxSolver::changeLhs(int i, const Real& newLhs, bool scale)
1051 {
1052  if( newLhs != lhsUnscaled(i) )
1053  {
1054  Real oldLhs = lhs(i);
1055  SPxLP::changeLhs(i, newLhs, scale);
1056 
1058  {
1059  changeLhsStatus(i, lhs(i), oldLhs);
1060  unInit();
1061  }
1062  }
1063 }
1064 
1065 void SPxSolver::changeRhsStatus(int i, Real newRhs, Real oldRhs)
1066 {
1067  SPxBasis::Desc::Status& stat = desc().rowStatus(i);
1068  Real currLhs = lhs(i);
1069  Real objChange = 0.0;
1070 
1071  MSG_DEBUG( std::cout << "DCHANG04 changeRhsStatus() : row " << i
1072  << ": " << stat; )
1073  switch (stat)
1074  {
1076  if (newRhs >= infinity)
1077  {
1078  if (currLhs <= -infinity)
1079  {
1080  stat = SPxBasis::Desc::P_FREE;
1081  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1082  objChange = -theLRbound[i] * oldRhs;
1083  }
1084  else
1085  {
1087  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1088  objChange = (theURbound[i] * currLhs) - (theLRbound[i] * oldRhs);
1089  }
1090  }
1091  else if( EQ(newRhs, currLhs) )
1092  {
1093  stat = SPxBasis::Desc::P_FIXED;
1094  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1095  objChange = maxRowObj(i) * (newRhs - oldRhs);
1096  }
1097  else if( m_nonbasicValueUpToDate && rep() == COLUMN )
1098  objChange = theLRbound[i] * (newRhs - oldRhs);
1099  break;
1101  if( EQ(newRhs, currLhs) )
1102  stat = SPxBasis::Desc::P_FIXED;
1103  break;
1105  if (newRhs < infinity)
1106  {
1108  if( m_nonbasicValueUpToDate && rep() == COLUMN )
1109  objChange = theLRbound[i] * newRhs;
1110  }
1111  break;
1113  if( NE(newRhs, currLhs) )
1114  {
1116  if( isInitialized() )
1117  theURbound[i] = maxRowObj(i);
1118  }
1119  break;
1125  if( rep() == ROW && theShift > 0.0 )
1127  stat = dualRowStatus(i);
1128  break;
1129  default:
1130  throw SPxInternalCodeException("XCHANG04 This should never happen.");
1131  }
1132  MSG_DEBUG( std::cout << " -> " << stat << std::endl; )
1133 
1134  // we only need to update the nonbasic value in column representation (see nonbasicValue() for comparison/explanation)
1135  if( rep() == COLUMN )
1136  updateNonbasicValue(objChange);
1137 }
1138 
1139 
1140 void SPxSolver::changeRhs(const Vector& newRhs, bool scale)
1141 {
1142  // we better recompute the nonbasic value when changing all rhs
1144 
1145  SPxLP::changeRhs(newRhs, scale);
1146 
1148  {
1149  for (int i = 0; i < nRows(); ++i)
1150  changeRhsStatus(i, rhs(i));
1151  unInit();
1152  }
1153 }
1154 
1155 void SPxSolver::changeRhs(int i, const Real& newRhs, bool scale)
1156 {
1157  if( newRhs != rhsUnscaled(i) )
1158  {
1159  Real oldRhs = rhs(i);
1160  SPxLP::changeRhs(i, newRhs, scale);
1161 
1163  {
1164  changeRhsStatus(i, rhs(i), oldRhs);
1165  unInit();
1166  }
1167  }
1168 }
1169 
1170 void SPxSolver::changeRange(const Vector& newLhs, const Vector& newRhs, bool scale)
1171 {
1172  // we better recompute the nonbasic value when changing all ranges
1174 
1175  SPxLP::changeLhs(newLhs, scale);
1176  SPxLP::changeRhs(newRhs, scale);
1178  {
1179  for (int i = nRows() - 1; i >= 0; --i)
1180  {
1181  changeLhsStatus(i, lhs(i));
1182  changeRhsStatus(i, rhs(i));
1183  }
1184  unInit();
1185  }
1186 }
1187 
1188 void SPxSolver::changeRange(int i, const Real& newLhs, const Real& newRhs, bool scale)
1189 {
1190  Real oldLhs = lhs(i);
1191  Real oldRhs = rhs(i);
1192 
1193  SPxLP::changeLhs(i, newLhs, scale);
1194  SPxLP::changeRhs(i, newRhs, scale);
1195 
1197  {
1198  changeLhsStatus(i, lhs(i), oldLhs);
1199  changeRhsStatus(i, rhs(i), oldRhs);
1200  unInit();
1201  }
1202 }
1203 
1204 void SPxSolver::changeRow(int i, const LPRow& newRow, bool scale)
1205 {
1207 
1208  SPxLP::changeRow(i, newRow, scale);
1210  SPxBasis::changedRow( i );
1211  unInit();
1212 }
1213 
1214 void SPxSolver::changeCol(int i, const LPCol& newCol, bool scale)
1215 {
1216  if( i < 0 )
1217  return;
1218 
1220 
1221  SPxLP::changeCol(i, newCol, scale);
1223  SPxBasis::changedCol( i );
1224  unInit();
1225 }
1226 
1227 void SPxSolver::changeElement(int i, int j, const Real& val, bool scale)
1228 {
1229  if( i < 0 || j < 0 )
1230  return;
1231 
1233 
1234  SPxLP::changeElement(i, j, val, scale);
1236  SPxBasis::changedElement( i, j );
1237  unInit();
1238 }
1239 
1241 {
1242 
1243  SPxLP::changeSense(sns);
1244  unInit();
1245 }
1246 } // 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:190
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:719
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:359
Abstract pricer base class.
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:770
void computeTest()
compute test vector in ENTERing Simplex.
Definition: enter.cpp:102
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:460
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:381
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:1555
void setLeaveBound4Col(int i, int n)
Definition: spxbounds.cpp:266
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:215
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:341
void localAddRows(int start)
virtual void doRemoveCols(int perm[])
#define MSG_DEBUG(x)
Definition: spxdefines.h:129
void shiftLPbound(int i, Real to)
shift i &#39;th lpBound to to.
Definition: spxsolver.h:1569
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:1825
Real entertol() const
feasibility tolerance maintained by ratio test during ENTER algorithm.
Definition: spxsolver.h:763
UpdateVector * thePvec
Definition: spxsolver.h:346
Real upperUnscaled(int i) const
Returns unscaled upper bound of column i.
virtual void changeSense(SPxSense sns)
SPxPricer * thepricer
Definition: spxsolver.h:380
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:339
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:910
Basis descriptor.
Definition: spxbasis.h:104
DVector theURbound
Upper Row Feasibility bound.
Definition: spxsolver.h:328
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:1503
void shiftUBbound(int i, Real to)
shift i &#39;th ubBound to to.
Definition: spxsolver.h:1548
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:338
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:375
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:329
DVector theUCbound
Upper Column Feasibility bound.
Definition: spxsolver.h:330
bool isInitialized() const
has the internal data been initialized?
Definition: spxsolver.h:1816
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:1562
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:342
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:331
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:344
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:475
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:633
void solve(Vector &x, const Vector &rhs)
Definition: spxbasis.h:631
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1129
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:345
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:235
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:469
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:2016
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