Scippy

SoPlex

Sequential object-oriented simPlex

spxsteeppr.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 //TODO may be faster to have a greater zero tolerance for sparse pricing vectors
17 // to reduce the number of nonzero entries, e.g. for workVec
18 
19 #include <assert.h>
20 #include <iostream>
21 
22 #include "spxdefines.h"
23 #include "spxsteeppr.h"
24 #include "random.h"
25 
26 #define STEEP_REFINETOL 2.0
27 
28 namespace soplex
29 {
30 
31 // #define EQ_PREF 1000
32 
34 {
35  thesolver = 0;
36 }
37 
39 {
40  thesolver = base;
41 
42  if (base)
43  {
44  workVec.clear();
45  workVec.reDim(base->dim());
46  workRhs.clear();
47  workRhs.reDim(base->dim());
48  }
49 }
50 
52 {
54 
55  setupWeights(type);
56  workVec.clear();
57  workRhs.clear();
58  refined = false;
59 
60  bestPrices.clear();
63 
64  if( type == SPxSolver::ENTER )
65  {
69  }
70 }
71 
73 {
74  int i;
75  int endDim = 0;
76  int endCoDim = 0;
77  DVector& weights = thesolver->weights;
78  DVector& coWeights = thesolver->coWeights;
79 
80  if( setup == DEFAULT )
81  {
82  if( type == SPxSolver::ENTER )
83  {
85  {
86  // check for added/removed rows and adapt norms accordingly
87  if (coWeights.dim() < thesolver->dim())
88  endDim = coWeights.dim();
89  else
90  endDim = thesolver->dim();
91  if (weights.dim() < thesolver->coDim())
92  endCoDim = weights.dim();
93  else
94  endCoDim = thesolver->coDim();
95  }
96 
97  coWeights.reDim(thesolver->dim(), false);
98  for (i = thesolver->dim() - 1; i >= endDim; --i)
99  coWeights[i] = 2.0;
100  weights.reDim(thesolver->coDim(), false);
101  for (i = thesolver->coDim() - 1; i >= endCoDim; --i)
102  weights[i] = 1.0;
103  }
104  else
105  {
106  assert(type == SPxSolver::LEAVE);
107 
109  {
110  // check for added/removed rows and adapt norms accordingly
111  if (coWeights.dim() < thesolver->dim())
112  endDim = coWeights.dim();
113  else
114  endDim = thesolver->dim();
115  }
116 
117  coWeights.reDim(thesolver->dim(), false);
118  for (i = thesolver->dim() - 1; i >= endDim; --i)
119  coWeights[i] = 1.0;
120  }
121  }
122  else
123  {
124  MSG_INFO1( (*thesolver->spxout), (*thesolver->spxout) << " --- initializing steepest edge multipliers" << std::endl; )
125 
126  if (type == SPxSolver::ENTER)
127  {
128  coWeights.reDim(thesolver->dim(), false);
129  for (i = thesolver->dim() - 1; i >= endDim; --i)
130  coWeights[i] = 1.0;
131  weights.reDim(thesolver->coDim(), false);
132  for (i = thesolver->coDim() - 1; i >= endCoDim; --i)
133  weights[i] = 1.0 + thesolver->vector(i).length2();
134  }
135  else
136  {
137  assert(type == SPxSolver::LEAVE);
138  coWeights.reDim(thesolver->dim(), false);
139  SSVector tmp(thesolver->dim(), thesolver->epsilon());
140  for( i = thesolver->dim() - 1; i >= endDim && !thesolver->isTimeLimitReached(); --i )
141  {
143  coWeights[i] = tmp.length2();
144  }
145  }
146  }
147  thesolver->weightsAreSetup = true;
148 }
149 
151 {
152  if (workVec.dim() != thesolver->dim())
153  {
154  DVector tmp = thesolver->weights;
156  thesolver->coWeights = tmp;
157 
158  workVec.clear();
160  }
161 }
162 
163 void SPxSteepPR::left4(int n, SPxId id)
164 {
165  assert(thesolver->type() == SPxSolver::LEAVE);
166 
167  if (id.isValid())
168  {
169  Real delta = 0.1 + 1.0 / thesolver->basis().iteration();
170  Real* coWeights_ptr = thesolver->coWeights.get_ptr();
171  const Real* workVec_ptr = workVec.get_const_ptr();
172  const Real* rhoVec = thesolver->fVec().delta().values();
173  Real rhov_1 = 1.0 / rhoVec[n];
174  Real beta_q = thesolver->coPvec().delta().length2() * rhov_1 * rhov_1;
175 
176 #ifndef NDEBUG
177  if (spxAbs(rhoVec[n]) < theeps * 0.5)
178  {
179  MSG_INFO3( (*thesolver->spxout), (*thesolver->spxout) << "WSTEEP04: rhoVec = "
180  << rhoVec[n] << " with smaller absolute value than 0.5*theeps = " << 0.5*theeps << std::endl; )
181  }
182 #endif
183 
184  const IdxSet& rhoIdx = thesolver->fVec().idx();
185  int len = thesolver->fVec().idx().size();
186 
187  for(int i = 0; i < len; ++i)
188  {
189  int j = rhoIdx.index(i);
190  coWeights_ptr[j] += rhoVec[j] * (beta_q * rhoVec[j] - 2.0 * rhov_1 * workVec_ptr[j]);
191 
192  if (coWeights_ptr[j] < delta)
193  coWeights_ptr[j] = delta; // coWeights_ptr[j] = delta / (1+delta-x);
194  else if (coWeights_ptr[j] >= infinity)
195  coWeights_ptr[j] = 1.0 / theeps;
196  }
197  coWeights_ptr[n] = beta_q;
198  }
199 }
200 
201 Real inline computePrice(Real viol, Real weight, Real tol)
202 {
203  if( weight < tol )
204  return viol * viol / tol;
205  else
206  return viol * viol / weight;
207 }
208 
210 {
211  int idx;
212  int nsorted;
213  Real x;
214  const Real* fTest = thesolver->fTest().get_const_ptr();
215  const Real* cpen = thesolver->coWeights.get_const_ptr();
216  IdxElement price;
217  prices.clear();
218  bestPrices.clear();
219 
220  // construct vector of all prices
221  for (int i = thesolver->infeasibilities.size() - 1; i >= 0; --i)
222  {
223  idx = thesolver->infeasibilities.index(i);
224  x = fTest[idx];
225  if (x < -feastol)
226  {
227  // it might happen that we call the pricer with a tighter tolerance than what was used when computing the violations
229  price.val = computePrice(x, cpen[idx], feastol);
230  price.idx = idx;
231  prices.append(price);
232  }
233  }
234  // set up structures for the quicksort implementation
236  // do a partial sort to move the best ones to the front
237  // TODO this can be done more efficiently, since we only need the indices
239  // copy indices of best values to bestPrices
240  for( int i = 0; i < nsorted; ++i )
241  {
242  bestPrices.addIdx(prices[i].idx);
244  }
245 
246  if( nsorted > 0 )
247  return prices[0].idx;
248  else
249  return -1;
250 }
251 
252 
254 {
255  assert(isConsistent());
256 
257  int retid;
258 
260  {
261  if ( bestPrices.size() < 2 || thesolver->basis().lastUpdate() == 0 )
262  {
263  // call init method to build up price-vector and return index of largest price
265  }
266  else
267  retid = selectLeaveHyper(theeps);
268  }
269  else if (thesolver->sparsePricingLeave)
270  retid = selectLeaveSparse(theeps);
271  else
272  retid = selectLeaveX(theeps);
273 
274  if( retid < 0 && !refined )
275  {
276  refined = true;
277  MSG_INFO3( (*thesolver->spxout), (*thesolver->spxout) << "WSTEEP03 trying refinement step..\n"; )
279  }
280 
281  if( retid >= 0 )
282  {
283  assert( thesolver->coPvec().delta().isConsistent() );
284  // coPvec().delta() might be not setup after the solve when it contains too many nonzeros.
285  // This is intended and forcing to keep the sparsity information leads to a slowdown
286  // TODO implement a dedicated solve method for unitvectors
288  thesolver->unitVector(retid));
289  assert( thesolver->coPvec().delta().isConsistent() );
292  }
293 
294  return retid;
295 }
296 
298 {
299  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
300  const Real* fTest = thesolver->fTest().get_const_ptr();
301  Real best = -infinity;
302  Real x;
303  int lastIdx = -1;
304 
305  for (int i = thesolver->dim() - 1; i >= 0; --i)
306  {
307  x = fTest[i];
308 
309  if (x < -tol)
310  {
311  x = computePrice(x, coWeights_ptr[i], tol);
312 
313  if (x > best)
314  {
315  best = x;
316  lastIdx = i;
317  }
318  }
319  }
320 
321  return lastIdx;
322 }
323 
325 {
326  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
327  const Real* fTest = thesolver->fTest().get_const_ptr();
328  Real best = -infinity;
329  Real x;
330  int lastIdx = -1;
331  int idx;
332 
333  for (int i = thesolver->infeasibilities.size() - 1; i >= 0; --i)
334  {
335  idx = thesolver->infeasibilities.index(i);
336  x = fTest[idx];
337 
338  if (x < -tol)
339  {
340  x = computePrice(x, coWeights_ptr[idx], tol);
341 
342  if (x > best)
343  {
344  best = x;
345  lastIdx = idx;
346  }
347  }
348  else
349  {
353  }
354  }
355 
356  return lastIdx;
357 }
358 
360 {
361  const Real* coPen = thesolver->coWeights.get_const_ptr();
362  const Real* fTest = thesolver->fTest().get_const_ptr();
363  Real leastBest = infinity;
364  Real best = -infinity;
365  Real x;
366  int bestIdx = -1;
367  int idx = 0;
368 
369  // find the best price from the short candidate list
370  for( int i = bestPrices.size() - 1; i >= 0; --i )
371  {
372  idx = bestPrices.index(i);
373  x = fTest[idx];
374  if( x < -tol )
375  {
377  x = computePrice(x, coPen[idx], tol);
378 
379  if( x > best )
380  {
381  best = x;
382  bestIdx = idx;
383  }
384  if( x < leastBest )
385  leastBest = x;
386  }
387  else
388  {
389  bestPrices.remove(i);
391  }
392  }
393 
394  // make sure we do not skip potential candidates due to a high leastBest value
395  if( leastBest == infinity )
396  {
397  assert(bestPrices.size() == 0);
398  leastBest = 0;
399  }
400 
401  // scan the updated indices for a better price
402  for( int i = thesolver->updateViols.size() - 1; i >= 0; --i )
403  {
404  idx = thesolver->updateViols.index(i);
405  // is this index a candidate for bestPrices?
406  if( thesolver->isInfeasible[idx] == VIOLATED )
407  {
408  x = fTest[idx];
409  assert(x < -tol);
410  x = computePrice(x, coPen[idx], tol);
411 
412  if( x > leastBest )
413  {
414  if( x > best )
415  {
416  best = x;
417  bestIdx = idx;
418  }
420  bestPrices.addIdx(idx);
421  }
422  }
423  }
424 
425  return bestIdx;
426 }
427 
428 /* Entering Simplex
429  */
430 void SPxSteepPR::entered4(SPxId /* id */, int n)
431 {
432  assert(thesolver->type() == SPxSolver::ENTER);
433 
434  if (n >= 0 && n < thesolver->dim())
435  {
436  Real delta = 2 + 1.0 / thesolver->basis().iteration();
437  Real* coWeights_ptr = thesolver->coWeights.get_ptr();
438  Real* weights_ptr = thesolver->weights.get_ptr();
439  const Real* workVec_ptr = workVec.get_const_ptr();
440  const Real* pVec = thesolver->pVec().delta().values();
441  const IdxSet& pIdx = thesolver->pVec().idx();
442  const Real* coPvec = thesolver->coPvec().delta().values();
443  const IdxSet& coPidx = thesolver->coPvec().idx();
444  Real xi_p = 1 / thesolver->fVec().delta()[n];
445  int i, j;
446  Real xi_ip;
447 
448  assert(thesolver->fVec().delta()[n] > thesolver->epsilon()
449  || thesolver->fVec().delta()[n] < -thesolver->epsilon());
450 
451  for (j = coPidx.size() - 1; j >= 0; --j)
452  {
453  i = coPidx.index(j);
454  xi_ip = xi_p * coPvec[i];
455  coWeights_ptr[i] += xi_ip * (xi_ip * pi_p - 2.0 * workVec_ptr[i]);
456  /*
457  if(coWeights_ptr[i] < 1)
458  coWeights_ptr[i] = 1 / (2-x);
459  */
460  if (coWeights_ptr[i] < delta)
461  coWeights_ptr[i] = delta;
462  // coWeights_ptr[i] = 1;
463  else if (coWeights_ptr[i] > infinity)
464  coWeights_ptr[i] = 1 / thesolver->epsilon();
465  }
466 
467  for (j = pIdx.size() - 1; j >= 0; --j)
468  {
469  i = pIdx.index(j);
470  xi_ip = xi_p * pVec[i];
471  weights_ptr[i] += xi_ip * (xi_ip * pi_p - 2.0 * (thesolver->vector(i) * workVec));
472  /*
473  if(weights_ptr[i] < 1)
474  weights_ptr[i] = 1 / (2-x);
475  */
476  if (weights_ptr[i] < delta)
477  weights_ptr[i] = delta;
478  // weights_ptr[i] = 1;
479  else if (weights_ptr[i] > infinity)
480  weights_ptr[i] = 1.0 / thesolver->epsilon();
481  }
482  }
483 
484  /*@
485  if(thesolver->isId(id))
486  weights[ thesolver->number(id) ] *= 1.0001;
487  else if(thesolver->isCoId(id))
488  coWeights[ thesolver->number(id) ] *= 1.0001;
489  */
490 
491 }
492 
493 
495 {
496  const Real* coTest = thesolver->coTest().get_const_ptr();
497  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
498  int idx;
499  int nsorted;
500  Real x;
501  IdxElement price;
502 
503  prices.clear();
504  bestPrices.clear();
505 
506  // construct vector of all prices
507  for( int i = thesolver->infeasibilities.size() - 1; i >= 0; --i )
508  {
509  idx = thesolver->infeasibilities.index(i);
510  x = coTest[idx];
511  if ( x < -feastol)
512  {
513  // it might happen that we call the pricer with a tighter tolerance than what was used when computing the violations
515  price.val = computePrice(x, coWeights_ptr[idx], feastol);
516  price.idx = idx;
517  prices.append(price);
518  }
519  else
520  {
523  }
524  }
525  // set up structures for the quicksort implementation
527  // do a partial sort to move the best ones to the front
528  // TODO this can be done more efficiently, since we only need the indices
530  // copy indices of best values to bestPrices
531  for( int i = 0; i < nsorted; ++i )
532  {
533  bestPrices.addIdx(prices[i].idx);
535  }
536 
537  if( nsorted > 0 )
538  {
539  best = prices[0].val;
540  return thesolver->coId(prices[0].idx);
541  }
542  else
543  return SPxId();
544 }
545 
546 
548 {
549  const Real* test = thesolver->test().get_const_ptr();
550  const Real* weights_ptr = thesolver->weights.get_const_ptr();
551  int idx;
552  int nsorted;
553  Real x;
554  IdxElement price;
555 
556  pricesCo.clear();
558 
559  // construct vector of all prices
560  for( int i = thesolver->infeasibilitiesCo.size() - 1; i >= 0; --i )
561  {
563  x = test[idx];
564  if ( x < -feastol)
565  {
566  // it might happen that we call the pricer with a tighter tolerance than what was used when computing the violations
568  price.val = computePrice(x, weights_ptr[idx], feastol);
569  price.idx = idx;
570  pricesCo.append(price);
571  }
572  else
573  {
576  }
577  }
578  // set up structures for the quicksort implementation
580  // do a partial sort to move the best ones to the front
581  // TODO this can be done more efficiently, since we only need the indices
583  // copy indices of best values to bestPrices
584  for( int i = 0; i < nsorted; ++i )
585  {
586  bestPricesCo.addIdx(pricesCo[i].idx);
588  }
589 
590  if( nsorted > 0 )
591  {
592  best = pricesCo[0].val;
593  return thesolver->id(pricesCo[0].idx);
594  }
595  else
596  return SPxId();
597 }
598 
599 
601 {
602  assert(thesolver != 0);
603  SPxId enterId;
604 
605  enterId = selectEnterX(theeps);
606 
607  if( !enterId.isValid() && !refined )
608  {
609  refined = true;
610  MSG_INFO3( (*thesolver->spxout), (*thesolver->spxout) << "WSTEEP05 trying refinement step..\n"; )
612  }
613 
614  assert(isConsistent());
615 
616  if (enterId.isValid())
617  {
618  SSVector& delta = thesolver->fVec().delta();
619 
620  thesolver->basis().solve4update(delta, thesolver->vector(enterId));
621 
622  workRhs.setup_and_assign(delta);
623  pi_p = 1 + delta.length2();
624 
626  }
627  return enterId;
628 }
629 
631 {
632  SPxId enterId;
633  SPxId enterCoId;
634  Real best;
635  Real bestCo;
636 
637  best = -infinity;
638  bestCo = -infinity;
639 
641  {
642  if( bestPrices.size() < 2 || thesolver->basis().lastUpdate() == 0 )
643  enterCoId = (thesolver->sparsePricingEnter) ? buildBestPriceVectorEnterDim(best, tol) : selectEnterDenseDim(best, tol);
644  else
645  enterCoId = (thesolver->sparsePricingEnter) ? selectEnterHyperDim(best, tol) : selectEnterDenseDim(best, tol);
646 
647  if( bestPricesCo.size() < 2 || thesolver->basis().lastUpdate() == 0 )
648  enterId = (thesolver->sparsePricingEnterCo) ? buildBestPriceVectorEnterCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
649  else
650  enterId = (thesolver->sparsePricingEnterCo) ? selectEnterHyperCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
651  }
652  else
653  {
654  enterCoId = (thesolver->sparsePricingEnter && !refined) ? selectEnterSparseDim(best, tol) : selectEnterDenseDim(best, tol);
655  enterId = (thesolver->sparsePricingEnterCo && !refined) ? selectEnterSparseCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
656  }
657 
658  // prefer slack indices to reduce nonzeros in basis matrix
659  if( enterCoId.isValid() && (best > SPARSITY_TRADEOFF * bestCo || !enterId.isValid()) )
660  return enterCoId;
661  else
662  return enterId;
663 }
664 
665 
667 {
668  const Real* coTest = thesolver->coTest().get_const_ptr();
669  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
670 
671  Real leastBest = infinity;
672  Real x;
673  int enterIdx = -1;
674  int idx;
675 
676  // find the best price from short candidate list
677  for( int i = bestPrices.size() - 1; i >= 0; --i )
678  {
679  idx = bestPrices.index(i);
680  x = coTest[idx];
681  if( x < -tol )
682  {
683  x = computePrice(x, coWeights_ptr[idx], tol);
684  if( x > best )
685  {
686  best = x;
687  enterIdx = idx;
688  }
689  if( x < leastBest )
690  leastBest = x;
691  }
692  else
693  {
694  bestPrices.remove(i);
696  }
697  }
698 
699  // make sure we do not skip potential candidates due to a high leastBest value
700  if( leastBest == infinity )
701  {
702  assert(bestPrices.size() == 0);
703  leastBest = 0;
704  }
705 
706  // scan the updated indices for a better price
707  for( int i = thesolver->updateViols.size() -1; i >= 0; --i )
708  {
709  idx = thesolver->updateViols.index(i);
710  // only look at indices that were not checked already
711  if( thesolver->isInfeasible[idx] == VIOLATED )
712  {
713  x = coTest[idx];
714  if( x < -tol )
715  {
716  x = computePrice(x, coWeights_ptr[idx], tol);
717  if( x > leastBest )
718  {
719  if (x > best)
720  {
721  best = x;
722  enterIdx = idx;
723  }
724  // put index into candidate list
726  bestPrices.addIdx(idx);
727  }
728  }
729  else
730  {
732  }
733  }
734  }
735 
736  if( enterIdx >= 0 )
737  return thesolver->coId(enterIdx);
738  else
739  return SPxId();
740 }
741 
742 
744 {
745  const Real* test = thesolver->test().get_const_ptr();
746  const Real* weights_ptr = thesolver->weights.get_const_ptr();
747 
748  Real leastBest = infinity;
749  Real x;
750  int enterIdx = -1;
751  int idx;
752 
753  // find the best price from short candidate list
754  for( int i = bestPricesCo.size() - 1; i >= 0; --i )
755  {
756  idx = bestPricesCo.index(i);
757  x = test[idx];
758  if( x < -tol )
759  {
760  x = computePrice(x, weights_ptr[idx], tol);
761  if( x > best )
762  {
763  best = x;
764  enterIdx = idx;
765  }
766  if( x < leastBest )
767  leastBest = x;
768  }
769  else
770  {
771  bestPricesCo.remove(i);
773  }
774  }
775 
776  // make sure we do not skip potential candidates due to a high leastBest value
777  if( leastBest == infinity )
778  {
779  assert(bestPricesCo.size() == 0);
780  leastBest = 0;
781  }
782 
783  // scan the updated indices for a better price
784  for( int i = thesolver->updateViolsCo.size() -1; i >= 0; --i )
785  {
786  idx = thesolver->updateViolsCo.index(i);
787  // only look at indices that were not checked already
788  if( thesolver->isInfeasibleCo[idx] == VIOLATED )
789  {
790  x = test[idx];
791  if( x < -tol )
792  {
793  x = computePrice(x, weights_ptr[idx], tol);
794  if( x > leastBest )
795  {
796  if (x > best)
797  {
798  best = x;
799  enterIdx = idx;
800  }
801  // put index into candidate list
803  bestPricesCo.addIdx(idx);
804  }
805  }
806  else
807  {
809  }
810  }
811  }
812 
813  if( enterIdx >= 0 )
814  return thesolver->id(enterIdx);
815  else
816  return SPxId();
817 }
818 
819 
821 {
822  SPxId enterId;
823  const Real* coTest = thesolver->coTest().get_const_ptr();
824  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
825 
826  int idx;
827  Real x;
828 
829  for (int i = thesolver->infeasibilities.size() -1; i >= 0; --i)
830  {
831  idx = thesolver->infeasibilities.index(i);
832  x = coTest[idx];
833 
834  if (x < -tol)
835  {
836  x = computePrice(x, coWeights_ptr[idx], tol);
837  if (x > best)
838  {
839  best = x;
840  enterId = thesolver->coId(idx);
841  }
842  }
843  else
844  {
847  }
848  }
849  return enterId;
850 }
851 
853 {
854  SPxId enterId;
855  const Real* test = thesolver->test().get_const_ptr();
856  const Real* weights_ptr = thesolver->weights.get_const_ptr();
857 
858  int idx;
859  Real x;
860 
861  for (int i = thesolver->infeasibilitiesCo.size() -1; i >= 0; --i)
862  {
864  x = test[idx];
865 
866  if (x < -tol)
867  {
868  x = computePrice(x, weights_ptr[idx], tol);
869  if (x > best)
870  {
871  best = x;
872  enterId = thesolver->id(idx);
873  }
874  }
875  else
876  {
879  }
880  }
881  return enterId;
882 }
883 
885 {
886  SPxId enterId;
887  const Real* coTest = thesolver->coTest().get_const_ptr();
888  const Real* coWeights_ptr = thesolver->coWeights.get_const_ptr();
889 
890  Real x;
891 
892  for (int i = 0, end = thesolver->dim(); i < end; ++i)
893  {
894  x = coTest[i];
895  if (x < -tol)
896  {
897  x = computePrice(x, coWeights_ptr[i], tol);
898  if (x > best)
899  {
900  best = x;
901  enterId = thesolver->coId(i);
902  }
903  }
904  }
905  return enterId;
906 }
907 
909 {
910  SPxId enterId;
911  const Real* test = thesolver->test().get_const_ptr();
912  const Real* weights_ptr = thesolver->weights.get_const_ptr();
913 
914  Real x;
915 
916  for(int i = 0, end = thesolver->coDim(); i < end; ++i)
917  {
918  x = test[i];
919  if (x < -tol)
920  {
921  x = computePrice(x, weights_ptr[i], tol);
922  if (x > best)
923  {
924  best = x;
925  enterId = thesolver->id(i);
926  }
927  }
928  }
929  return enterId;
930 }
931 
932 
934 {
935  DVector& weights = thesolver->weights;
936  n = weights.dim();
937  weights.reDim(thesolver->coDim());
938 
939  if (thesolver->type() == SPxSolver::ENTER)
940  {
941  for (; n < weights.dim(); ++n)
942  weights[n] = 2;
943  }
944 }
945 
947 {
948  DVector& coWeights = thesolver->coWeights;
949  n = coWeights.dim();
950  workVec.reDim (thesolver->dim());
951  coWeights.reDim (thesolver->dim());
952  for (; n < coWeights.dim(); ++n)
953  coWeights[n] = 1;
954 }
955 
957 {
958  assert(thesolver != 0);
959  DVector& weights = thesolver->weights;
960  weights[i] = weights[weights.dim()];
961  weights.reDim(thesolver->coDim());
962 }
963 
964 void SPxSteepPR::removedVecs(const int perm[])
965 {
966  assert(thesolver != 0);
967  DVector& weights = thesolver->weights;
968  if (thesolver->type() == SPxSolver::ENTER)
969  {
970  int i;
971  int j = weights.dim();
972  for (i = 0; i < j; ++i)
973  {
974  if (perm[i] >= 0)
975  weights[perm[i]] = weights[i];
976  }
977  }
978  weights.reDim(thesolver->coDim());
979 }
980 
982 {
983  assert(thesolver != 0);
984  DVector& coWeights = thesolver->coWeights;
985  coWeights[i] = coWeights[coWeights.dim()];
986  coWeights.reDim(thesolver->dim());
987 }
988 
989 void SPxSteepPR::removedCoVecs(const int perm[])
990 {
991  assert(thesolver != 0);
992  DVector& coWeights = thesolver->coWeights;
993  int i;
994  int j = coWeights.dim();
995  for (i = 0; i < j; ++i)
996  {
997  if (perm[i] >= 0)
998  coWeights[perm[i]] = coWeights[i];
999  }
1000  coWeights.reDim(thesolver->dim());
1001 }
1002 
1004 {
1005 #ifdef ENABLE_CONSISTENCY_CHECKS
1006  DVector& w = thesolver->weights;
1007  DVector& coW = thesolver->coWeights;
1008  if (thesolver != 0 && thesolver->type() == SPxSolver::LEAVE && setup == EXACT)
1009  {
1010  int i;
1011  SSVector tmp(thesolver->dim(), thesolver->epsilon());
1012  Real x;
1013  for (i = thesolver->dim() - 1; i >= 0; --i)
1014  {
1016  x = coW[i] - tmp.length2();
1017  if (x > thesolver->leavetol() || -x > thesolver->leavetol())
1018  {
1019  MSG_ERROR( std::cerr << "ESTEEP03 x[" << i << "] = " << x << std::endl; )
1020  }
1021  }
1022  }
1023 
1024  if (thesolver != 0 && thesolver->type() == SPxSolver::ENTER)
1025  {
1026  int i;
1027  for (i = thesolver->dim() - 1; i >= 0; --i)
1028  {
1029  if (coW[i] < thesolver->epsilon())
1030  return MSGinconsistent("SPxSteepPR");
1031  }
1032 
1033  for (i = thesolver->coDim() - 1; i >= 0; --i)
1034  {
1035  if (w[i] < thesolver->epsilon())
1036  return MSGinconsistent("SPxSteepPR");
1037  }
1038  }
1039 #endif
1040 
1041  return true;
1042 }
1043 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3909
Random numbers.
SPxId coId(int i) const
id of i &#39;th covector.
Definition: spxsolver.h:1098
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:545
virtual SPxId selectEnter()
Definition: spxsteeppr.cpp:600
void reDim(int newdim, const bool setZero=true)
Resets DVectorBase&#39;s dimension to newdim.
Definition: dvectorbase.h:249
int selectLeaveX(Real tol)
implementation of full pricing
Definition: spxsteeppr.cpp:297
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:719
SPxId selectEnterHyperCoDim(Real &best, Real feastol)
implementation of hyper sparse pricing in the entering Simplex
Definition: spxsteeppr.cpp:743
int buildBestPriceVectorLeave(Real feastol)
prepare data structures for hyper sparse pricing
Definition: spxsteeppr.cpp:209
const Vector & fTest() const
Violations of fVec.
Definition: spxsolver.h:1366
virtual void setType(SPxSolver::Type)
set entering/leaving algorithm
Definition: spxsteeppr.cpp:51
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:410
SPxOut * spxout
message handler
Definition: spxsolver.h:436
bool sparsePricingLeave
These values enable or disable sparse pricing.
Definition: spxsolver.h:421
THREADLOCAL const Real infinity
Definition: spxdefines.cpp:26
#define STEEP_REFINETOL
Definition: spxsteeppr.cpp:26
Type
Algorithmic type.
Definition: spxsolver.h:124
R length2() const
Squared norm.
Definition: vectorbase.h:403
DIdxSet bestPrices
array of best pricing candidates
Definition: spxsteeppr.h:75
T * get_ptr()
get a C pointer to the data.
Definition: dataarray.h:110
virtual void load(SPxSolver *base)
sets the solver
Definition: spxsteeppr.cpp:38
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:779
Representation
LP basis representation.
Definition: spxsolver.h:105
bool sparsePricingEnterCo
true if sparsePricing is turned on in the entering Simplex
Definition: spxsolver.h:423
Real computePrice(Real viol, Real weight, Real tol)
Definition: spxdevexpr.cpp:104
DataArray< int > isInfeasible
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:417
DataArray< IdxElement > prices
temporary array of precomputed pricing values
Definition: spxsteeppr.h:71
starting with multipliers set to 1
Definition: spxsteeppr.h:55
void clear()
removes all indices.
Definition: idxset.h:184
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:539
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:1056
void setup4solve(SSVector *p_y, SSVector *p_rhs)
Setup vectors to be solved within Simplex loop.
Definition: spxsolver.h:1669
void clear()
remove all elements.
Definition: dataarray.h:205
virtual int selectLeave()
Definition: spxsteeppr.cpp:253
virtual void addedCoVecs(int n)
n covectors have been added to loaded LP.
Definition: spxsteeppr.cpp:946
SSVector workVec
working vector
Definition: spxsteeppr.h:67
bool isTimeLimitReached(const bool forceCheck=false)
returns whether current time limit is reached; call to time() may be skipped unless forceCheck is tru...
Definition: spxsolver.cpp:1581
const R * get_const_ptr() const
Conversion to C-style pointer.
Definition: vectorbase.h:453
Steepest edge pricer.
int dim() const
Dimension of VectorBase.
Definition: ssvectorbase.h:560
Entering Simplex.
Definition: spxsolver.h:134
Generic Ids for LP rows or columns.Both SPxColIds and SPxRowIds may be treated uniformly as SPxIds: ...
Definition: spxid.h:85
UpdateVector & coPvec() const
copricing vector.
Definition: spxsolver.h:1379
void remove(int n, int m)
removes indices at position numbers n through m.
Definition: idxset.cpp:49
R * get_ptr()
Conversion to C-style pointer.
Definition: vectorbase.h:444
Leaving Simplex.
Definition: spxsolver.h:143
double Real
Definition: spxdefines.h:218
SPxId selectEnterX(Real tol)
choose the best entering index among columns and rows but prefer sparsity
Definition: spxsteeppr.cpp:630
const R * values() const
Returns array values.
Definition: ssvectorbase.h:299
bool refined
has a refinement step already been tried?
Definition: spxsteeppr.h:83
#define HYPERPRICINGSIZE
Definition: spxsolver.h:38
virtual void setRep(SPxSolver::Representation rep)
set row/column representation
Definition: spxsteeppr.cpp:150
virtual void entered4(SPxId id, int n)
Definition: spxsteeppr.cpp:430
virtual bool isConsistent() const
int size() const
returns the number of used indices.
Definition: idxset.h:124
virtual void left4(int n, SPxId id)
Definition: spxsteeppr.cpp:163
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:114
void append(const T &t)
append element t.
Definition: dataarray.h:121
SPxId id(int i) const
id of i &#39;th vector.
Definition: spxsolver.h:1079
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1304
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
DVector coWeights
store dual norms
Definition: spxsolver.h:433
virtual void addedVecs(int n)
n vectors have been added to loaded LP.
Definition: spxsteeppr.cpp:933
SPxSolver * thesolver
the solver
Definition: spxpricer.h:56
void clear()
Clears vector.
Definition: ssvectorbase.h:600
starting with exactly computed values
Definition: spxsteeppr.h:54
DataArray< IdxElement > pricesCo
temporary array of precomputed pricing values
Definition: spxsteeppr.h:73
void setEpsilon(R eps)
Changes the non-zero epsilon, invalidating the setup. */.
Definition: ssvectorbase.h:110
bool isConsistent() const
consistency check.
Definition: ssvectorbase.h:617
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:422
DIdxSet bestPricesCo
array of best pricing candidates
Definition: spxsteeppr.h:77
void setup4coSolve(SSVector *p_y, SSVector *p_rhs)
Setup vectors to be cosolved within Simplex loop.
Definition: spxsolver.h:1697
SPxId selectEnterSparseCoDim(Real &best, Real tol)
implementation of sparse pricing for the entering Simplex
Definition: spxsteeppr.cpp:852
const Vector & test() const
Violations of pVec.
Definition: spxsolver.h:1512
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:122
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:767
SPxId selectEnterHyperDim(Real &best, Real feastol)
implementation of hyper sparse pricing in the entering Simplex
Definition: spxsteeppr.cpp:666
void reDim(int newdim)
Resets dimension to newdim.
Definition: ssvectorbase.h:566
Debugging, floating point type and parameter definitions.
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1459
int selectLeaveHyper(Real tol)
implementation of hyper sparse pricing in the leaving Simplex
Definition: spxsteeppr.cpp:359
DIdxSet infeasibilities
Definition: spxsolver.h:404
R length2() const
Squared euclidian norm.
Definition: ssvectorbase.h:532
int dim() const
Dimension of vector.
Definition: vectorbase.h:215
void setup_and_assign(SSVectorBase< S > &rhs)
Sets up rhs vector, and assigns it.
Definition: ssvectorbase.h:718
Everything should be within this namespace.
void setupWeights(SPxSolver::Type type)
setup steepest edge weights
Definition: spxsteeppr.cpp:72
const IdxSet & idx() const
nonzero indices of update vector
Definition: updatevector.h:133
IdxCompare compare
Definition: spxpricer.h:88
void solve4update(SSVector &x, const SVector &rhs)
solves linear system with basis matrix.
Definition: spxbasis.h:664
int selectLeaveSparse(Real tol)
implementation of sparse pricing in the leaving Simplex
Definition: spxsteeppr.cpp:324
SPxId buildBestPriceVectorEnterDim(Real &best, Real feastol)
build up vector of pricing values for later use
Definition: spxsteeppr.cpp:494
#define SPARSITY_TRADEOFF
Definition: spxsolver.h:41
int SPxQuicksortPart(T *keys, COMPARATOR &compare, int start, int end, int size, int start2=0, int end2=0, bool type=true)
Generic implementation of Partial QuickSort.
Definition: sorter.h:219
Real theeps
violation bound
Definition: spxpricer.h:58
const Vector & coTest() const
violations of coPvec.
Definition: spxsolver.h:1446
virtual void clear()
clear solver and preferences
Definition: spxsteeppr.cpp:33
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:150
int size() const
return nr. of elements.
Definition: dataarray.h:211
Type type() const
return current Type.
Definition: spxsolver.h:484
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:418
virtual void removedVec(int i)
the i&#39;th vector has been removed from the loaded LP.
Definition: spxsteeppr.cpp:956
int coDim() const
codimension.
Definition: spxsolver.h:1061
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:425
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:118
virtual void removedCoVec(int i)
the i&#39;th covector has been removed from the loaded LP.
Definition: spxsteeppr.cpp:981
DVector weights
dual pricing norms
Definition: spxsolver.h:432
Setup setup
setup type.
Definition: spxsteeppr.h:81
#define MSGinconsistent(name)
Definition: spxdefines.h:126
bool weightsAreSetup
are the dual norms already set up?
Definition: spxsolver.h:434
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1138
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
DIdxSet updateViolsCo
Definition: spxsolver.h:411
SPxId selectEnterDenseCoDim(Real &best, Real tol)
implementation of selectEnter() in dense case
Definition: spxsteeppr.cpp:908
void reMax(int newMax=1, int newSize=-1)
reset maximum number of elements.
Definition: dataarray.h:254
SSVector workRhs
working vector
Definition: spxsteeppr.h:69
int index(int n) const
access n &#39;th index.
Definition: idxset.h:118
void setMax(int newmax=1)
sets the maximum number of indices.
Definition: didxset.cpp:22
SPxId buildBestPriceVectorEnterCoDim(Real &best, Real feastol)
Definition: spxsteeppr.cpp:547
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1736
virtual void removedCoVecs(const int perm[])
n covectors have been removed from loaded LP.
Definition: spxsteeppr.cpp:989
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:407
bool hyperPricingLeave
true if hyper sparse pricing is turned on in the leaving Simplex
Definition: spxsolver.h:424
const IdxElement * elements
Definition: spxpricer.h:77
SPxId selectEnterDenseDim(Real &best, Real tol)
implementation of selectEnter() in dense case (slack variables)
Definition: spxsteeppr.cpp:884
Set of indices.Class IdxSet provides a set of indices. At construction it must be given an array of i...
Definition: idxset.h:56
R length2() const
Squared norm.
Definition: svectorbase.h:503
const SVector & unitVector(int i) const
return i &#39;th unit vector.
Definition: spxsolver.h:1217
SPxId selectEnterSparseDim(Real &best, Real tol)
implementation of sparse pricing for the entering Simplex (slack variables)
Definition: spxsteeppr.cpp:820
virtual void removedVecs(const int perm[])
n vectors have been removed from loaded LP.
Definition: spxsteeppr.cpp:964