// ----------------------------------------------------------------
void SPxWeightST::generate(SPxSolver& base)
{
   SPxId tmpId;

   forbidden.reSize(base.dim());
   rowWeight.reSize(base.nRows());
   colWeight.reSize(base.nCols());
   rowRight.reSize (base.nRows());
   colUp.reSize (base.nCols());

   if (base.rep() == SPxSolver::COLUMN)
   {
      weight   = &colWeight;
      coWeight = &rowWeight;
   }
   else
   {
      weight   = &rowWeight;
      coWeight = &colWeight;
   }
   assert(weight->size()   == base.coDim());
   assert(coWeight->size() == base.dim());

   setupWeights(base);

   SPxBasis::Desc desc(base);
   //   desc.reSize(base.nRows(), base.nCols());

   DataArray < SPxId > pref(base.nRows() + base.nCols());
   initPrefs(pref, base, rowWeight, colWeight);

   int i;
   int deltai;
   int j;
   int sel;

   for(i = 0; i < forbidden.size(); ++i)
      forbidden[i] = 0;

   if (base.rep() == SPxSolver::COLUMN)
   {
      i      = 0;
      deltai = 1;
   }
   else
   {
      i      = pref.size() - 1;
      deltai = -1;
   }

   {
      int  dim = base.dim();
      Real max = 0;

      for (; i >= 0 && i < pref.size(); i += deltai)
      {
         tmpId               = pref[i];
         const SVector& bVec = base.vector(tmpId);
         sel                 = -1;

         // column or row singleton ?
         if (bVec.size() == 1)
         {
            int idx = bVec.index(0);

            if (forbidden[idx] < 2)
            {
               sel  = idx;
               dim += (forbidden[idx] > 0) ? 1 : 0;
            }
         }
         else
         {
            max = bVec.maxAbs();

            int best = base.nRows();

            for (j = bVec.size(); --j >= 0;)
            {
               Real x = bVec.value(j);
               int  k = bVec.index(j);
               int  l = base.coVector(k).size();

               if (!forbidden[k] && (fabs(x) > STABLE * max) && (l < best))
               {
                  best = l;
                  sel  = k;
               }
            }
         }

         if (sel >= 0)
         {
            MSG_DEBUG(
               if (pref[i].type() == SPxId::ROW_ID)
                  spxout << "DWEIST01 r" << base.number(pref[i]);
               else
                  spxout << "DWEIST02 c" << base.number(pref[i]);
            )

            forbidden[sel] = 2;

            if (base.rep() == SPxSolver::COLUMN)
               setDualStatus(desc, base, pref[i]);
            else
               setPrimalStatus(desc, base, pref[i]);

            for (j = bVec.size(); --j >= 0;)
            {
               Real x = bVec.value(j);
               int  k = bVec.index(j);

               if (!forbidden[k] && (x > EPS * max || -x > EPS * max))
               {
                  forbidden[k] = 1;
                  --dim;
               }
            }

            if (--dim == 0)
            {
               //@ for(++i; i < pref.size(); ++i)
               if (base.rep() == SPxSolver::COLUMN)
               {
                  for (i += deltai; i >= 0 && i < pref.size(); i += deltai)
                     setPrimalStatus(desc, base, pref[i]);

                  for (i = forbidden.size(); --i >= 0;)
                  {
                     if (forbidden[i] < 2)
                        setDualStatus(desc, base, base.coId(i));
                  }
               }
               else
               {
                  for (i += deltai; i >= 0 && i < pref.size(); i += deltai)
                     setDualStatus(desc, base, pref[i]);

                  for (i = forbidden.size(); --i >= 0;)
                  {
                     if (forbidden[i] < 2)
                        setPrimalStatus(desc, base, base.coId(i));
                  }
               }
               break;
            }
         }
         else if (base.rep() == SPxSolver::COLUMN)
Exemple #2
0
// ----------------------------------------------------------------
void SPxWeightST::generate(SPxSolver& base)
{
   SPxId tmpId;

   forbidden.reSize(base.dim());
   rowWeight.reSize(base.nRows());
   colWeight.reSize(base.nCols());
   rowRight.reSize (base.nRows());
   colUp.reSize (base.nCols());

   if (base.rep() == SPxSolver::COLUMN)
   {
      weight   = &colWeight;
      coWeight = &rowWeight;
   }
   else
   {
      weight   = &rowWeight;
      coWeight = &colWeight;
   }
   assert(weight->size()   == base.coDim());
   assert(coWeight->size() == base.dim());

   setupWeights(base);

   SPxBasis::Desc desc(base);
   //   desc.reSize(base.nRows(), base.nCols());

   DataArray < SPxId > pref(base.nRows() + base.nCols());
   initPrefs(pref, base, rowWeight, colWeight);

   int i;
   int stepi;
   int j;
   int sel;

   for(i = 0; i < base.dim(); ++i)
      forbidden[i] = 0;

   if (base.rep() == SPxSolver::COLUMN)
   {
      // in COLUMN rep we scan from beginning to end
      i      = 0;
      stepi = 1;
   }
   else
   {
      // in ROW rep we scan from end to beginning
      i      = pref.size() - 1;
      stepi = -1;
   }

   int  dim = base.dim();
   Real maxEntry = 0;

   for (; i >= 0 && i < pref.size(); i += stepi)
   {
      tmpId              = pref[i];
      const SVector& vec = base.vector(tmpId);
      sel                = -1;

      // column or row singleton ?
      if (vec.size() == 1)
      {
         int idx = vec.index(0);

         if (forbidden[idx] < 2)
         {
            sel  = idx;
            dim += (forbidden[idx] > 0) ? 1 : 0;
         }
      }
      else
      {
         maxEntry = vec.maxAbs();

         // initialize the nonzero counter
         int minRowEntries = base.nRows();

         // find a stable index with a sparse row/column
         for (j = vec.size(); --j >= 0;)
         {
            Real x = vec.value(j);
            int  k = vec.index(j);
            int  nRowEntries = base.coVector(k).size();

            if (!forbidden[k] && (spxAbs(x) > STABLE * maxEntry) && (nRowEntries < minRowEntries))
            {
               minRowEntries = nRowEntries;
               sel  = k;
            }
         }
      }

      // we found a valid index
      if (sel >= 0)
      {
         MSG_DEBUG(
            if (pref[i].type() == SPxId::ROW_ID)
               std::cout << "DWEIST01 r" << base.number(pref[i]);
            else
               std::cout << "DWEIST02 c" << base.number(pref[i]);
         )

         forbidden[sel] = 2;

         // put current column/row into basis
         if (base.rep() == SPxSolver::COLUMN)
            setDualStatus(desc, base, pref[i]);
         else
            setPrimalStatus(desc, base, pref[i]);

         for (j = vec.size(); --j >= 0;)
         {
            Real x = vec.value(j);
            int  k = vec.index(j);

            if (!forbidden[k] && (x > EPS * maxEntry || -x > EPS * maxEntry))
            {
               forbidden[k] = 1;
               --dim;
            }
         }

         if (--dim == 0)
         {
            //@ for(++i; i < pref.size(); ++i)
            if (base.rep() == SPxSolver::COLUMN)
            {
               // set all remaining indeces to nonbasic status
               for (i += stepi; i >= 0 && i < pref.size(); i += stepi)
                  setPrimalStatus(desc, base, pref[i]);

               // fill up the basis wherever linear independence is assured
               for (i = forbidden.size(); --i >= 0;)
               {
                  if (forbidden[i] < 2)
                     setDualStatus(desc, base, base.coId(i));
               }
            }
            else
            {
               for (i += stepi; i >= 0 && i < pref.size(); i += stepi)
                  setDualStatus(desc, base, pref[i]);

               for (i = forbidden.size(); --i >= 0;)
               {
                  if (forbidden[i] < 2)
                     setPrimalStatus(desc, base, base.coId(i));
               }
            }
            break;
         }
      }