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