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-2015 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