Beispiel #1
0
// -----------------------------------------------------------------
void SPxSolver::perturbMax(
   const UpdateVector& uvec,
   Vector& p_low,
   Vector& p_up,
   Real eps,
   Real delta,
   int start,
   int incr) 
{
   METHOD( "SPxSolver::perturbMax()" );
   assert(uvec.dim() == p_low.dim());
   assert(uvec.dim() == p_up.dim());

   const Real* vec = uvec.get_const_ptr();
   const Real* upd = uvec.delta().values();
   const IdxSet& idx = uvec.delta().indices();
   Random mult(10.0 * delta, 100.0 * delta);
   Real x, l, u;
   int i, j;

#ifdef  FULL_SHIFT
   eps = delta;
   for (i = uvec.dim() - start - 1; i >= 0; i -= incr)
   {
      u = p_up[i];
      l = p_low[i];
      if (p_up[i] <= vec[i] + eps)
      {
         p_up[i] = vec[i] + Real(mult);
         theShift += p_up[i] - u;
      }
      if (p_low[i] >= vec[i] - eps)
      {
         p_low[i] = vec[i] - Real(mult);
         theShift -= p_low[i] - l;
      }
   }

#else   // !FULL_SHIFT
   for (j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
   {
      i = idx.index(j);
      x = upd[i];
      u = p_up[i];
      l = p_low[i];
      if (x > epsilon())
      {
         if (u != l && vec[i] >= u - eps)
         {
            p_up[i] = vec[i] + Real(mult);
            theShift += p_up[i] - u;
         }
      }
      else if (x < epsilon())
      {
         if (u != l && vec[i] <= l + eps)
         {
            p_low[i] = vec[i] - Real(mult);
            theShift -= p_low[i] - l;
         }
      }
   }
#endif  // !FULL_SHIFT
}
Beispiel #2
0
/* See maxDelta() */
int SPxFastRT::minDelta(
   Real& val,
   Real& maxabs,
   UpdateVector& update,
   const Vector& lowBound,
   const Vector& upBound,
   int start,
   int incr) const
{
   int i, sel;
   Real x, y, max;
   Real u, l;
   bool columnleaving = thesolver->rep() == SPxSolver::COLUMN && m_type == SPxSolver::LEAVE;

   Real mabs = maxabs;

   const Real* up = upBound.get_const_ptr();
   const Real* low = lowBound.get_const_ptr();
   const Real* vec = update.get_const_ptr();
   const Real* upd = update.delta().values();
   const int* idx = update.delta().indexMem();

   sel = -1;
   max = val;

   if (update.delta().isSetup())
   {
      const int* last = idx + update.delta().size();
      for (idx += start; idx < last; idx += incr)
      {
         i = *idx;
         x = upd[i];

         /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
         if( columnleaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))) )
            continue;

         if (x > epsilon)
         {
            // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
            mabs = (x > mabs) ? x : mabs;
            l = low[i];
            if (l > -infinity)
            {
               y = l - vec[i];
               if ( y >= 0 )
                  x = - fastDelta / x;
               else
                  x = ( y - fastDelta ) / x;

               if (x > max)
               {
                  max = x;
                  sel = i;
               }
            }
         }
         else if (x < -epsilon)
         {
            // @todo check wether mabs should be computed only over bounded vars, i.e., in the if block below
            mabs = (-x > mabs) ? -x : mabs;
            u = up[i];
            if (u < infinity)
            {
               y = u - vec[i];
               if (y <= 0)
                  x = fastDelta / x;
               else
                  x = (y + fastDelta) / x;

               if (x > max)
               {
                  max = x;
                  sel = i;
               }
            }
         }
      }
   }
   else
   {
      /* In this case, the indices of the semi-sparse vector update.delta() are not set up and are filled below. */
      int* l_idx = update.delta().altIndexMem();
      Real* uval = update.delta().altValues();
      const Real* uend = uval + update.dim();
      assert( uval == upd );

      for (i = 0; uval < uend; ++uval, ++i)
      {
         x = *uval;

         if (x)
         {
            if (x >= -epsilon && x <= epsilon)
            {
               *uval = 0.0;
               continue;
            }
            else
               *l_idx++ = i;

            /* in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables */
            if( columnleaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))) )
               continue;

            if (x > epsilon)
            {
               mabs = (x > mabs) ? x : mabs;
               l = low[i];
               if (l > -infinity)
               {
                  y = l - vec[i];
                  if ( y >= 0 )
                     x = - fastDelta / x;
                  else
                     x = ( y - fastDelta ) / x;

                  if (x > max)
                  {
                     max = x;
                     sel = i;
                  }
               }
            }
            else if (x < -epsilon)
            {
               mabs = (-x > mabs) ? -x : mabs;
               u = up[i];
               if (u < infinity)
               {
                  y = u - vec[i];
                  if (y <= 0)
                     x = fastDelta / x;
                  else
                     x = (y + fastDelta) / x;

                  if (x > max)
                  {
                     max = x;
                     sel = i;
                  }
               }
            }
         }
      }
      update.delta().setSize(int(l_idx - update.delta().indexMem()));
      update.delta().forceSetup();
   }

   val = max;
   maxabs = mabs;

   return sel;
}
Beispiel #3
0
/* See minSelect() */
int SPxFastRT::maxSelect(
   Real& val,
   Real& stab,
   Real& best,
   Real& bestDelta,
   Real max,
   const UpdateVector& update,
   const Vector& lowBound,
   const Vector& upBound,
   int start,
   int incr) const
{
   int i;
   Real x, y;
   bool columnleaving = thesolver->rep() == SPxSolver::COLUMN && m_type == SPxSolver::LEAVE;

   const Real* up = upBound.get_const_ptr();
   const Real* low = lowBound.get_const_ptr();
   const Real* vec = update.get_const_ptr();
   const Real* upd = update.delta().values();
   const int* idx = update.delta().indexMem();
   const int* last = idx + update.delta().size();

   int nr = -1;
   int bestNr = -1;

   for (idx += start; idx < last; idx += incr)
   {
      i = *idx;
      x = upd[i];

      // in the dual algorithm, bound flips cannot happen, hence we only consider nonbasic variables
      if( columnleaving && ((iscoid && thesolver->isCoBasic(i)) || (!iscoid && thesolver->isBasic(i))) )
         continue;

      if (x > stab)
      {
         y = (up[i] - vec[i]) / x;
         if (y <= max)
         {
            val = y;
            nr = i;
            stab = x;
         }
         else if (y > best)
         {
            best = y;
            bestNr = i;
         }
      }
      else if (x < -stab)
      {
         y = (low[i] - vec[i]) / x;
         if (y <= max)
         {
            val = y;
            nr = i;
            stab = -x;
         }
         else if (y > best)
         {
            best = y;
            bestNr = i;
         }
      }
   }

   if (nr < 0 && bestNr > 0)
   {
      if (upd[bestNr] > 0)
         bestDelta = up[bestNr] - vec[bestNr];
      else
         bestDelta = vec[bestNr] - low[bestNr];
   }

   return nr;
}
Beispiel #4
0
// -----------------------------------------------------------------
void SPxSolver::perturbMax(
   const UpdateVector& uvec,
   Vector& p_low,
   Vector& p_up,
   Real eps,
   Real p_delta,
   int start,
   int incr) 
{
   assert(uvec.dim() == p_low.dim());
   assert(uvec.dim() == p_up.dim());

   const Real* vec = uvec.get_const_ptr();
   const Real* upd = uvec.delta().values();
   const IdxSet& idx = uvec.delta().indices();
   Random mult(10.0 * p_delta, 100.0 * p_delta);
   Real x, l, u;
   int i, j;

#ifdef  FULL_SHIFT
   eps = p_delta;
   for (i = uvec.dim() - start - 1; i >= 0; i -= incr)
   {
      u = p_up[i];
      l = p_low[i];
      if (p_up[i] <= vec[i] + eps)
      {
         p_up[i] = vec[i] + Real(mult);
         theShift += p_up[i] - u;
      }
      if (p_low[i] >= vec[i] - eps)
      {
         p_low[i] = vec[i] - Real(mult);
         theShift -= p_low[i] - l;
      }
   }

#else   // !FULL_SHIFT
   for (j = uvec.delta().size() - start - 1; j >= 0; j -= incr)
   {
      i = idx.index(j);
      x = upd[i];
      u = p_up[i];
      l = p_low[i];

      // do not permute these bounds! c.f. computeFrhs2() in spxvecs.cpp
      if( dualStatus(baseId(i)) == SPxBasis::Desc::D_ON_BOTH )
      {
         continue;
      }

      if (x > eps)
      {
         if (u != l && vec[i] >= u - eps)
         {
            p_up[i] = vec[i] + Real(mult);
            theShift += p_up[i] - u;
         }
      }
      else if (x < -eps)
      {
         if (u != l && vec[i] <= l + eps)
         {
            p_low[i] = vec[i] - Real(mult);
            theShift -= p_low[i] - l;
         }
      }
   }
#endif  // !FULL_SHIFT
}