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-2016 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 //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  prefSetup = 0;
37  weightsAreSetup = false;
38 }
39 
41 {
42  thesolver = base;
43 
44  if (base)
45  {
46  workVec.clear();
47  workVec.reDim(base->dim());
48  workRhs.clear();
49  workRhs.reDim(base->dim());
50 
51  leavePref.reSize(base->dim());
52  coPref.reSize (base->dim());
53  pref.reSize (base->coDim());
54  prefSetup = 0;
55  }
56 }
57 
59 {
61 
64  setupPrefs(type);
65  setupWeights(type);
66  workVec.clear();
67  workRhs.clear();
68  refined = false;
70  {
72  {
73  bestPrices.clear();
76  }
78  {
82  }
83  }
85  {
86  bestPrices.clear();
89  }
90 }
91 
93 {
94  int i;
95  int endDim = 0;
96  int endCoDim = 0;
97 
98  if( setup == DEFAULT )
99  {
100  if( type == SPxSolver::ENTER )
101  {
102  if( weightsAreSetup )
103  {
104  // check for added/removed rows and adapt norms accordingly
105  if (coWeights.dim() < thesolver->dim())
106  endDim = coWeights.dim();
107  else
108  endDim = thesolver->dim();
109  if (weights.dim() < thesolver->coDim())
110  endCoDim = weights.dim();
111  else
112  endCoDim = thesolver->coDim();
113  }
114 
115  coWeights.reDim(thesolver->dim(), false);
116  for (i = thesolver->dim() - 1; i >= endDim; --i)
117  coWeights[i] = 2;
118  weights.reDim(thesolver->coDim(), false);
119  for (i = thesolver->coDim() - 1; i >= endCoDim; --i)
120  weights[i] = 1;
121  }
122  else
123  {
124  assert(type == SPxSolver::LEAVE);
125 
126  if( weightsAreSetup )
127  {
128  // check for added/removed rows and adapt norms accordingly
129  if (coWeights.dim() < thesolver->dim())
130  endDim = coWeights.dim();
131  else
132  endDim = thesolver->dim();
133  }
134 
135  coWeights.reDim(thesolver->dim(), false);
136  for (i = thesolver->dim() - 1; i >= endDim; --i)
137  {
138  const SPxId id = thesolver->basis().baseId(i);
139  const int n = thesolver->number(id);
140  assert(n >= 0);
141  leavePref[i] = thesolver->isId(id) ? pref[n] : coPref[n];
142  coWeights[i] = 1.0;
143  }
144  }
145  }
146  else
147  {
148  MSG_INFO1( (*thesolver->spxout), (*thesolver->spxout) << " --- initializing steepest edge multipliers" << std::endl; )
149 
150  if (type == SPxSolver::ENTER)
151  {
152  coWeights.reDim(thesolver->dim(), false);
153  for (i = thesolver->dim() - 1; i >= endDim; --i)
154  coWeights[i] = 1;
155  weights.reDim(thesolver->coDim(), false);
156  for (i = thesolver->coDim() - 1; i >= endCoDim; --i)
157  weights[i] = 1 + thesolver->vector(i).length2();
158  }
159  else
160  {
161  assert(type == SPxSolver::LEAVE);
162  coWeights.reDim(thesolver->dim(), false);
163  SSVector tmp(thesolver->dim(), thesolver->epsilon());
164  for (i = thesolver->dim() - 1; i >= endDim; --i)
165  {
166  const SPxId id = thesolver->basis().baseId(i);
167  const int n = thesolver->number(id);
168  assert(n >= 0);
169  leavePref[i] = thesolver->isId(id) ? pref[n] : coPref[n];
171  coWeights[i] = tmp.length2();
172  }
173  }
174  }
175  weightsAreSetup = true;
176 }
177 
179  Real mult,
180  Real /*tie*/,
181  Real /*cotie*/,
182  Real shift,
183  Real coshift)
184 {
185  DataArray<Real>* p;
186  DataArray<Real>* cp;
187  // Real rtie;
188  // Real ctie;
189  Real rshift;
190  Real cshift;
191  int i;
192 
193  if (thesolver->rep() == SPxSolver::COLUMN)
194  {
195  cp = &pref;
196  p = &coPref;
197  // ctie = tie;
198  // rtie = cotie;
199  cshift = shift;
200  rshift = coshift;
201  }
202  else
203  {
204  p = &pref;
205  cp = &coPref;
206  // rtie = tie;
207  // ctie = cotie;
208  rshift = shift;
209  cshift = coshift;
210  }
211 
212  // p[i] += rtie * thesolver->rowVector(i).size() / Real(thesolver->nCols());
213  // p[i] += EQ_PREF * (thesolver->rhs(i) == thesolver->lhs(i));
214  // p[i] += EQ_PREF * (thesolver->rhs(i) >= infinity
215  // && thesolver->lhs(i) <= -infinity);
216  for(i = 0; i < thesolver->nRows(); ++i)
217  (*p)[i] = rshift;
218 
219  // cp[i] += ctie * thesolver->colVector(i).size() / Real(thesolver->nRows());
220  // cp[i] += EQ_PREF * (thesolver->upper(i) == thesolver->lower(i));
221  // cp[i] += EQ_PREF * (thesolver->upper(i) >= infinity
222  // && thesolver->lower(i) <= -infinity);
223  for(i = 0; i < thesolver->nCols(); ++i)
224  (*cp)[i] = cshift;
225 
226  for(i = 0; i < coPref.size(); ++i)
227  coPref[i] *= 1.0 - mult * i;
228 
229  for(i = 0; i < pref.size(); ++i)
230  pref[i] *= 1.0 + mult * i;
231 }
232 
234 {
235  if (tp != prefSetup)
236  {
237  Real mult = 1e-8 / Real(1 + thesolver->dim() + thesolver->coDim());
238 
239  if (tp == SPxSolver::ENTER)
240  setupPrefsX(-mult, -1e-5, -1e-5, 1.0, 1.0);
241  else
242  setupPrefsX(mult, 1e-5, 1e-5, 1.0, 1.0);
243 
244  prefSetup = tp;
245  }
246 }
247 
249 {
250  if (workVec.dim() != thesolver->dim())
251  {
252  DVector tmp = weights;
253  weights = coWeights;
254  coWeights = tmp;
255 
256  workVec.clear();
258  }
259 }
260 
261 void SPxSteepPR::left4(int n, SPxId id)
262 {
263  assert(thesolver->type() == SPxSolver::LEAVE);
264 
265  // Update preference multiplier in #leavePref#
266  if (thesolver->isId(id))
267  leavePref[n] = pref[thesolver->number(id)];
268  else if (thesolver->isCoId(id))
269  leavePref[n] = coPref[thesolver->number(id)];
270 
271  if (id.isValid())
272  {
273  // Real delta = 0.1; // thesolver->epsilon();
274  Real delta = 0.1 + 1.0 / thesolver->basis().iteration();
275  Real* coWeights_ptr = coWeights.get_ptr();
276  const Real* workVec_ptr = workVec.get_const_ptr();
277  const Real* rhoVec = thesolver->fVec().delta().values();
278  Real rhov_1 = 1.0 / rhoVec[n];
279  Real beta_q = thesolver->coPvec().delta().length2() * rhov_1 * rhov_1;
280 
281  //TK: I gave the 0.5 extra, because I am not sure how hard this assert is.
282 #ifndef NDEBUG
283  if (spxAbs(rhoVec[n]) < theeps * 0.5)
284  {
285  MSG_ERROR( std::cerr << "WSTEEP04: rhoVec = "
286  << rhoVec[n] << " with smaller absolute value than 0.5*theeps = " << 0.5*theeps << std::endl; )
287  }
288 #endif // NDEBUG
289 
290  // Update #coWeights# vector
291  const IdxSet& rhoIdx = thesolver->fVec().idx();
292  int len = thesolver->fVec().idx().size();
293 
294  for(int i = 0; i < len; ++i)
295  {
296  int j = rhoIdx.index(i);
297 
298  coWeights_ptr[j] += rhoVec[j] * (beta_q * rhoVec[j] - 2.0 * rhov_1 * workVec_ptr[j]);
299 
300  if (coWeights_ptr[j] < delta)
301  coWeights_ptr[j] = delta; // coWeights_ptr[j] = delta / (1+delta-x);
302  else if (coWeights_ptr[j] >= infinity)
303  coWeights_ptr[j] = 1.0 / theeps;
304  }
305  coWeights_ptr[n] = beta_q;
306  //@ coWeights_ptr[n] = 0.999*beta_q;
307  //@ coWeights_ptr[n] = 1.001*beta_q;
308  }
309 }
310 
312 {
313  int idx;
314  int nsorted;
315  Real x;
316  const Real* fTest = thesolver->fTest().get_const_ptr();
317  const Real* cpen = coWeights.get_const_ptr();
318  const Real* prefPtr = leavePref.get_const_ptr();
319  IdxElement price;
320  prices.clear();
321  bestPrices.clear();
322 
323  // construct vector of all prices
324  for (int i = thesolver->infeasibilities.size() - 1; i >= 0; --i)
325  {
326  idx = thesolver->infeasibilities.index(i);
327  x = fTest[idx];
328  if (x < -feastol)
329  {
330  if( cpen[idx] < feastol )
331  x = x * x / feastol * prefPtr[idx];
332  else
333  x = x * x / cpen[idx] * prefPtr[idx];
334  price.val = x;
335  price.idx = idx;
336  prices.append(price);
337  }
338  }
339  // set up structures for the quicksort implementation
341  // do a partial sort to move the best ones to the front
342  // TODO this can be done more efficiently, since we only need the indices
344  // copy indices of best values to bestPrices
345  for( int i = 0; i < nsorted; ++i )
346  {
347  bestPrices.addIdx(prices[i].idx);
349  }
350 
351  if( nsorted > 0 )
352  return prices[0].idx;
353  else
354  return -1;
355 }
356 
357 
359 {
360  assert(isConsistent());
361 
362  int retid;
363 
365  {
366  if ( bestPrices.size() < 2 || thesolver->basis().lastUpdate() == 0 )
367  {
368  // call init method to build up price-vector and return index of largest price
370  }
371  else
372  retid = selectLeaveHyper(theeps);
373  }
374  else if (thesolver->sparsePricingLeave)
375  retid = selectLeaveSparse(theeps);
376  else
377  retid = selectLeaveX(theeps);
378 
379  if( retid < 0 && !refined )
380  {
381  refined = true;
382  MSG_INFO3( (*thesolver->spxout), (*thesolver->spxout) << "WSTEEP03 trying refinement step..\n"; )
384  }
385 
386  if( retid >= 0 )
387  {
388  assert( thesolver->coPvec().delta().isConsistent() );
389  // coPvec().delta() might be not setup after the solve when it contains too many nonzeros.
390  // This is intended and forcing to keep the sparsity information leads to a slowdown
391  // TODO implement a dedicated solve method for unitvectors
393  thesolver->unitVector(retid));
394  assert( thesolver->coPvec().delta().isConsistent() );
397  }
398 
399  return retid;
400 }
401 
403 {
404  const Real* coWeights_ptr = coWeights.get_const_ptr();
405  const Real* fTest = thesolver->fTest().get_const_ptr();
406  // const Real* low = thesolver->lbBound();
407  // const Real* up = thesolver->ubBound();
408  const Real* p = leavePref.get_const_ptr();
409 
410  Real best = -infinity;
411  Real x;
412 
413  int lastIdx = -1;
414 
415  for (int i = thesolver->dim() - 1; i >= 0; --i)
416  {
417  x = fTest[i];
418 
419  if (x < -tol)
420  {
421  /**@todo this was an assert! is an assertion correct?*/
422  // assert(coWeights_ptr[i] >= theeps);
423  if( coWeights_ptr[i] < tol )
424  {
425 #ifdef ENABLE_ADDITIONAL_CHECKS
426  MSG_WARNING( spxout, spxout << "WSTEEP02 SPxSteepPR::selectLeaveX(): coWeights too small ("
427  << coWeights_ptr[i] << "), assuming epsilon (" << tol << ")!" << std::endl; )
428 #endif
429  x = x * x / tol * p[i];
430  }
431  else
432  x = x * x / coWeights_ptr[i] * p[i];
433 
434  if (x > best)
435  {
436  best = x;
437  lastIdx = i;
438  }
439  }
440  }
441 
442  return lastIdx;
443 }
444 
446 {
447  const Real* coWeights_ptr = coWeights.get_const_ptr();
448  const Real* fTest = thesolver->fTest().get_const_ptr();
449  const Real* p = leavePref.get_const_ptr();
450  Real best = -infinity;
451  Real x;
452  int lastIdx = -1;
453  int idx;
454 
455  for (int i = thesolver->infeasibilities.size() - 1; i >= 0; --i)
456  {
457  idx = thesolver->infeasibilities.index(i);
458  x = fTest[idx];
459 
460  if (x < -tol)
461  {
462  if( coWeights_ptr[idx] < tol )
463  {
464 #ifdef ENABLE_ADDITIONAL_CHECKS
465  MSG_WARNING( spxout, spxout << "WSTEEP02 SPxSteepPR::selectLeaveSparse(): coWeights too small ("
466  << coWeights_ptr[idx] << "), assuming epsilon (" << tol << ")!" << std::endl; )
467 #endif
468  x = x * x / tol * p[idx];
469  }
470  else
471  x = x * x / coWeights_ptr[idx] * p[idx];
472 
473  if (x > best)
474  {
475  best = x;
476  lastIdx = idx;
477  }
478  }
479  else
480  {
484  }
485  }
486 
487  return lastIdx;
488 }
489 
491 {
492  const Real* coPen = coWeights.get_const_ptr();
493  const Real* fTest = thesolver->fTest().get_const_ptr();
494  const Real* prefPtr = leavePref.get_const_ptr();
495 
496  Real leastBest = infinity;
497  Real best = -infinity;
498  Real x;
499 
500  int bestIdx = -1;
501  int idx = 0;
502 
503  // find the best price from the short candidate list
504  for( int i = bestPrices.size() - 1; i >= 0; --i )
505  {
506  idx = bestPrices.index(i);
507  x = fTest[idx];
508  if( x < -tol )
509  {
511  if( coPen[idx] < -tol )
512  {
513 #ifdef ENABLE_ADDITIONAL_CHECKS
514  MSG_WARNING( spxout, spxout << "WSTEEP02 SPxSteepPR::selectLeaveSparse(): coWeights too small ("
515  << coPen[idx] << "), assuming epsilon (" << tol << ")!" << std::endl; )
516 #endif
517  x = x * x / tol * prefPtr[idx];
518  }
519  else
520  x = x * x / coPen[idx] * prefPtr[idx];
521 
522  if( x > best )
523  {
524  best = x;
525  bestIdx = idx;
526  }
527  if( x < leastBest )
528  leastBest = x;
529  }
530  else
531  {
532  bestPrices.remove(i);
534  }
535  }
536 
537  // make sure we do not skip potential candidates due to a high leastBest value
538  if( leastBest == infinity )
539  {
540  assert(bestPrices.size() == 0);
541  leastBest = 0;
542  }
543 
544  // scan the updated indices for a better price
545  for( int i = thesolver->updateViols.size() - 1; i >= 0; --i )
546  {
547  idx = thesolver->updateViols.index(i);
548  // is this index a candidate for bestPrices?
549  if( thesolver->isInfeasible[idx] == VIOLATED )
550  {
551  x = fTest[idx];
552  assert(x < -tol);
553  if( coPen[idx] < -tol )
554  {
555 #ifdef ENABLE_ADDITIONAL_CHECKS
556  MSG_WARNING( spxout, spxout << "WSTEEP02 SPxSteepPR::selectLeaveSparse(): coWeights too small ("
557  << coPen[idx] << "), assuming epsilon (" << tol << ")!" << std::endl; )
558 #endif
559  x = x * x / tol * prefPtr[idx];
560  }
561  else
562  x = x * x / coPen[idx] * prefPtr[idx];
563 
564  if( x > leastBest )
565  {
566  if( x > best )
567  {
568  best = x;
569  bestIdx = idx;
570  }
572  bestPrices.addIdx(idx);
573  }
574  }
575  }
576 
577  return bestIdx;
578 }
579 
580 /* Entering Simplex
581  */
582 void SPxSteepPR::entered4(SPxId /* id */, int n)
583 {
584  assert(thesolver->type() == SPxSolver::ENTER);
585 
586  if (n >= 0 && n < thesolver->dim())
587  {
588  Real delta = 2 + 1.0 / thesolver->basis().iteration();
589  Real* coWeights_ptr = coWeights.get_ptr();
590  Real* weights_ptr = weights.get_ptr();
591  const Real* workVec_ptr = workVec.get_const_ptr();
592  const Real* pVec = thesolver->pVec().delta().values();
593  const IdxSet& pIdx = thesolver->pVec().idx();
594  const Real* coPvec = thesolver->coPvec().delta().values();
595  const IdxSet& coPidx = thesolver->coPvec().idx();
596  Real xi_p = 1 / thesolver->fVec().delta()[n];
597  int i, j;
598  Real xi_ip, x;
599 
600  assert(thesolver->fVec().delta()[n] > thesolver->epsilon()
601  || thesolver->fVec().delta()[n] < -thesolver->epsilon());
602 
603  for (j = coPidx.size() - 1; j >= 0; --j)
604  {
605  i = coPidx.index(j);
606  xi_ip = xi_p * coPvec[i];
607  x = coWeights_ptr[i] += xi_ip * (xi_ip * pi_p - 2 * workVec_ptr[i]);
608  /*
609  if(x < 1)
610  coWeights_ptr[i] = 1 / (2-x);
611  */
612  if (x < delta)
613  coWeights_ptr[i] = delta;
614  // coWeights_ptr[i] = 1;
615  else if (x > infinity)
616  coWeights_ptr[i] = 1 / thesolver->epsilon();
617  }
618 
619  for (j = pIdx.size() - 1; j >= 0; --j)
620  {
621  i = pIdx.index(j);
622  xi_ip = xi_p * pVec[i];
623  x = weights_ptr[i] += xi_ip * (xi_ip * pi_p - 2.0 * (thesolver->vector(i) * workVec));
624  /*
625  if(x < 1)
626  weights_ptr[i] = 1 / (2-x);
627  */
628  if (x < delta)
629  weights_ptr[i] = delta;
630  // weights_ptr[i] = 1;
631  else if (x > infinity)
632  weights_ptr[i] = 1.0 / thesolver->epsilon();
633  }
634  }
635 
636  /*@
637  if(thesolver->isId(id))
638  weights[ thesolver->number(id) ] *= 1.0001;
639  else if(thesolver->isCoId(id))
640  coWeights[ thesolver->number(id) ] *= 1.0001;
641  */
642 
643 }
644 
645 
647 {
648  const Real* cp = coPref.get_const_ptr();
649  const Real* coTest = thesolver->coTest().get_const_ptr();
650  const Real* coWeights_ptr = coWeights.get_const_ptr();
651  int idx;
652  int nsorted;
653  Real x;
654  IdxElement price;
655 
656  prices.clear();
657  bestPrices.clear();
658 
659  // construct vector of all prices
660  for( int i = thesolver->infeasibilities.size() - 1; i >= 0; --i )
661  {
662  idx = thesolver->infeasibilities.index(i);
663  x = coTest[idx];
664  if ( x < -feastol)
665  {
667  x = x * x / coWeights_ptr[idx];
668  price.val = x * cp[idx];
669  price.idx = idx;
670  prices.append(price);
671  }
672  else
673  {
676  }
677  }
678  // set up structures for the quicksort implementation
680  // do a partial sort to move the best ones to the front
681  // TODO this can be done more efficiently, since we only need the indices
683  // copy indices of best values to bestPrices
684  for( int i = 0; i < nsorted; ++i )
685  {
686  bestPrices.addIdx(prices[i].idx);
688  }
689 
690  if( nsorted > 0 )
691  {
692  best = prices[0].val;
693  return thesolver->coId(prices[0].idx);
694  }
695  else
696  return SPxId();
697 }
698 
699 
701 {
702  const Real* p = pref.get_const_ptr();
703  const Real* test = thesolver->test().get_const_ptr();
704  const Real* weights_ptr = weights.get_const_ptr();
705  int idx;
706  int nsorted;
707  Real x;
708  IdxElement price;
709 
710  pricesCo.clear();
712 
713  // construct vector of all prices
714  for( int i = thesolver->infeasibilitiesCo.size() - 1; i >= 0; --i )
715  {
717  x = test[idx];
718  if ( x < -feastol)
719  {
721  x = x * x / weights_ptr[idx];
722  price.val = x * p[idx];
723  price.idx = idx;
724  pricesCo.append(price);
725  }
726  else
727  {
730  }
731  }
732  // set up structures for the quicksort implementation
734  // do a partial sort to move the best ones to the front
735  // TODO this can be done more efficiently, since we only need the indices
737  // copy indices of best values to bestPrices
738  for( int i = 0; i < nsorted; ++i )
739  {
740  bestPricesCo.addIdx(pricesCo[i].idx);
742  }
743 
744  if( nsorted > 0 )
745  {
746  best = pricesCo[0].val;
747  return thesolver->id(pricesCo[0].idx);
748  }
749  else
750  return SPxId();
751 }
752 
753 
755 {
756  assert(thesolver != 0);
757  SPxId enterId;
758 
759  enterId = selectEnterX(theeps);
760 
761  if( !enterId.isValid() && !refined )
762  {
763  refined = true;
764  MSG_INFO3( (*thesolver->spxout), (*thesolver->spxout) << "WSTEEP05 trying refinement step..\n"; )
766  }
767 
768  assert(isConsistent());
769 
770  if (enterId.isValid())
771  {
772  SSVector& delta = thesolver->fVec().delta();
773 
774  thesolver->basis().solve4update(delta, thesolver->vector(enterId));
775 
776  workRhs.setup_and_assign(delta);
777  pi_p = 1 + delta.length2();
778 
780  }
781  return enterId;
782 }
783 
785 {
786  SPxId enterId;
787  SPxId enterCoId;
788  Real best;
789  Real bestCo;
790 
791  best = -infinity;
792  bestCo = -infinity;
793 
795  {
796  if( bestPrices.size() < 2 || thesolver->basis().lastUpdate() == 0 )
797  enterCoId = (thesolver->sparsePricingEnter) ? buildBestPriceVectorEnterDim(best, tol) : selectEnterDenseDim(best, tol);
798  else
799  enterCoId = (thesolver->sparsePricingEnter) ? selectEnterHyperDim(best, tol) : selectEnterDenseDim(best, tol);
800 
801  if( bestPricesCo.size() < 2 || thesolver->basis().lastUpdate() == 0 )
802  enterId = (thesolver->sparsePricingEnterCo) ? buildBestPriceVectorEnterCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
803  else
804  enterId = (thesolver->sparsePricingEnterCo) ? selectEnterHyperCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
805  }
806  else
807  {
808  enterCoId = (thesolver->sparsePricingEnter && !refined) ? selectEnterSparseDim(best, tol) : selectEnterDenseDim(best, tol);
809  enterId = (thesolver->sparsePricingEnterCo && !refined) ? selectEnterSparseCoDim(bestCo, tol) : selectEnterDenseCoDim(bestCo, tol);
810  }
811 
812  // prefer slack indices to reduce nonzeros in basis matrix
813  if( enterCoId.isValid() && (best > SPARSITY_TRADEOFF * bestCo || !enterId.isValid()) )
814  return enterCoId;
815  else
816  return enterId;
817 }
818 
819 
821 {
822  const Real* cp = coPref.get_const_ptr();
823  const Real* coTest = thesolver->coTest().get_const_ptr();
824  const Real* coWeights_ptr = coWeights.get_const_ptr();
825 
826  Real leastBest = infinity;
827  Real x;
828  int enterIdx = -1;
829  int idx;
830 
831  // find the best price from short candidate list
832  for( int i = bestPrices.size() - 1; i >= 0; --i )
833  {
834  idx = bestPrices.index(i);
835  x = coTest[idx];
836  if( x < -tol )
837  {
838  x = x * x / coWeights_ptr[idx];
839  x = x * cp[idx];
840  if( x > best )
841  {
842  best = x;
843  enterIdx = idx;
844  }
845  if( x < leastBest )
846  leastBest = x;
847  }
848  else
849  {
850  bestPrices.remove(i);
852  }
853  }
854 
855  // make sure we do not skip potential candidates due to a high leastBest value
856  if( leastBest == infinity )
857  {
858  assert(bestPrices.size() == 0);
859  leastBest = 0;
860  }
861 
862  // scan hte updated indeces for a better price
863  for( int i = thesolver->updateViols.size() -1; i >= 0; --i )
864  {
865  idx = thesolver->updateViols.index(i);
866  // only look at indeces that were not checked already
867  if( thesolver->isInfeasible[idx] == VIOLATED )
868  {
869  x = coTest[idx];
870  if( x < -tol )
871  {
872  x = x * x / coWeights_ptr[idx];
873  x = x * cp[idx];
874  if( x > leastBest )
875  {
876  if (x > best)
877  {
878  best = x;
879  enterIdx = idx;
880  }
881  // put index into candidate list
883  bestPrices.addIdx(idx);
884  }
885  }
886  else
887  {
889  }
890  }
891  }
892 
893  if( enterIdx >= 0 )
894  return thesolver->coId(enterIdx);
895  else
896  return SPxId();
897 }
898 
899 
901 {
902  const Real* p = pref.get_const_ptr();
903  const Real* test = thesolver->test().get_const_ptr();
904  const Real* weights_ptr = weights.get_const_ptr();
905 
906  Real leastBest = infinity;
907  Real x;
908  int enterIdx = -1;
909  int idx;
910 
911  // find the best price from short candidate list
912  for( int i = bestPricesCo.size() - 1; i >= 0; --i )
913  {
914  idx = bestPricesCo.index(i);
915  x = test[idx];
916  if( x < -tol )
917  {
918  x = x * x / weights_ptr[idx];
919  x = x * p[idx];
920  if( x > best )
921  {
922  best = x;
923  enterIdx = idx;
924  }
925  if( x < leastBest )
926  leastBest = x;
927  }
928  else
929  {
930  bestPricesCo.remove(i);
932  }
933  }
934 
935  // make sure we do not skip potential candidates due to a high leastBest value
936  if( leastBest == infinity )
937  {
938  assert(bestPricesCo.size() == 0);
939  leastBest = 0;
940  }
941 
942  // scan the updated indeces for a better price
943  for( int i = thesolver->updateViolsCo.size() -1; i >= 0; --i )
944  {
945  idx = thesolver->updateViolsCo.index(i);
946  // only look at indeces that were not checked already
947  if( thesolver->isInfeasibleCo[idx] == VIOLATED )
948  {
949  x = test[idx];
950  if( x < -tol )
951  {
952  x = x * x / weights_ptr[idx];
953  x = x * p[idx];
954  if( x > leastBest )
955  {
956  if (x > best)
957  {
958  best = x;
959  enterIdx = idx;
960  }
961  // put index into candidate list
963  bestPricesCo.addIdx(idx);
964  }
965  }
966  else
967  {
969  }
970  }
971  }
972 
973  if( enterIdx >= 0 )
974  return thesolver->id(enterIdx);
975  else
976  return SPxId();
977 }
978 
979 
981 {
982  SPxId enterId;
983  const Real* cp = coPref.get_const_ptr();
984  const Real* coTest = thesolver->coTest().get_const_ptr();
985  const Real* coWeights_ptr = coWeights.get_const_ptr();
986 
987  int idx;
988  Real x;
989  Real coPen;
990  Real coPrefValue;
991 
992  for (int i = thesolver->infeasibilities.size() -1; i >= 0; --i)
993  {
994  idx = thesolver->infeasibilities.index(i);
995  x = coTest[idx];
996 
997  if (x < -tol)
998  {
999  coPen = coWeights_ptr[idx];
1000  x = x * x / coPen;
1001  coPrefValue = cp[idx];
1002  x = x * coPrefValue;
1003  // x *= 1 + cp[i];
1004  if (x > best)
1005  {
1006  best = x;
1007  enterId = thesolver->coId(idx);
1008  }
1009  }
1010  else
1011  {
1014  }
1015  }
1016  return enterId;
1017 }
1018 
1020 {
1021  SPxId enterId;
1022  const Real* p = pref.get_const_ptr();
1023  const Real* test = thesolver->test().get_const_ptr();
1024  const Real* weights_ptr = weights.get_const_ptr();
1025 
1026  int idx;
1027  Real x;
1028  Real pen;
1029  Real prefValue;
1030 
1031  for (int i = thesolver->infeasibilitiesCo.size() -1; i >= 0; --i)
1032  {
1033  idx = thesolver->infeasibilitiesCo.index(i);
1034  x = test[idx];
1035 
1036  if (x < -tol)
1037  {
1038  pen = weights_ptr[idx];
1039  x = x * x / pen;
1040  prefValue = p[idx];
1041  x = x * prefValue;
1042  // x *= 1 + p[i];
1043  if (x > best)
1044  {
1045  best = x;
1046  enterId = thesolver->id(idx);
1047  }
1048  }
1049  else
1050  {
1053  }
1054  }
1055  return enterId;
1056 }
1057 
1059 {
1060  SPxId enterId;
1061  const Real* cp = coPref.get_const_ptr();
1062  const Real* coTest = thesolver->coTest().get_const_ptr();
1063  const Real* coWeights_ptr = coWeights.get_const_ptr();
1064 
1065  Real x;
1066 
1067  for (int i = 0, end = thesolver->dim(); i < end; ++i)
1068  {
1069  x = coTest[i];
1070  if (x < -tol)
1071  {
1072  x *= x / coWeights_ptr[i];
1073  x *= cp[i];
1074  // x *= 1 + cp[i];
1075  if (x > best)
1076  {
1077  best = x;
1078  enterId = thesolver->coId(i);
1079  }
1080  }
1081  }
1082  return enterId;
1083 }
1084 
1086 {
1087  SPxId enterId;
1088  const Real* p = pref.get_const_ptr();
1089  const Real* test = thesolver->test().get_const_ptr();
1090  const Real* weights_ptr = weights.get_const_ptr();
1091 
1092  Real x;
1093 
1094  for(int i = 0, end = thesolver->coDim(); i < end; ++i)
1095  {
1096  x = test[i];
1097  if (x < -tol)
1098  {
1099  x *= x / weights_ptr[i];
1100  x *= p[i];
1101  // x *= 1 + p[i];
1102  if (x > best)
1103  {
1104  best = x;
1105  enterId = thesolver->id(i);
1106  }
1107  }
1108  }
1109  return enterId;
1110 }
1111 
1112 
1114 {
1115  n = weights.dim();
1116  pref.reSize (thesolver->coDim());
1118 
1119  if (thesolver->type() == SPxSolver::ENTER)
1120  {
1122  for (; n < weights.dim(); ++n)
1123  weights[n] = 2;
1124  }
1125  prefSetup = 0;
1126 }
1127 
1129 {
1130  n = coWeights.dim();
1131 
1133  coPref.reSize (thesolver->dim());
1135 
1136  workVec.reDim (thesolver->dim());
1138  for (; n < coWeights.dim(); ++n)
1139  coWeights[n] = 1;
1140  prefSetup = 0;
1141 }
1142 
1144 {
1145  assert(thesolver != 0);
1146  weights[i] = weights[weights.dim()];
1148  prefSetup = 0;
1149 }
1150 
1151 void SPxSteepPR::removedVecs(const int perm[])
1152 {
1153  assert(thesolver != 0);
1154  if (thesolver->type() == SPxSolver::ENTER)
1155  {
1156  int i;
1157  int j = weights.dim();
1158  for (i = 0; i < j; ++i)
1159  if (perm[i] >= 0)
1160  weights[perm[i]] = weights[i];
1161  }
1163  prefSetup = 0;
1164 }
1165 
1167 {
1168  assert(thesolver != 0);
1169  coWeights[i] = coWeights[coWeights.dim()];
1171  prefSetup = 0;
1172 }
1173 
1174 void SPxSteepPR::removedCoVecs(const int perm[])
1175 {
1176  assert(thesolver != 0);
1177  int i;
1178  int j = coWeights.dim();
1179  for (i = 0; i < j; ++i)
1180  if (perm[i] >= 0)
1181  coWeights[perm[i]] = coWeights[i];
1183  prefSetup = 0;
1184 }
1185 
1187 {
1188 #ifdef ENABLE_CONSISTENCY_CHECKS
1189  if (thesolver != 0 && thesolver->type() == SPxSolver::LEAVE && setup == EXACT)
1190  {
1191  int i;
1192  SSVector tmp(thesolver->dim(), thesolver->epsilon());
1193  Real x;
1194  for (i = thesolver->dim() - 1; i >= 0; --i)
1195  {
1197  x = coWeights[i] - tmp.length2();
1198  if (x > thesolver->leavetol() || -x > thesolver->leavetol())
1199  {
1200  MSG_ERROR( std::cerr << "ESTEEP03 x[" << i << "] = " << x << std::endl; )
1201  }
1202  }
1203  }
1204 
1205  if (thesolver != 0 && thesolver->type() == SPxSolver::ENTER)
1206  {
1207  int i;
1208  for (i = thesolver->dim() - 1; i >= 0; --i)
1209  if (coWeights[i] < thesolver->epsilon())
1210  return MSGinconsistent("SPxSteepPR");
1211 
1212  for (i = thesolver->coDim() - 1; i >= 0; --i)
1213  if (weights[i] < thesolver->epsilon())
1214  return MSGinconsistent("SPxSteepPR");
1215  }
1216 #endif
1217 
1218  return true;
1219 }
1220 } // namespace soplex
Rational spxAbs(const Rational &r)
Absolute.
Definition: rational.cpp:3925
int dim() const
dimension of basis matrix.
Definition: spxsolver.h:936
Random numbers.
int coDim() const
codimension.
Definition: spxsolver.h:941
const R * values() const
Returns array values.
Definition: ssvectorbase.h:288
Representation rep() const
return the current basis representation.
Definition: spxsolver.h:406
virtual SPxId selectEnter()
Definition: spxsteeppr.cpp:754
void reDim(int newdim, const bool setZero=true)
Resets DVectorBase&#39;s dimension to newdim.
Definition: dvectorbase.h:249
DataArray< Real > pref
preference multiplier for selecting as pivot
Definition: spxsteeppr.h:85
int selectLeaveX(Real tol)
implementation of full pricing
Definition: spxsteeppr.cpp:402
const IdxSet & idx() const
nonzero indices of update vector
Definition: updatevector.h:133
void coSolve(Vector &x, const Vector &rhs)
Cosolves linear system with basis matrix.
Definition: spxbasis.h:678
void setupPrefs(SPxSolver::Type)
Definition: spxsteeppr.cpp:233
SPxId selectEnterHyperCoDim(Real &best, Real feastol)
implementation of hyper sparse pricing in the entering Simplex
Definition: spxsteeppr.cpp:900
int buildBestPriceVectorLeave(Real feastol)
prepare data structures for hyper sparse pricing
Definition: spxsteeppr.cpp:311
virtual void setType(SPxSolver::Type)
set entering/leaving algorithm
Definition: spxsteeppr.cpp:58
DIdxSet updateViols
store indices that were changed in the previous iteration and must be checked in hyper pricing ...
Definition: spxsolver.h:363
SPxOut * spxout
message handler
Definition: spxsolver.h:384
bool sparsePricingLeave
These values enable or disable sparse pricing.
Definition: spxsolver.h:374
#define STEEP_REFINETOL
Definition: spxsteeppr.cpp:26
Type
Algorithmic type.
Definition: spxsolver.h:124
DIdxSet bestPrices
array of best pricing candidates
Definition: spxsteeppr.h:75
bool isValid() const
returns TRUE iff the id is a valid column or row identifier.
Definition: spxid.h:150
int iteration() const
returns number of basis changes since last load().
Definition: spxbasis.h:539
const Vector & fTest() const
Violations of fVec.
Definition: spxsolver.h:1246
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:40
Representation
LP basis representation.
Definition: spxsolver.h:105
bool sparsePricingEnterCo
true if sparsePricing is turned on in the entering Simplex
Definition: spxsolver.h:376
int number(const SPxRowId &id) const
Returns the row number of the row with identifier id.
Definition: spxlpbase.h:450
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:370
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
const R * get_const_ptr() const
Conversion to C-style pointer.
Definition: vectorbase.h:412
UpdateVector & fVec() const
feasibility vector.
Definition: spxsolver.h:1184
UpdateVector & pVec() const
pricing vector.
Definition: spxsolver.h:1339
void setup4solve(SSVector *p_y, SSVector *p_rhs)
Setup vectors to be solved within Simplex loop.
Definition: spxsolver.h:1549
void clear()
remove all elements.
Definition: dataarray.h:205
bool isConsistent() const
consistency check.
Definition: ssvectorbase.h:589
virtual int selectLeave()
Definition: spxsteeppr.cpp:358
virtual void addedCoVecs(int n)
n covectors have been added to loaded LP.
SSVector workVec
working vector
Definition: spxsteeppr.h:67
bool isCoId(const SPxId &p_id) const
Is p_id a CoId.
Definition: spxsolver.h:1005
SPxId coId(int i) const
id of i &#39;th covector.
Definition: spxsolver.h:978
bool weightsAreSetup
are the weights already set up?
Definition: spxpricer.h:63
bool isId(const SPxId &p_id) const
Is p_id an SPxId ?
Definition: spxsolver.h:996
int index(int n) const
access n &#39;th index.
Definition: idxset.h:118
Steepest edge pricer.
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
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:403
Leaving Simplex.
Definition: spxsolver.h:143
UpdateVector & coPvec() const
copricing vector.
Definition: spxsolver.h:1259
double Real
SOPLEX_DEBUG.
Definition: spxdefines.h:200
SPxId selectEnterX(Real tol)
choose the best entering index among columns and rows but prefer sparsity
Definition: spxsteeppr.cpp:784
const Vector & test() const
Violations of pVec.
Definition: spxsolver.h:1392
bool refined
has a refinement step already been tried?
Definition: spxsteeppr.h:91
#define HYPERPRICINGSIZE
Definition: spxsolver.h:38
virtual void setRep(SPxSolver::Representation rep)
set row/column representation
Definition: spxsteeppr.cpp:248
virtual void entered4(SPxId id, int n)
Definition: spxsteeppr.cpp:582
const T * get_const_ptr() const
get a const C pointer to the data.
Definition: dataarray.h:115
virtual void left4(int n, SPxId id)
Definition: spxsteeppr.cpp:261
int size() const
returns the number of used indices.
Definition: idxset.h:124
int nCols() const
Returns number of columns in LP.
Definition: spxlpbase.h:133
void append(const T &t)
append element t.
Definition: dataarray.h:121
const SPxBasis & basis() const
Return current basis.
Definition: spxsolver.h:1616
void addIdx(int i)
adds index i to the index set
Definition: didxset.h:75
int size() const
return nr. of elements.
Definition: dataarray.h:211
virtual void addedVecs(int n)
n vectors have been added to loaded LP.
SPxSolver * thesolver
the solver
Definition: spxpricer.h:56
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
Definition: spxdefines.h:109
void clear()
Clears vector.
Definition: ssvectorbase.h:572
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
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
Definition: spxdefines.h:113
int dim() const
Dimension of vector.
Definition: vectorbase.h:174
bool sparsePricingEnter
true if sparsePricing is turned on in the entering Simplex for slack variables
Definition: spxsolver.h:375
Type type() const
return current Type.
Definition: spxsolver.h:412
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:1577
SPxId selectEnterSparseCoDim(Real &best, Real tol)
implementation of sparse pricing for the entering Simplex
virtual bool isConsistent() const
SPxId & baseId(int i)
Definition: spxbasis.h:497
const Vector & coTest() const
violations of coPvec.
Definition: spxsolver.h:1326
SPxId selectEnterHyperDim(Real &best, Real feastol)
implementation of hyper sparse pricing in the entering Simplex
Definition: spxsteeppr.cpp:820
void reDim(int newdim)
Resets dimension to newdim.
Definition: ssvectorbase.h:538
Debugging, floating point type and parameter definitions.
int nRows() const
Returns number of rows in LP.
Definition: spxlpbase.h:127
Sequential object-oriented SimPlex.SPxSolver is an LP solver class using the revised Simplex algorith...
Definition: spxsolver.h:84
int selectLeaveHyper(Real tol)
implementation of hyper sparse pricing in the leaving Simplex
Definition: spxsteeppr.cpp:490
DIdxSet infeasibilities
Definition: spxsolver.h:357
void setup_and_assign(SSVectorBase< S > &rhs)
Sets up rhs vector, and assigns it.
Definition: ssvectorbase.h:690
const SVector & unitVector(int i) const
return i &#39;th unit vector.
Definition: spxsolver.h:1097
Everything should be within this namespace.
void setupWeights(SPxSolver::Type type)
setup steepest edge weights
Definition: spxsteeppr.cpp:92
IdxCompare compare
Definition: spxpricer.h:93
int lastUpdate() const
returns number of basis changes since last refactorization.
Definition: spxbasis.h:533
void solve4update(SSVector &x, const SVector &rhs)
solves linear system with basis matrix.
Definition: spxbasis.h:628
R length2() const
Squared norm.
Definition: svectorbase.h:477
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Definition: spxdefines.h:111
const SVector & vector(int i) const
i &#39;th vector.
Definition: spxsolver.h:1018
int selectLeaveSparse(Real tol)
implementation of sparse pricing in the leaving Simplex
Definition: spxsteeppr.cpp:445
SPxId buildBestPriceVectorEnterDim(Real &best, Real feastol)
build up vector of pricing values for later use
Definition: spxsteeppr.cpp:646
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
SPxId id(int i) const
id of i &#39;th vector.
Definition: spxsolver.h:959
virtual void clear()
clear solver and preferences
Definition: spxsteeppr.cpp:33
void setupPrefsX(Real mult, Real, Real, Real shift, Real coshift)
Definition: spxsteeppr.cpp:178
Real epsilon() const
values are considered to be 0.
Definition: spxsolver.h:670
DataArray< Real > leavePref
Definition: spxsteeppr.h:87
DataArray< int > isInfeasibleCo
0: index not violated, 1: index violated, 2: index violated and among candidate list ...
Definition: spxsolver.h:371
R length2() const
Squared euclidian norm.
Definition: ssvectorbase.h:504
virtual void removedVec(int i)
the i&#39;th vector has been removed from the loaded LP.
const Real infinity
Definition: spxdefines.cpp:26
int dim() const
Dimension of VectorBase.
Definition: ssvectorbase.h:532
bool hyperPricingEnter
true if hyper sparse pricing is turned on in the entering Simplex
Definition: spxsolver.h:378
DataArray< Real > coPref
preference multiplier for selecting as pivot
Definition: spxsteeppr.h:83
virtual void removedCoVec(int i)
the i&#39;th covector has been removed from the loaded LP.
Setup setup
setup type.
Definition: spxsteeppr.h:89
#define MSGinconsistent(name)
Definition: spxdefines.h:121
SSVector & delta()
update vector , writeable
Definition: updatevector.h:122
DIdxSet updateViolsCo
Definition: spxsolver.h:364
SPxId selectEnterDenseCoDim(Real &best, Real tol)
implementation of selectEnter() in dense case
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
Definition: spxdefines.h:117
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
void setMax(int newmax=1)
sets the maximum number of indices.
Definition: didxset.cpp:22
SPxId buildBestPriceVectorEnterCoDim(Real &best, Real feastol)
Definition: spxsteeppr.cpp:700
virtual void removedCoVecs(const int perm[])
n covectors have been removed from loaded LP.
void reSize(int newsize)
reset size to newsize.
Definition: dataarray.h:223
DIdxSet infeasibilitiesCo
Definition: spxsolver.h:360
bool hyperPricingLeave
true if hyper sparse pricing is turned on in the leaving Simplex
Definition: spxsolver.h:377
const IdxElement * elements
Definition: spxpricer.h:82
SPxId selectEnterDenseDim(Real &best, Real tol)
implementation of selectEnter() in dense case (slack variables)
Real leavetol() const
feasibility tolerance maintained by ratio test during LEAVE algorithm.
Definition: spxsolver.h:682
Set of indices.Class IdxSet provides a set of indices. At construction it must be given an array of i...
Definition: idxset.h:56
columnwise representation.
Definition: spxsolver.h:108
R length2() const
Squared norm.
Definition: vectorbase.h:362
SPxId selectEnterSparseDim(Real &best, Real tol)
implementation of sparse pricing for the entering Simplex (slack variables)
Definition: spxsteeppr.cpp:980
virtual void removedVecs(const int perm[])
n vectors have been removed from loaded LP.