Пример #1
0
void MILPSolverCPX::addCol(const vector<pair<int,double> > & entries, const double & lb, const double & ub, const ColumnType & type)
{
    static const bool debug = false;
    
    if (debug) {
        cout << "Adding column to LP: ";
    }
 
    if (alwaysLPRelaxation) {
        (*modelvar).add(IloNumVar(*env, lb, ub));
    } else {
    
        if (type == C_BOOL) {
            (*modelvar).add(IloNumVar(*env, lb, ub, ILOBOOL));
            //cout << "Adding column " << colCount << " as binary\n";
            integervars.insert(make_pair(colCount, true));
        } else if (type == C_INT) {
            (*modelvar).add(IloNumVar(*env, lb, ub, ILOINT));
            //cout << "Adding column " << colCount << " as an integer\n";
            integervars.insert(make_pair(colCount, false));
        } else {
            (*modelvar).add(IloNumVar(*env, lb, ub));
        }
    }
        
    const int entCount = entries.size();
    for (int i = 0; i < entCount; ++i) {
        IloRange & target = modelcon->data[entries[i].first];
        target.setLinearCoef((*modelvar)[colCount], entries[i].second);
        coeffs[entries[i].first][colCount] = entries[i].second;
        if (debug) {
            if (i) cout << " + ";
            cout << entries[i].second << "*" << getRowName(entries[i].first);
        }

    }
    
            
    if (debug) {
        if (lb == -IloInfinity) {
            cout << " <= " << ub << "\n";
        } else if (ub == IloInfinity) {
            cout << " >= " << lb << "\n";
        } else if (ub == lb) {
            cout << " == " << ub << "\n";
        } else {
            cout << " in [" << lb << "," << ub << "]\n";            
        }
    }
                
    ++colCount;
}
Пример #2
0
 /** Gets name (if row does not exist then NULL)
 */
 inline const char *rowName(int whichRow) const
 {
   return getRowName(whichRow);
 }
Пример #3
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; )
   }