Beispiel #1
0
// TK13OCT1998
void LPRowSet::setType(
   int i,
   LPRow::Type p_type)
{
   switch (p_type)
   {
   case LPRow::LESS_EQUAL:
      lhs_w(i) = -infinity;
      break;
   case LPRow::EQUAL:
      if (lhs_w(i) > -infinity)
         rhs_w(i) = lhs(i);
      else
         lhs_w(i) = rhs(i);
      break;
   case LPRow::GREATER_EQUAL:
      rhs_w(i) = infinity;
      break;
   case LPRow::RANGE :
      MSG_ERROR( spxout << "EROWST01 RANGE not supported in LPRowSet::setType()" 
                        << std::endl; )
      throw SPxInternalCodeException("XROWST01 This should never happen.");
   default:
      throw SPxInternalCodeException("XROWST02 This should never happen.");
   }
Beispiel #2
0
static Real getRHS(Real left, Real right)
{
   Real rhsval;

   if (left > -infinity) /// This includes ranges
      rhsval = left;
   else if (right <  infinity)
      rhsval = right;
   else
      throw SPxInternalCodeException("XMPSWR01 This should never happen.");

   return rhsval;
}
Beispiel #3
0
std::ostream& operator<<(std::ostream& os, const SPxId& id)
{
   switch(id.type())
   {
   case SPxId::ROW_ID:
      os << "row ";
      break;
   case SPxId::COL_ID :
      os << "col ";
      break;
   case SPxId::INVALID :
      os << "Invalid ";
      break;
   default :
      throw SPxInternalCodeException("XSPXID01 This should never happen.");
   }
   os << id.idx << " (" << id.info << ")";

   return os;
}
Beispiel #4
0
std::ostream& operator<<(std::ostream& os, const SPxBasis::Desc::Status& stat)
{
   char text;
   
   switch(stat)
   {
   case SPxBasis::Desc::P_ON_LOWER :
      text = 'L';
      break;
   case SPxBasis::Desc::P_ON_UPPER :
      text = 'U';
      break;
   case SPxBasis::Desc::P_FREE :
      text = 'F';
      break;
   case SPxBasis::Desc::P_FIXED :
      text = 'X';
      break;
   case SPxBasis::Desc::D_FREE :
      text = 'f';
      break;
   case SPxBasis::Desc::D_ON_UPPER :
      text = 'u';
      break;
   case SPxBasis::Desc::D_ON_LOWER :
      text = 'l';
      break;
   case SPxBasis::Desc::D_ON_BOTH :
      text = 'x';
      break;
   case SPxBasis::Desc::D_UNDEFINED :
      text = '.';
      break;
   default :
      os << std::endl << "Invalid status <" << int(stat) << ">" << std::endl;
      throw SPxInternalCodeException("XSPXDE01 This should never happen.");
   }
   os << text;

   return os;
}
Beispiel #5
0
LPRow::LPRow(const SVector& p_rowVector, LPRow::Type p_type, Real p_value)
   : vec(p_rowVector)
{
   switch (p_type)
   {
   case LESS_EQUAL:
      left = -infinity;
      right = p_value;
      break;
   case EQUAL:
      left = p_value;
      right = p_value;
      break;
   case GREATER_EQUAL:
      left = p_value;
      right = infinity;
      break;
   default:
      throw SPxInternalCodeException("XLPROW03 This should never happen.");
   }

   assert(isConsistent());
}
Beispiel #6
0
/* compute statistics on leaving variable 
   Compute a set of statistical values on the variable selected for leaving the
   basis.
 */
void SPxSolver::getLeaveVals(
   int leaveIdx,
   SPxBasis::Desc::Status& leaveStat,
   SPxId& leaveId,
   Real& leaveMax,
   Real& leavebound,
   int& leaveNum)
{
   METHOD( "SPxSolver::getLeaveVals()" );
   SPxBasis::Desc& ds = desc();
   leaveId = baseId(leaveIdx);

   if (leaveId.isSPxRowId())
   {
      leaveNum = number(SPxRowId(leaveId));
      leaveStat = ds.rowStatus(leaveNum);

      assert(isBasic(leaveStat));
      switch (leaveStat)
      {
      case SPxBasis::Desc::P_ON_UPPER :
         assert( rep() == ROW );
         ds.rowStatus(leaveNum) = dualRowStatus(leaveNum);
         leavebound = 0;
         leaveMax = -infinity;
         break;
      case SPxBasis::Desc::P_ON_LOWER :
         assert( rep() == ROW );
         ds.rowStatus(leaveNum) = dualRowStatus(leaveNum);
         leavebound = 0;
         leaveMax = infinity;
         break;
      case SPxBasis::Desc::P_FREE :
         assert( rep() == ROW );
         throw SPxInternalCodeException("XLEAVE01 This should never happen.");
      case SPxBasis::Desc::D_FREE :
         assert( rep() == COLUMN );
         ds.rowStatus(leaveNum) = SPxBasis::Desc::P_FIXED;
         assert(lhs(leaveNum) == rhs(leaveNum));
         leavebound = -rhs(leaveNum);
         if ((*theFvec)[leaveIdx] < theLBbound[leaveIdx])
            leaveMax = infinity;
         else
            leaveMax = -infinity;
         break;
      case SPxBasis::Desc::D_ON_LOWER :
         assert( rep() == COLUMN );
         ds.rowStatus(leaveNum) = SPxBasis::Desc::P_ON_UPPER;
         leavebound = -rhs(leaveNum);                // slack !!
         leaveMax = infinity;
         break;
      case SPxBasis::Desc::D_ON_UPPER :
         assert( rep() == COLUMN );
         ds.rowStatus(leaveNum) = SPxBasis::Desc::P_ON_LOWER;
         leavebound = -lhs(leaveNum);                // slack !!
         leaveMax = -infinity;
         break;
      case SPxBasis::Desc::D_ON_BOTH :
         assert( rep() == COLUMN );
         if ((*theFvec)[leaveIdx] > theLBbound[leaveIdx])
         {
            ds.rowStatus(leaveNum) = SPxBasis::Desc::P_ON_LOWER;
            theLRbound[leaveNum] = -infinity;
            leavebound = -lhs(leaveNum);            // slack !!
            leaveMax = -infinity;
         }
         else
         {
            ds.rowStatus(leaveNum) = SPxBasis::Desc::P_ON_UPPER;
            theURbound[leaveNum] = infinity;
            leavebound = -rhs(leaveNum);            // slack !!
            leaveMax = infinity;
         }
         break;

      default:
         throw SPxInternalCodeException("XLEAVE02 This should never happen.");
      }
      MSG_DEBUG( spxout << "DLEAVE51 SPxSolver::getLeaveVals() : row " << leaveNum
                        << ": " << leaveStat
                        << " -> " << ds.rowStatus(leaveNum)
                        << std::endl; )
   }
Beispiel #7
0
SPxId SPxWeightPR::selectEnter()
{
   const Vector& rTest = (solver()->rep() == SPxSolver::ROW)
                         ? solver()->test() : solver()->coTest();
   const Vector& cTest = (solver()->rep() == SPxSolver::ROW)
                         ? solver()->coTest() : solver()->test();
   const SPxBasis::Desc& ds = solver()->basis().desc();
   Real best = infinity;
   SPxId lastId;
   Real x;
   int i;

   for (i = solver()->nRows() - 1; i >= 0; --i)
   {
      x = rTest[i];
      if (x < -theeps)
      {
         x *= -x;
         switch (ds.rowStatus(i))
         {
         case SPxBasis::Desc::P_ON_LOWER :
         case SPxBasis::Desc::D_ON_LOWER :
            x *= 1 + rPenalty[i];
            break;
         case SPxBasis::Desc::P_ON_UPPER :
         case SPxBasis::Desc::D_ON_UPPER :
            x *= 1 - rPenalty[i];
            break;
         case SPxBasis::Desc::P_FREE :
         case SPxBasis::Desc::D_FREE :
            return SPxId(solver()->rId(i));
         case SPxBasis::Desc::D_ON_BOTH :
            if (solver()->pVec()[i] > solver()->upBound()[i])
               x *= 1 + rPenalty[i];
            else
               x *= 1 - rPenalty[i];
            break;
         case SPxBasis::Desc::D_UNDEFINED :
         case SPxBasis::Desc::P_FIXED :
         default:
            throw SPxInternalCodeException("XWGTPR01 This should never happen.");
         }
         if (x < best)
         {
            best = x;
            lastId = solver()->rId(i);
         }
      }
   }

   for (i = solver()->nCols() - 1; i >= 0; --i)
   {
      x = cTest[i];
      if (x < -theeps)
      {
         x *= -x;
         switch (ds.colStatus(i))
         {
         case SPxBasis::Desc::P_ON_LOWER :
         case SPxBasis::Desc::D_ON_LOWER :
            x *= 1 + cPenalty[i];
            break;
         case SPxBasis::Desc::P_ON_UPPER :
         case SPxBasis::Desc::D_ON_UPPER :
            x *= 1 - cPenalty[i];
            break;
         case SPxBasis::Desc::P_FREE :
         case SPxBasis::Desc::D_FREE :
            return SPxId(solver()->cId(i));
         case SPxBasis::Desc::D_ON_BOTH :
            if (solver()->coPvec()[i] > solver()->ucBound()[i])
               x *= 1 + cPenalty[i];
            else
               x *= 1 - cPenalty[i];
            break;
         case SPxBasis::Desc::P_FIXED :
         case SPxBasis::Desc::D_UNDEFINED :
         default:
            throw SPxInternalCodeException("XWGTPR02 This should never happen.");
         }
         if (x < best)
         {
            best = x;
            lastId = solver()->cId(i);
         }
      }
   }
   assert(isConsistent());
   return lastId;
}
Beispiel #8
0
/** @note There will always be a BOUNDS section, even if there are no bounds.
 */
void SPxLP::writeMPS(
   std::ostream&  p_output,          ///< output stream.
   const NameSet* p_rnames,          ///< row names.
   const NameSet* p_cnames,          ///< column names.
   const DIdxSet* p_intvars)         ///< integer variables.
   const
{
   METHOD("writeMPS");

   const char*    indicator;
   char           name [16];
   char           name1[16];
   char           name2[16];
   bool           has_ranges = false;
   int            i;
   int            k;
   
   // --- NAME Section ---
   p_output << "NAME          MPSDATA" << std::endl;

   // --- ROWS Section ---
   p_output << "ROWS" << std::endl;

   for(i = 0; i < nRows(); i++)
   {
      if (lhs(i) == rhs(i))
         indicator = "E";
      else if ((lhs(i) > -infinity) && (rhs(i) < infinity))
      {
         indicator  = "E";
         has_ranges = true;
      }
      else if (lhs(i) > -infinity)
         indicator = "G";
      else if (rhs(i) <  infinity)
         indicator = "L";
      else
         throw SPxInternalCodeException("XMPSWR02 This should never happen.");

      writeRecord(p_output, indicator, getRowName(*this, i, p_rnames, name)); 
   }
   writeRecord(p_output, "N", "MINIMIZE"); 
   
   // --- COLUMNS Section ---
   p_output << "COLUMNS" << std::endl;

   bool has_intvars = (p_intvars != 0) && (p_intvars->size() > 0);

   for(int j = 0; j < (has_intvars ? 2 : 1); j++)
   {
      bool is_intrun = has_intvars && (j == 1);

      if (is_intrun)
         p_output << "    MARK0001  'MARKER'                 'INTORG'" 
                  << std::endl;

      for(i = 0; i < nCols(); i++)
      {
         bool is_intvar = has_intvars && (p_intvars->number(i) >= 0);

         if (  ( is_intrun && !is_intvar)
            || (!is_intrun &&  is_intvar))
             continue;

         const SVector& col = colVector(i);
         int colsize2       = (col.size() / 2) * 2;

         assert(colsize2 % 2 == 0);

         for(k = 0; k < colsize2; k += 2)
            writeRecord(p_output, 0, 
               getColName(*this, i,                p_cnames, name),
               getRowName(*this, col.index(k),     p_rnames, name1),
               col.value(k),
               getRowName(*this, col.index(k + 1), p_rnames, name2),
               col.value(k + 1));

         if (colsize2 != col.size())
            writeRecord(p_output, 0,
               getColName(*this, i,            p_cnames, name),
               getRowName(*this, col.index(k), p_rnames, name1),
               col.value(k));

         if (isNotZero(maxObj(i)))
            writeRecord(p_output, 0, getColName(*this, i, p_cnames, name),
               "MINIMIZE", -maxObj(i));
      }
      if (is_intrun)
         p_output << "    MARK0001  'MARKER'                 'INTEND'"
                  << std::endl;
   }
   // --- RHS Section ---
   p_output << "RHS" << std::endl;

   i = 0;
   while(i < nRows())
   {
      Real rhsval1 = 0.0;
      Real rhsval2 = 0.0;

      for(; i < nRows(); i++)
         if ((rhsval1 = getRHS(lhs(i), rhs(i))) != 0.0)
            break;

      if (i < nRows())
      {
         for(k = i + 1; k < nRows(); k++)
            if ((rhsval2 = getRHS(lhs(k), rhs(k))) != 0.0)
               break;

         if (k < nRows())
            writeRecord(p_output, 0, "RHS", 
               getRowName(*this, i, p_rnames, name1),
               rhsval1, 
               getRowName(*this, k, p_rnames, name2),
               rhsval2);
         else
            writeRecord(p_output, 0, "RHS", 
               getRowName(*this, i, p_rnames, name1),
               rhsval1);

         i = k + 1;
      }
   }

   // --- RANGES Section ---
   if (has_ranges)
   {
      p_output << "RANGES" << std::endl;
         
      for(i = 0; i < nRows(); i++)
         if ((lhs(i) > -infinity) && (rhs(i) < infinity))
            writeRecord(p_output, "", "RANGE", 
               getRowName(*this, i, p_rnames, name1),
               rhs(i) - lhs(i));
   }
   // --- BOUNDS Section ---
   p_output << "BOUNDS" << std::endl;

   for(i = 0; i < nCols(); i++)
   {
      // skip variables that do not appear in the objective function or any constraint
      const SVector& col = colVector(i);
      if (col.size() == 0 && isZero(maxObj(i)))
         continue;
      if (lower(i) == upper(i))
      {
         writeRecord(p_output, "FX", "BOUND", 
            getColName(*this, i, p_cnames, name1),
            lower(i));

         continue;
      }
      if ((lower(i) <= -infinity) && (upper(i) >= infinity))
      {
         writeRecord(p_output, "FR", "BOUND", 
            getColName(*this, i, p_cnames, name1));
         continue;
      }
      if (lower(i) != 0.0)
      {
         if (lower(i) > -infinity)
            writeRecord(p_output, "LO", "BOUND", 
               getColName(*this, i, p_cnames, name1),
               lower(i));
         else
            writeRecord(p_output, "MI", "BOUND", 
               getColName(*this, i, p_cnames, name1));
      }

      if (has_intvars && (p_intvars->number(i) >= 0))
      {
         // Integer variables have default upper bound 1.0, but we should write
         // it nevertheless since CPLEX seems to assume infinity otherwise.
         writeRecord(p_output, "UP", "BOUND", 
            getColName(*this, i, p_cnames, name1),
            upper(i));
      }
      else
      {
         // Continous variables have default upper bound infinity
         if (upper(i) < infinity)
            writeRecord(p_output, "UP", "BOUND", 
               getColName(*this, i, p_cnames, name1),
               upper(i));
      }
   }   
   // --- ENDATA Section ---
   p_output << "ENDATA" << std::endl;   

   // Output warning when writing a maximisation problem
   if(spxSense() == SPxLP::MAXIMIZE)
   {
      MSG_WARNING( spxout << "XMPSWR03 Warning: objective function inverted when writing maximization problem in MPS file format" << std::endl; )
   }