// 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."); }
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; }
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; }
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; }
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()); }
/* 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; ) }
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; }
/** @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; ) }