29 #define FREE_LHS_RHS 1 30 #define FREE_CONSTRAINT 1 31 #define EMPTY_CONSTRAINT 1 32 #define ROW_SINGLETON 1 33 #define AGGREGATE_VARS 1 34 #define FORCE_CONSTRAINT 1 37 #define EMPTY_COLUMN 1 38 #define FIX_VARIABLE 1 39 #define FREE_ZERO_OBJ_VARIABLE 1 40 #define ZERO_OBJ_COL_SINGLETON 1 41 #define DOUBLETON_EQUATION 1 42 #define FREE_COL_SINGLETON 1 44 #define DOMINATED_COLUMN 1 45 #define WEAKLY_DOMINATED_COLUMN 1 46 #define MULTI_AGGREGATE 1 48 #define TRIVIAL_HEURISTICS 1 57 #define DUPLICATE_ROWS 1 58 #define DUPLICATE_COLS 1 62 #define CHECK_BASIC_DIM 72 for(
int rs = 0; rs <
nRows; ++rs)
78 for(
int cs = 0; cs <
nCols; ++cs)
84 assert(numBasis == nRows);
85 return numBasis ==
nRows;
92 assert(
isZero(s[m_i], 1e-9));
99 MSG_DEBUG(std::cout <<
"RowObjPS: removing slack column " << m_j <<
" (" << cStatus[m_j] <<
100 ") for row " << m_i <<
" (" << rStatus[m_i] <<
").\n");
115 rStatus[m_i] = cStatus[m_j];
122 #ifdef CHECK_BASIC_DIM 140 rStatus[m_old_i] = rStatus[m_i];
145 for(
int k = 0; k < m_row.size(); ++k)
146 slack += m_row.value(k) * x[m_row.index(k)];
156 #ifdef CHECK_BASIC_DIM 173 rStatus[m_old_i] = rStatus[m_i];
184 #ifdef CHECK_BASIC_DIM 201 rStatus[m_old_i] = rStatus[m_i];
203 Real aij = m_col[m_i];
206 s[m_i] = aij * x[m_j];
211 for(
int k = 0; k < m_col.size(); ++k)
213 if(m_col.index(k) != m_i)
214 val -= m_col.value(k) * y[m_col.index(k)];
217 Real newLo = (aij > 0) ? m_lhs / aij : m_rhs / aij;
218 Real newUp = (aij > 0) ? m_rhs / aij : m_lhs / aij;
223 if(newLo <= m_oldLo && newUp >= m_oldUp)
232 assert(
EQrel(newLo, x[m_j],
eps()));
240 else if((
EQrel(m_oldLo, x[m_j],
eps()) && r[m_j] <= -
eps())
241 || (
EQrel(m_oldUp, x[m_j],
eps()) && r[m_j] >=
eps())
261 else if(
EQrel(newLo, m_oldUp,
eps()))
276 assert(
EQrel(m_oldUp, x[m_j],
eps()));
284 else if(
EQrel(newUp, m_oldLo,
eps()))
299 assert(
EQrel(m_oldLo, x[m_j],
eps()));
370 #ifdef CHECK_BASIC_DIM 387 rStatus[m_old_i] = rStatus[m_i];
393 int cBasisCandidate = -1;
394 Real maxViolation = -1.0;
397 for(
int k = 0; k < m_row.size(); ++k)
399 int cIdx = m_row.index(k);
400 Real aij = m_row.value(k);
401 Real oldLo = m_oldLowers[k];
402 Real oldUp = m_oldUppers[k];
404 switch(cStatus[cIdx])
415 if(violation > maxViolation && ((
EQrel(oldLo, x[cIdx],
eps()) && r[cIdx] < -
eps())
416 || (
EQrel(oldUp, x[cIdx],
eps()) && r[cIdx] >
eps())))
418 maxViolation = violation;
419 cBasisCandidate =
cIdx;
437 if(cBasisCandidate >= 0)
441 assert(cBasisCandidate == m_row.index(bas_k));
446 Real aij = m_row.value(bas_k);
447 Real multiplier = r[cBasisCandidate] / aij;
448 r[cBasisCandidate] = 0.0;
450 for(
int k = 0; k < m_row.size(); ++k)
457 r[m_row.index(k)] -= m_row.value(k) * multiplier;
461 Real val = m_objs[bas_k];
464 for(
int k = 0; k < basis_col.
size(); ++k)
466 if(basis_col.
index(k) != m_i)
467 val -= basis_col.
value(k) * y[basis_col.
index(k)];
478 #ifdef CHECK_BASIC_DIM 497 cStatus[m_old_j] = cStatus[m_j];
503 for(
int k = 0; k < m_col.size(); ++k)
504 s[m_col.index(k)] += m_col.value(k) * x[m_j];
509 for(
int k = 0; k < m_col.size(); ++k)
510 val -= m_col.value(k) * y[m_col.index(k)];
515 if(m_lower == m_upper)
517 assert(
EQrel(m_lower, m_val));
523 assert(
EQrel(m_val, m_lower) ||
EQrel(m_val, m_upper) || m_val == 0.0);
529 #ifdef CHECK_BASIC_DIM 547 cStatus[m_j] = m_status;
557 cStatus[m_old_j] = cStatus[m_j];
559 int rIdx = m_old_i - m_col.size() + 1;
561 for(
int k = 0; k < m_col.size(); ++k)
563 int rIdx_new = m_col.index(k);
564 s[
rIdx] = s[rIdx_new];
565 y[
rIdx] = y[rIdx_new];
566 rStatus[
rIdx] = rStatus[rIdx_new];
578 for(
int k = 0; k < m_rows.size(); ++k)
581 const SVector& row = m_rows[k];
583 for(
int l = 0; l < row.
size(); ++l)
585 if(row.
index(l) != m_j)
594 Real z = (m_lRhs[k] / scale) - (val / scale);
599 Real up = z * scale / row[m_j];
621 for(
int k = 0; k < m_rows.size(); ++k)
624 const SVector& row = m_rows[k];
626 for(
int l = 0; l < row.
size(); ++l)
628 if(row.
index(l) != m_j)
637 Real z = (m_lRhs[k] / scale) - (val / scale);
642 Real lo = z * scale / row[m_j];
661 for(
int k = 0; k < m_col.size(); ++k)
662 s[m_col.index(k)] = slack[k] + m_col.value(k) * x[m_j];
667 for(
int k = 0; k < m_col.size(); ++k)
669 int idx = m_col.index(k);
670 y[idx] = m_rowObj[idx];
674 for(
int k = 0; k < m_col.size(); ++k)
698 #ifdef CHECK_BASIC_DIM 715 cStatus[m_old_j] = cStatus[m_j];
718 Real aij = m_row[m_j];
724 throw SPxException(
"Simplifier: infinite activities - aborting unsimplification");
735 Real z1 = (m_lhs / scale1) - (s[m_i] / scale1);
736 Real z2 = (m_rhs / scale2) - (s[m_i] / scale2);
744 Real lo = (aij > 0) ? z1 * scale1 / aij : z2 * scale2 / aij;
745 Real up = (aij > 0) ? z2 * scale2 / aij : z1 * scale1 / aij;
753 assert(
LErel(lo, up));
758 if(m_lower <= -infinity && m_upper >=
infinity)
763 else if(m_lower == m_upper)
783 if(m_lower <= -infinity && m_upper >=
infinity)
788 else if(m_lower == m_upper)
808 if(m_lower <= -infinity && m_upper >=
infinity)
815 assert(
EQrel(m_lower, m_upper));
853 s[m_i] += aij * x[m_j];
856 r[m_j] = -1.0 * aij * y[m_i];
860 #ifdef CHECK_BASIC_DIM 878 rStatus[m_old_i] = rStatus[m_i];
883 cStatus[m_old_j] = cStatus[m_j];
887 Real aij = m_row[m_j];
889 for(
int k = 0; k < m_row.size(); ++k)
891 if(m_row.index(k) != m_j)
892 val += m_row.value(k) * x[m_row.index(k)];
900 Real z = (m_lRhs / scale) - (val / scale);
905 x[m_j] = z * scale / aij;
909 y[m_i] = m_obj / aij;
922 #ifdef CHECK_BASIC_DIM 941 ((m_maxSense && ((r[m_j] > 0 && m_strictUp) || (r[m_j] < 0 && m_strictLo))) ||
942 (!m_maxSense && ((r[m_j] > 0 && m_strictLo) || (r[m_j] < 0 && m_strictUp)))))))
945 Real aik = m_col[m_i];
947 for(
int _k = 0; _k < m_col.size(); ++_k)
949 if(m_col.index(_k) != m_i)
950 val -= m_col.value(_k) * y[m_col.index(_k)];
956 r[m_j] = m_jObj - val * m_aij / aik;
965 if(
GT(r[m_j], 0) || (
isZero(r[m_j]) &&
EQ(x[m_j], m_Lo_j)))
974 #ifdef CHECK_BASIC_DIM 991 for(
int i = m_perm.size() - 1; i >= 0; --i)
995 int rIdx_new = m_perm[i];
997 s[
rIdx] = s[rIdx_new];
998 y[
rIdx] = y[rIdx_new];
999 rStatus[
rIdx] = rStatus[rIdx_new];
1005 for(
int k = 0; k < m_scale.size(); ++k)
1007 if(m_scale.index(k) != m_i)
1008 s[m_scale.index(k)] = s[m_i] / m_scale.value(k);
1012 bool haveSetBasis =
false;
1014 for(
int k = 0; k < m_scale.size(); ++k)
1016 int i = m_scale.index(k);
1022 y[i] = m_rowObj.value(k);
1029 if(rStatus[m_i] ==
SPxSolver::FIXED && (i == m_maxLhsIdx || i == m_minRhsIdx))
1032 y[i] = y[m_i] * m_scale.value(k);
1033 y[m_i] = m_i_rowObj;
1035 if(m_isLhsEqualRhs[k])
1039 else if(i == m_maxLhsIdx)
1045 assert(i == m_minRhsIdx);
1053 haveSetBasis =
true;
1058 y[i] = y[m_i] * m_scale.value(k);
1059 y[m_i] = m_i_rowObj;
1066 haveSetBasis =
true;
1071 y[i] = y[m_i] * m_scale.value(k);
1072 y[m_i] = m_i_rowObj;
1079 haveSetBasis =
true;
1084 y[i] = m_rowObj.value(k);
1089 #ifdef CHECK_BASIC_DIM 1111 #ifdef CHECK_BASIC_DIM 1126 for(
int i = m_perm.size() - 1; i >= 0; --i)
1130 int cIdx_new = m_perm[i];
1132 x[
cIdx] = x[cIdx_new];
1133 r[
cIdx] = r[cIdx_new];
1134 cStatus[
cIdx] = cStatus[cIdx_new];
1184 assert(
LErel(m_loJ, 0.0));
1185 assert(
GErel(m_upJ, 0.0));
1186 assert(
LErel(m_loK, 0.0));
1187 assert(
GErel(m_upK, 0.0));
1195 else if(
LErel(m_loK, 0.0) &&
GErel(m_upK, 0.0))
1208 else if(
LErel(m_loJ, 0.0) &&
GErel(m_upJ, 0.0))
1224 Real z1 = (x[m_k] / scale1) - (m_loK / scale1);
1225 Real z2 = (x[m_k] / scale2) - (m_upK / scale2);
1233 if(m_loJ <= -infinity && m_upJ >=
infinity && m_loK <= -infinity && m_upK >=
infinity)
1238 else if(m_scale > 0.0)
1240 if(
GErel(x[m_k], m_upK + m_scale * m_upJ))
1245 x[m_k] -= m_scale * x[m_j];
1247 else if(
GErel(x[m_k], m_loK + m_scale * m_upJ) && m_upJ <
infinity)
1251 x[m_k] -= m_scale * x[m_j];
1253 else if(
GErel(x[m_k], m_upK + m_scale * m_loJ) && m_upK <
infinity)
1258 x[m_j] = z2 * scale2 / m_scale;
1260 else if(
GErel(x[m_k], m_loK + m_scale * m_loJ) && m_loJ > -
infinity)
1264 x[m_k] -= m_scale * x[m_j];
1266 else if(
GErel(x[m_k], m_loK + m_scale * m_loJ) && m_loK > -
infinity)
1271 x[m_j] = z1 * scale1 / m_scale;
1273 else if(
LTrel(x[m_k], m_loK + m_scale * m_loJ))
1278 x[m_k] -= m_scale * x[m_j];
1287 assert(m_scale < 0.0);
1289 if(
GErel(x[m_k], m_upK + m_scale * m_loJ))
1294 x[m_k] -= m_scale * x[m_j];
1296 else if(
GErel(x[m_k], m_loK + m_scale * m_loJ) && m_loJ > -
infinity)
1300 x[m_k] -= m_scale * x[m_j];
1302 else if(
GErel(x[m_k], m_upK + m_scale * m_upJ) && m_upK <
infinity)
1307 x[m_j] = z2 * scale2 / m_scale;
1309 else if(
GErel(x[m_k], m_loK + m_scale * m_upJ) && m_upJ <
infinity)
1313 x[m_k] -= m_scale * x[m_j];
1315 else if(
GErel(x[m_k], m_loK + m_scale * m_upJ) && m_loK > -
infinity)
1320 x[m_j] = z1 * scale1 / m_scale;
1322 else if(
LTrel(x[m_k], m_loK + m_scale * m_upJ))
1327 x[m_k] -= m_scale * x[m_j];
1337 r[m_j] = m_scale * r[m_k];
1345 s[m_old_i] = s[m_i];
1346 y[m_old_i] = y[m_i];
1347 rStatus[m_old_i] = rStatus[m_i];
1350 x[m_old_j] = x[m_j];
1351 r[m_old_j] = r[m_j];
1352 cStatus[m_old_j] = cStatus[m_j];
1356 Real aij = m_row[m_j];
1357 int active_idx = -1;
1359 assert(m_row.size() == 2);
1361 for(
int k = 0; k < 2; ++k)
1363 if(m_row.index(k) != m_j)
1365 active_idx = m_row.index(k);
1366 val = m_row.value(k) * x[active_idx];
1370 assert(active_idx >= 0);
1377 Real z = (m_rhs / scale) - (val / scale);
1382 x[m_j] = z * scale / aij;
1385 if(isOptimal && (
LT(x[m_j], m_lower,
eps()) ||
GT(x[m_j], m_upper,
eps())))
1387 MSG_ERROR(std::cerr <<
"EMAISM: numerical violation after disaggregating variable" << std::endl;)
1393 for(
int k = 0; k < m_col.size(); ++k)
1395 if(m_col.index(k) != m_i)
1396 dualVal += m_col.value(k) * y[m_col.index(k)];
1399 z = m_obj - dualVal;
1406 &&
NE(x[active_idx], m_oldupper,
eps())) ||
1408 &&
NE(x[active_idx], m_oldlower,
eps())))
1411 r[active_idx] = 0.0;
1412 assert(
NE(m_upper, m_lower));
1414 if(
EQ(x[m_j], m_upper,
eps()))
1416 else if(
EQ(x[m_j], m_lower,
eps()))
1432 #ifdef CHECK_BASIC_DIM 1448 s[m_old_i] = s[m_i];
1449 y[m_old_i] = y[m_i];
1450 rStatus[m_old_i] = rStatus[m_i];
1453 x[m_old_j] = x[m_j];
1454 r[m_old_j] = r[m_j];
1455 cStatus[m_old_j] = cStatus[m_j];
1459 Real aij = m_row[m_j];
1461 for(
int k = 0; k < m_row.size(); ++k)
1463 if(m_row.index(k) != m_j)
1464 val += m_row.value(k) * x[m_row.index(k)];
1472 Real z = (m_const / scale) - (val / scale);
1477 x[m_j] = z * scale / aij;
1482 if(isOptimal && (
LT(x[m_j], m_lower,
eps()) ||
GT(x[m_j], m_upper,
eps())))
1483 MSG_ERROR(std::cerr <<
"numerical violation in original space due to MultiAggregation\n";)
1489 for(
int k = 0; k < m_col.size(); ++k)
1491 if(m_col.index(k) != m_i)
1492 dualVal += m_col.value(k) * y[m_col.index(k)];
1495 z = m_obj - dualVal;
1510 #ifdef CHECK_BASIC_DIM 1525 switch(cStatus[m_j])
1528 if(
LT(x[m_j], m_origupper,
eps()) &&
GT(x[m_j], m_origlower,
eps()))
1530 else if(
LT(x[m_j], m_origupper,
eps()))
1532 else if(
GT(x[m_j], m_origlower,
eps()))
1538 if(
GT(x[m_j], m_origlower,
eps()))
1544 if(
LT(x[m_j], m_origupper,
eps()))
1553 #ifdef CHECK_BASIC_DIM 1565 for(
int i = lp.
nRows() - 1; i >= 0; --i)
1597 for(
int i = lp.
nRows() - 1; i >= 0; --i)
1607 else if(lhs > -
infinity && lhs < -maxVal)
1612 else if(lhs < infinity && lhs > maxVal)
1626 else if(rhs > -
infinity && rhs < -maxVal)
1631 else if(rhs < infinity && rhs > maxVal)
1650 for(
int j = 0; j < lp.
nCols(); ++j)
1660 else if(lo > -
infinity && lo < -maxVal)
1665 else if(lo < infinity && lo > maxVal)
1679 else if(up > -
infinity && up < -maxVal)
1684 else if(up < infinity && up > maxVal)
1696 Real absBnd = (lo > up) ? lo : up;
1705 while(i < col.
size())
1709 if(
isZero(aij * absBnd, tol))
1712 int row_j = row.
pos(j);
1721 <<
" removed, absBnd=" << absBnd
1732 else if(
isZero(aij, tol))
1751 else if(obj > -
infinity && obj < -maxVal)
1756 else if(obj < infinity && obj > maxVal)
1763 if(remRows + remNzos + chgLRhs + chgBnds + objCnt > 0)
1771 << remRows <<
" rows, " 1772 << remNzos <<
" non-zeros, " 1773 << chgBnds <<
" col bounds, " 1774 << chgLRhs <<
" row bounds, " 1775 << objCnt <<
" objective coefficients" << std::endl;)
1786 bool minNegInfinite =
false;
1787 bool maxInfinite =
false;
1792 for(
int l = 0; l < row.
size(); ++l)
1794 if(colNumber < 0 || row.
index(l) != colNumber)
1800 minNegInfinite =
true;
1804 else if(
LT(row.
value(l), 0.0))
1807 minNegInfinite =
true;
1820 else if(
LT(row.
value(l), 0.0))
1852 minVal = (side - minRes) / val;
1857 maxVal = (side - maxRes) / val;
1859 else if(
GT(val, 0.0))
1864 minVal = (side - maxRes) / val;
1869 maxVal = (side - minRes) / val;
1890 bool zerovalid =
true;
1899 for(
int j = lp.
nCols() - 1; j >= 0; --j)
1907 for(
int k = 0; k < col.
size(); ++k)
1938 lower =
MINIMUM(-largeValue, upper);
1951 lowersol[j] = lower;
1952 uppersol[j] = upper;
1954 if(downLocks[j] > upLocks[j])
1956 else if(downLocks[j] < upLocks[j])
1959 locksol[j] = (lower + upper) / 2.0;
1961 lowerObj += lp.
maxObj(j) * lowersol[j];
1962 upperObj += lp.
maxObj(j) * uppersol[j];
1963 lockObj += lp.
maxObj(j) * locksol[j];
1999 for(
int i = lp.
nRows() - 1; i >= 0; --i)
2004 for(
int k = 0; k < row.
size(); k++)
2005 activity += row.
value(k) * sol[row.
index(k)];
2021 for(
int j = lp.
nCols() - 1; j >= 0; --j)
2030 pseudoObj += val * lp.
lower(j);
2037 pseudoObj += val * lp.
upper(j);
2046 for(
int j = lp.
nCols() - 1; j >= 0; --j)
2065 else if(objval > 0.0)
2091 for(
int i = lp.
nRows() - 1; i >= 0; --i)
2103 <<
" rhs=" << lp.
rhs(i) << std::endl;)
2120 for(
int j = lp.
nCols() - 1; j >= 0; --j)
2127 <<
": empty -> maxObj=" << lp.
maxObj(j)
2128 <<
" lower=" << lp.
lower(j)
2129 <<
" upper=" << lp.
upper(j);)
2182 if(remRows + remCols > 0)
2188 << remRows <<
" rows, " 2189 << remCols <<
" cols" 2199 assert(row.
size() == 1);
2202 int j = row.
index(0);
2207 <<
": singleton -> val=" << aij
2208 <<
" lhs=" << lp.
lhs(i)
2209 <<
" rhs=" << lp.
rhs(i);)
2235 <<
" (" << lp.
lower(j)
2237 <<
" (" << lp.
upper(j)
2238 <<
")" << std::endl;)
2240 bool stricterUp =
false;
2241 bool stricterLo =
false;
2261 lp.
upper(j), oldLo, oldUp));
2275 assert(row.
size() == 2);
2279 assert(rhs < infinity && rhs > -
infinity);
2281 int j = row.
index(0);
2282 int k = row.
index(1);
2296 MSG_DEBUG((*
spxout) <<
"IMAISM22 row " << i <<
": doubleton equation -> " 2297 << aij <<
" x_" << j <<
" + " << aik <<
" x_" << k <<
" = " << rhs;)
2308 new_lo_j = (upper_k >=
infinity) ? -
infinity : (rhs - aik * upper_k) / aij;
2309 new_up_j = (lower_k <= -
infinity) ?
infinity : (rhs - aik * lower_k) / aij;
2310 new_lo_k = (upper_j >=
infinity) ? -
infinity : (rhs - aij * upper_j) / aik;
2311 new_up_k = (lower_j <= -
infinity) ?
infinity : (rhs - aij * lower_j) / aik;
2313 else if(aij * aik > 0.0)
2316 new_lo_j = (lower_k <= -
infinity) ? -
infinity : (rhs - aik * lower_k) / aij;
2318 new_lo_k = (lower_j <= -
infinity) ? -
infinity : (rhs - aij * lower_j) / aik;
2324 bool flip_jk =
false;
2326 if(new_lo_j <= -infinity && new_up_j >=
infinity)
2331 else if(new_lo_k <= -infinity && new_up_k >=
infinity)
2336 else if(
LE(new_lo_j, lower_j) &&
GE(new_up_j, upper_j))
2338 if(
LE(new_lo_k, lower_k) &&
GE(new_up_k, upper_k))
2349 else if(
LE(new_lo_k, lower_k) &&
GE(new_up_k, upper_k))
2365 Real _lower_j = lower_j;
2366 Real _upper_j = upper_j;
2381 Real aggr_coef = - (aik / aij);
2382 Real aggr_const = rhs / aij;
2385 << aggr_const <<
" + " << aggr_coef <<
" * x_" << k << std::endl;)
2388 for(
int r = 0; r < col_j.
size(); ++r)
2390 int row_r = col_j.
index(r);
2403 lp.
changeLhs(row_r, lhs_r - aggr_const * arj);
2409 lp.
changeRhs(row_r, rhs_r - aggr_const * arj);
2413 Real newcoef = aggr_coef * arj;
2414 int pos_rk = col_k.
pos(row_r);
2435 lp.
changeObj(k, obj_k + aggr_coef * obj_j);
2448 Real z1 = (rhs / scale1) - (aij * upper_j / scale1);
2449 Real z2 = (rhs / scale2) - (aij * lower_j / scale2);
2464 else if(aik * aij < 0.0)
2473 Real oldlower_k = lower_k;
2474 Real oldupper_k = upper_k;
2490 m_hist.append(
new(AggregationPSptr)
AggregationPS(lp, i, j, rhs, oldupper_k, oldlower_k));
2526 int oldRows = lp.
nRows();
2528 bool redundantLower;
2529 bool redundantUpper;
2533 for(
int i = lp.
nRows() - 1; i >= 0; --i)
2544 for(
int k = 0; k < row.
size(); ++k)
2547 int j = row.
index(k);
2560 lhsBnd += aij * lp.
lower(j);
2565 rhsBnd += aij * lp.
upper(j);
2572 rhsBnd += aij * lp.
lower(j);
2577 lhsBnd += aij * lp.
upper(j);
2584 if(rhsCnt <= 1 || lhsCnt <= 1)
2586 for(
int k = 0; k < row.
size(); ++k)
2589 int j = row.
index(k);
2591 redundantLower =
false;
2592 redundantUpper =
false;
2609 Real z = (lp.
lhs(i) / scale) - (rhsBnd / scale);
2617 lo = lp.
upper(j) + z * scale / aij;
2619 lo = z * scale / aij;
2627 <<
": redundant lower bound on x" << j
2628 <<
" -> lower=" << lo
2629 <<
" (" << lp.
lower(j)
2630 <<
")" << std::endl;)
2632 redundantLower =
true;
2648 Real z = (lp.
rhs(i) / scale) - (lhsBnd / scale);
2656 up = lp.
lower(j) + z * scale / aij;
2658 up = z * scale / aij;
2666 <<
": redundant upper bound on x" << j
2667 <<
" -> upper=" << up
2668 <<
" (" << lp.
upper(j)
2669 <<
")" << std::endl;)
2671 redundantUpper =
true;
2681 lhsBnd -= aij * lp.
lower(j);
2696 rhsBnd -= aij * lp.
upper(j);
2718 Real z = (lp.
lhs(i) / scale) - (rhsBnd / scale);
2726 up = lp.
lower(j) + z * scale / aij;
2728 up = z * scale / aij;
2736 <<
": redundant upper bound on x" << j
2737 <<
" -> upper=" << up
2738 <<
" (" << lp.
upper(j)
2739 <<
")" << std::endl;)
2741 redundantUpper =
true;
2756 Real z = (lp.
rhs(i) / scale) - (lhsBnd / scale);
2764 lo = lp.
upper(j) + z * scale / aij;
2766 lo = z * scale / aij;
2774 <<
": redundant lower bound on x" << j
2775 <<
" -> lower=" << lo
2776 <<
" (" << lp.
lower(j)
2777 <<
")" << std::endl;)
2779 redundantLower =
true;
2789 lhsBnd -= aij * lp.
upper(j);
2804 rhsBnd -= aij * lp.
lower(j);
2820 redundantLhs =
false;
2821 redundantRhs =
false;
2827 <<
": redundant lhs -> lhsBnd=" << lhsBnd
2828 <<
" lhs=" << lp.
lhs(i)
2831 redundantLhs =
true;
2837 <<
": redundant rhs -> rhsBnd=" << rhsBnd
2838 <<
" rhs=" << lp.
rhs(i)
2841 redundantRhs =
true;
2876 <<
": infeasible -> lhs=" << lp.
lhs(i)
2877 <<
" rhs=" << lp.
rhs(i)
2878 <<
" lhsBnd=" << lhsBnd
2879 <<
" rhsBnd=" << rhsBnd
2890 <<
": unconstrained -> removed" << std::endl;)
2897 remNzos += row.
size();
2907 #if EMPTY_CONSTRAINT 2918 <<
" rhs=" << lp.
rhs(i) << std::endl;)
2960 #if FORCE_CONSTRAINT 2967 <<
": forcing constraint fix on lhs ->" 2968 <<
" lhs=" << lp.
lhs(i)
2969 <<
" rhsBnd=" << rhsBnd
2976 for(
int k = 0; k < row.
size(); ++k)
2979 int j = row.
index(k);
2983 lowers[k] = lp.
lower(j);
2984 uppers[k] = lp.
upper(j);
2999 remNzos += row.
size();
3011 <<
": forcing constraint fix on rhs ->" 3012 <<
" rhs=" << lp.
rhs(i)
3013 <<
" lhsBnd=" << lhsBnd
3020 for(
int k = 0; k < row.
size(); ++k)
3023 int j = row.
index(k);
3027 lowers[k] = lp.
lower(j);
3028 uppers[k] = lp.
upper(j);
3043 remNzos += row.
size();
3054 assert(remRows > 0 || remNzos == 0);
3056 if(remRows + chgLRhs + chgBnds > 0)
3066 << remRows <<
" rows, " 3067 << remNzos <<
" non-zeros, " 3068 << chgBnds <<
" col bounds, " 3069 << chgLRhs <<
" row bounds; kept " 3070 << keptBnds <<
" column bounds, " 3071 << keptLRhs <<
" row bounds" 3101 int oldCols = lp.
nCols();
3102 int oldRows = lp.
nRows();
3104 for(
int j = lp.
nCols() - 1; j >= 0; --j)
3112 <<
": infeasible bounds on x" << j
3113 <<
" -> lower=" << lp.
lower(j)
3114 <<
" upper=" << lp.
upper(j)
3124 <<
": empty -> maxObj=" << lp.
maxObj(j)
3125 <<
" lower=" << lp.
lower(j)
3126 <<
" upper=" << lp.
upper(j);)
3188 for(
int k = 0; k < col.
size(); ++k)
3190 if(!loFree && !upFree)
3193 int i = col.
index(k);
3198 if(col.
value(k) > 0.0)
3206 else if(col.
value(k) < 0.0)
3224 <<
" unconstrained above ->";)
3246 <<
" unconstrained below ->";)
3265 #if FREE_ZERO_OBJ_VARIABLE 3266 bool unconstrained_below = loFree && lp.
lower(j) <= -
infinity;
3267 bool unconstrained_above = upFree && lp.
upper(j) >=
infinity;
3269 if(unconstrained_below || unconstrained_above)
3273 <<
" unconstrained " 3274 << (unconstrained_below ?
"below" :
"above")
3275 <<
" with zero objective (" << lp.
maxObj(j)
3276 <<
")" << std::endl;)
3282 SPxQuicksort(col_idx_sorted.mem(), col_idx_sorted.size(), compare);
3291 remRows += col.
size();
3293 for(
int k = col_idx_sorted.size() - 1; k >= 0; --k)
3300 for(
int k = 0; k < col.
size(); ++k)
3302 int l = col.
index(k);
3323 <<
" fixed -> lower=" << lp.
lower(j)
3324 <<
" upper=" << lp.
upper(j) << std::endl;)
3329 remNzos += col.
size();
3343 int i = col.
index(0);
3348 #if ZERO_OBJ_COL_SINGLETON 3350 <<
": singleton in row " << i
3351 <<
" with zero objective";)
3359 lhs = lp.
lhs(i) - aij * lp.
upper(j);
3362 rhs = lp.
rhs(i) - aij * lp.
lower(j);
3367 lhs = lp.
lhs(i) - aij * lp.
lower(j);
3370 rhs = lp.
rhs(i) - aij * lp.
upper(j);
3385 <<
" (" << lp.
lhs(i)
3387 <<
" (" << lp.
rhs(i)
3388 <<
")" << std::endl;)
3423 #if DOUBLETON_EQUATION 3425 <<
": singleton in row " << i
3426 <<
" with doubleton equation ->";)
3435 if(row.
index(0) == j)
3440 else if(row.
index(1) == j)
3463 Real z1 = (lhs / scale1) - (aij * lp.
upper(j) / scale1);
3464 Real z2 = (lhs / scale2) - (aij * lp.
lower(j) / scale2);
3477 else if(aij * aik < 0.0)
3492 <<
": lower=" << lp.
lower(k)
3494 <<
") upper=" << lp.
upper(k)
3496 <<
")" << std::endl;)
3524 #if FREE_COL_SINGLETON 3531 <<
": free singleton in inequality constraint" << std::endl;)
3581 <<
": free singleton removed" << std::endl;)
3585 for(
int h = 0; h < row.size(); ++h)
3587 int k = row.
index(h);
3591 Real new_obj = lp.
obj(k) - (lp.
obj(j) * row.value(h) / aij);
3598 remNzos += row.size();
3610 if(remCols + remRows > 0)
3618 << remRows <<
" rows, " 3619 << remCols <<
" cols, " 3620 << remNzos <<
" non-zeros, " 3621 << chgBnds <<
" col bounds" 3645 int oldRows = lp.
nRows();
3646 int oldCols = lp.
nCols();
3655 for(
int i = lp.
nRows() - 1; i >= 0; --i)
3661 <<
": unconstrained" << std::endl;)
3682 for(
int j = 0; j < lp.
nCols(); ++j)
3696 dualVarUp[i] = bound;
3699 dualVarLo[i] = bound;
3704 dualVarLo[i] = bound;
3707 dualVarUp[i] = bound;
3714 for(
int j = 0; j < lp.
nCols(); ++j)
3716 dualConsLo[j] = dualConsUp[j] = 0.0;
3720 for(
int k = 0; k < col.
size(); ++k)
3726 int i = col.
index(k);
3735 dualConsLo[j] += aij * dualVarLo[i];
3740 dualConsUp[j] += aij * dualVarUp[i];
3747 dualConsUp[j] += aij * dualVarLo[i];
3752 dualConsLo[j] += aij * dualVarUp[i];
3757 for(
int j = lp.
nCols() - 1; j >= 0; --j)
3766 <<
": dual infeasible -> dual lhs bound=" << dualConsLo[j]
3767 <<
" dual rhs bound=" << dualConsUp[j] << std::endl;)
3777 #if DOMINATED_COLUMN 3779 <<
": dominated -> maxObj=" << obj
3780 <<
" dual rhs bound=" << dualConsUp[j] << std::endl;)
3800 #if DOMINATED_COLUMN 3802 <<
": dominated -> maxObj=" << obj
3803 <<
" dual lhs bound=" << dualConsLo[j] << std::endl;)
3825 #if WEAKLY_DOMINATED_COLUMN 3827 <<
": weakly dominated -> maxObj=" << obj
3828 <<
" dual rhs bound=" << dualConsUp[j] << std::endl;)
3840 #if WEAKLY_DOMINATED_COLUMN 3842 <<
": weakly dominated -> maxObj=" << obj
3843 <<
" dual lhs bound=" << dualConsLo[j] << std::endl;)
3870 assert(remRows > 0 || remCols > 0 || remNzos == 0);
3872 if(remCols + remRows > 0)
3879 << remRows <<
" rows, " 3880 << remCols <<
" cols, " 3881 << remNzos <<
" non-zeros" 3901 int oldRows = lp.
nRows();
3902 int oldCols = lp.
nCols();
3907 for(
int j = lp.
nCols() - 1; j >= 0; --j)
3918 for(
int k = 0; k < col.
size(); ++k)
3946 if(upLocks[j] == 1 || downLocks[j] == 1)
3952 bool bestislhs =
true;
3954 for(
int k = 0; k < col.
size(); ++k)
3966 rowNumber = col.
index(k);
3967 lhs = lp.
lhs(rowNumber);
3968 rhs = lp.
rhs(rowNumber);
3977 maxOtherLocks = INT_MAX;
3986 && ((col.
value(k) > 0.0 && lp.
maxObj(j) <= 0.0 && downLocks[j] == 1 && upLocks[j] <= maxOtherLocks)
3987 || (col.
value(k) < 0.0 && lp.
maxObj(j) >= 0.0 && upLocks[j] == 1 && downLocks[j] <= maxOtherLocks));
3989 && ((col.
value(k) > 0.0 && lp.
maxObj(j) >= 0.0 && upLocks[j] == 1 && downLocks[j] <= maxOtherLocks)
3990 || (col.
value(k) < 0.0 && lp.
maxObj(j) <= 0.0 && downLocks[j] == 1 && upLocks[j] <= maxOtherLocks));
3992 if(aggLhs || aggRhs)
4009 assert(
LE(minVal, maxVal));
4015 bestpos = col.
index(k);
4030 assert(
LE(minVal, maxVal));
4035 bestpos = col.
index(k);
4048 Real aggConstant = (bestislhs ? lp.
lhs(bestpos) : lp.
rhs(
4054 (*
spxout) <<
"IMAISM51 col " << j
4055 <<
": Aggregating row: " << bestpos
4056 <<
" Aggregation Constant=" << aggConstant
4057 <<
" Coefficient of aggregated col=" << aggAij << std::endl;
4064 for(
int k = 0; k < col.
size(); ++k)
4066 if(col.
index(k) != bestpos)
4068 int rowNumber = col.
index(k);
4076 for(
int l = 0; l < bestRow.
size(); l++)
4078 if(bestRow.
index(l) != j)
4082 - updateRow[j]*bestRow.
value(l) / aggAij);
4090 lp.
changeRhs(rowNumber, updateRhs - updateRow[j]*aggConstant / aggAij);
4093 lp.
changeLhs(rowNumber, updateLhs - updateRow[j]*aggConstant / aggAij);
4095 assert(
LE(lp.
lhs(rowNumber), lp.
rhs(rowNumber)));
4099 for(
int l = 0; l < bestRow.
size(); l++)
4101 if(bestRow.
index(l) != j)
4119 assert(remRows > 0 || remCols > 0 || remNzos == 0);
4121 if(remCols + remRows > 0)
4128 << remRows <<
" rows, " 4129 << remCols <<
" cols, " 4130 << remNzos <<
" non-zeros" 4154 int oldRows = lp.
nRows();
4165 for(
int i = 0; i < lp.
nRows(); ++i)
4179 << rs_remRows <<
" rows, " 4180 << rs_remRows <<
" non-zeros" 4209 classSize[0] = lp.
nRows();
4211 for(
int i = 1; i < lp.
nRows(); ++i)
4222 for(
int j = 0; j < lp.
nCols(); ++j)
4226 for(
int k = 0; k < col.
size(); ++k)
4229 int i = col.
index(k);
4236 if(--classSize[pClass[i]] == 0)
4237 idxSet.addIdx(pClass[i]);
4241 for(
int m = 0; m < col.
size(); ++m)
4243 int k = pClass[col.
index(m)];
4254 int classIdx = idxSet.index(0);
4261 classIdx = idxSet.index(0);
4266 ++classSize[classIdx];
4268 oldVal = m_classSetRows[k].value(l);
4280 for(
int k = 0; k < lp.
nRows(); ++k)
4283 for(
int k = 0; k < lp.
nRows(); ++k)
4289 const int nRowsOld_tmp = lp.
nRows();
4293 for(
int j = 0; j < nRowsOld_tmp; ++j)
4298 int idxFirstDupRows = -1;
4299 int idxLastDupRows = -1;
4302 for(
int k = 0; k < lp.
nRows(); ++k)
4308 if(idxFirstDupRows < 0)
4310 idxFirstDupRows = k;
4313 for(
int l = 1; l <
m_dupRows[k].size(); ++l)
4319 numDelRows += (
m_dupRows[k].size() - 1);
4324 int k_tmp, j_tmp = -1;
4326 for(k_tmp = j_tmp = 0; k_tmp < nRowsOld_tmp; ++k_tmp)
4328 if(perm_tmp[k_tmp] >= 0)
4329 perm_tmp[k_tmp] = j_tmp++;
4334 bool doChangeRanges =
false;
4338 for(
int k = 0; k < lp.
nRows(); ++k)
4343 <<
" duplicate rows found" << std::endl;)
4357 for(
int l = 0; l <
m_dupRows[k].size(); ++l)
4360 isLhsEqualRhs[l] = (lp.
lhs(i) == lp.
rhs(i));
4367 maxLhs = lp.
lhs(rowIdx);
4368 minRhs = lp.
rhs(rowIdx);
4372 Real scaledLhs, scaledRhs;
4373 Real factor = scale[rowIdx] / scale[i];
4386 if(scaledLhs > maxLhs)
4392 if(scaledRhs < minRhs)
4404 Real newLhs = (maxLhs > lp.
lhs(rowIdx)) ? maxLhs : lp.
lhs(rowIdx);
4405 Real newRhs = (minRhs < lp.
rhs(rowIdx)) ? minRhs : lp.
rhs(rowIdx);
4407 if(k == idxLastDupRows)
4411 for(
int j = 0; j < nRowsOld_tmp; ++j)
4413 da_perm[j] = perm_tmp[j];
4419 m_dupRows[k], scale, da_perm, isLhsEqualRhs,
true,
EQrel(newLhs, newRhs), k == idxFirstDupRows));
4427 m_dupRows[k], scale, da_perm_empty, isLhsEqualRhs,
false,
EQrel(newLhs, newRhs),
4428 k == idxFirstDupRows));
4431 if(maxLhs > lp.
lhs(rowIdx) || minRhs < lp.
rhs(rowIdx))
4434 doChangeRanges =
true;
4438 MSG_DEBUG((*
spxout) <<
"IMAISM55 duplicate rows yield infeasible bounds:" 4439 <<
" lhs=" << newLhs
4440 <<
" rhs=" << newRhs << std::endl;)
4449 newLhsVec[rowIdx] = newLhs;
4450 newRhsVec[rowIdx] = newRhs;
4463 const int nRowsOld = lp.
nRows();
4467 for(
int i = 0; i < nRowsOld; ++i)
4481 for(
int i = 0; i < nRowsOld; ++i)
4484 assert(perm[i] == perm_tmp[i]);
4494 if(remRows + remNzos > 0)
4500 << remRows <<
" rows, " 4501 << remNzos <<
" non-zeros" 4550 classSize[0] = lp.
nCols();
4552 for(
int j = 1; j < lp.
nCols(); ++j)
4563 for(
int i = 0; i < lp.
nRows(); ++i)
4567 for(
int k = 0; k < row.
size(); ++k)
4570 int j = row.
index(k);
4577 if(--classSize[pClass[j]] == 0)
4578 idxSet.addIdx(pClass[j]);
4582 for(
int m = 0; m < row.
size(); ++m)
4584 int k = pClass[row.
index(m)];
4595 int classIdx = idxSet.index(0);
4603 classIdx = idxSet.index(0);
4608 ++classSize[classIdx];
4610 oldVal = m_classSetCols[k].value(l);
4623 for(
int k = 0; k < lp.
nCols(); ++k)
4626 for(
int k = 0; k < lp.
nCols(); ++k)
4629 fixAndRemCol[k] =
false;
4633 bool hasDuplicateCol =
false;
4636 for(
int k = 0; k < lp.
nCols(); ++k)
4641 <<
" duplicate columns found" << std::endl;)
4643 if(!hasDuplicateCol)
4648 hasDuplicateCol =
true;
4651 for(
int l = 0; l <
m_dupCols[k].size(); ++l)
4653 for(
int m = 0; m <
m_dupCols[k].size(); ++m)
4658 if(l != m && !remCol[j1] && !remCol[j2])
4664 Real factor = scale[j1] / scale[j2];
4665 Real objDif = cj1 - cj2 * scale[j1] / scale[j2];
4711 <<
" replaced by one" << std::endl;)
4719 MSG_DEBUG((*
spxout) <<
"IMAISM80 not removing two duplicate columns " << j1
4721 <<
" because zero not contained in their bounds" << std::endl;)
4730 if(factor > 0 && objDif > 0)
4741 <<
" first one fixed at upper bound=" << lp.
upper(j1) << std::endl;)
4748 else if(factor < 0 && objDif < 0)
4759 <<
" first one fixed at lower bound=" << lp.
lower(j1) << std::endl;)
4770 if(factor < 0 && objDif > 0)
4781 <<
" first one fixed at upper bound=" << lp.
upper(j1) << std::endl;)
4790 else if(factor > 0 && objDif < 0)
4801 <<
" first one fixed at lower bound=" << lp.
lower(j1) << std::endl;)
4813 fixAndRemCol[j1] =
true;
4824 for(
int j = 0; j < lp.
nCols(); ++j)
4836 const int nColsOld = lp.
nCols();
4840 for(
int j = 0; j < nColsOld; ++j)
4854 for(
int j = 0; j < nColsOld; ++j)
4862 for(
int j = 0; j < nColsOld; ++j)
4864 da_perm[j] = perm[j];
4876 assert(remCols > 0 || remNzos == 0);
4884 << remCols <<
" cols, " 4885 << remNzos <<
" non-zeros" 4907 mid = (up + lo) / 2.0;
4915 <<
"to new value: " << mid
4920 for(
int k = 0; k < col.
size(); ++k)
4922 int i = col.
index(k);
4932 Real rhs = (lp.
rhs(i) / scale) - (y / scale);
4941 <<
" (" << lp.
rhs(i)
4942 <<
") aij=" << col.
value(k)
4956 Real lhs = (lp.
lhs(i) / scale) - (y / scale);
4965 <<
" (" << lp.
lhs(i)
4966 <<
") aij=" << col.
value(k)
5011 for(
int k = 0; k <
m_hist.size(); ++k)
5038 int numRangedRows = 0;
5039 int numBoxedCols = 0;
5040 int numEqualities = 0;
5042 for(
int i = 0; i < lp.
nRows(); ++i)
5052 for(
int j = 0; j < lp.
nCols(); ++j)
5056 (*spxout) <<
"LP has " 5057 << numEqualities <<
" equations, " 5058 << numRangedRows <<
" ranged rows, " 5059 << numBoxedCols <<
" boxed columns" 5087 for(
int i = 0; i < lp.
nRows(); ++i)
5090 for(
int j = 0; j < lp.
nCols(); ++j)
5142 #if TRIVIAL_HEURISTICS 5172 << m_remCols <<
" columns, " 5185 << lp.
nRows() <<
" rows " 5186 << lp.
nCols() <<
" columns " 5187 << lp.
nNzos() <<
" nonzeros" 5191 int numRangedRows = 0;
5192 int numBoxedCols = 0;
5193 int numEqualities = 0;
5195 for(
int i = 0; i < lp.
nRows(); ++i)
5205 for(
int j = 0; j < lp.
nCols(); ++j)
5209 (*spxout) <<
"Reduced LP has " 5210 << numEqualities <<
" equations, " 5211 << numRangedRows <<
" ranged rows, " 5212 << numBoxedCols <<
" boxed columns" 5253 assert(x.
dim() == r.
dim());
5254 assert(y.
dim() == s.
dim());
5259 for(
int j = 0; j < x.
dim(); ++j)
5266 for(
int i = 0; i < y.
dim(); ++i)
5274 for(
int k =
m_hist.size() - 1; k >= 0; --k)
5285 ":\n" << ex.
what() <<
"\n");
5313 #ifdef CHECK_BASIC_DIM 5353 os <<
"DUAL_INFEASIBLE";
const VectorBase< R > & rhs() const
Returns right hand side vector.
DVector m_prim
unsimplified primal solution vector.
Rational spxAbs(const Rational &r)
Absolute.
bool isNotZero(Real a, Real eps=Param::epsilon())
returns true iff |a| > eps
Real m_opttol
dual feasibility tolerance.
DataArray< PostStep * > m_hist
vector of presolve history.
Postsolves multi aggregation.
Exception class for things that should NEVER happen.This class is derived from the SoPlex exception b...
bool LTrel(Real a, Real b, Real eps=Param::epsilon())
returns true iff relDiff(a,b) <= -eps
free variable fixed to zero.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
friend class FreeConstraintPS
Result removeRowSingleton(SPxLP &lp, const SVector &row, int &i)
remove row singletons.
DataArray< int > m_stat
preprocessing history.
bool GE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a >= b + eps
void reDim(int newdim, const bool setZero=true)
Resets DVectorBase's dimension to newdim.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
int m_keptLRhs
number of kept left- and right-hand sides
UnitVectorBase< Real > UnitVector
const VectorBase< R > & upper() const
Returns upper bound vector.
Real m_epsilon
epsilon zero.
THREADLOCAL const Real infinity
Postsolves variable bound fixing.
Result
Result of the simplification.
the problem was so much simplified that it vanished
Postsolves duplicate rows.
int m_remNzos
number of removed nonzero coefficients
int size() const
Number of used indices.
void computeMinMaxResidualActivity(SPxLP &lp, int rowNumber, int colNumber, Real &minAct, Real &maxAct)
computes the minimum and maximum residual activity for a given row and column. If colNumber is set to...
Real m_feastol
primal feasibility tolerance.
DataArray< SPxSolver::VarStatus > m_rBasisStat
basis status of rows.
Real maxAbs(Real a, Real b)
returns max(|a|,|b|)
virtual void removeCols(int perm[])
Removes multiple columns.
bool LE(Real a, Real b, Real eps=Param::epsilon())
returns true iff a <= b + eps
bool LT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a < b + eps
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
SPxLP::SPxSense m_thesense
optimization sense.
bool NE(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| > eps
virtual Result simplify(SPxLP &lp, Real eps, Real delta)
simplify SPxLP lp with identical primal and dual feasibility tolerance.
friend class DuplicateRowsPS
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
int cIdx(int j) const
returns for a given column index of the (reduced) LP the corresponding column index in the unsimplifi...
variable fixed to identical bounds.
DVector m_dual
unsimplified dual solution vector.
R & value(int n)
Reference to value of n 'th nonzero.
General methods in LP preprocessing.
Postsolves empty constraints.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
int m_keptBnds
number of kept bounds
#define ASSERT_WARN(prefix, expr)
Macro to turn some assertions into warnings.
Real m_minReduction
minimal reduction (sum of removed rows/cols) to continue simplification
void remove(int n, int m)
Remove nonzeros n thru m.
void handleExtremes(SPxLP &lp)
handles extreme values by setting them to zero or infinity.
bool m_postsolved
status of postsolving.
int rIdx(int i) const
returns for a given row index of the (reduced) LP the corresponding row index in the unsimplified LP...
virtual void unsimplify(const Vector &x, const Vector &y, const Vector &s, const Vector &r, const SPxSolver::VarStatus rows[], const SPxSolver::VarStatus cols[], bool isOptimal=true)
reconstructs an optimal solution for the unsimplified LP.
SVectorBase< R > & rowVector_w(int i)
virtual void removeRows(int perm[])
Removes multiple rows.
void fixColumn(SPxLP &lp, int i, bool correctIdx=true)
handles the fixing of a variable. correctIdx is true iff the index mapping has to be updated...
virtual const std::string what() const
returns exception message
virtual void addObjoffset(const Real val)
add objective offset.
Wrapper for different output streams and verbosity levels.
int nRows() const
Returns number of rows in LP.
Exception class for out of memory exceptions.This class is derived from the SoPlex exception base cla...
virtual void start()=0
start timer, resume accounting user, system and real time.
virtual Real stop()=0
stop timer, return accounted user time.
void spx_alloc(T &p, int n=1)
Allocate memory.
simplification could be done
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
Postsolves the case when constraints are removed due to a variable with zero objective that is free i...
int nNzos() const
Returns number of nonzeros in LP.
virtual const char * getName() const
get name of simplifying step.
friend class RowSingletonPS
Timer * m_timeUsed
user time used for simplification
nothing known about basis status (possibly due to a singular basis in transformed problem) ...
Array< DSVector > m_classSetCols
stores parallel classes with non-zero row entry
Result duplicateCols(SPxLP &lp, bool &again)
removes duplicate columns
void removeCol(SPxLP &lp, int j)
removes a column in the LP.
bool GT(Real a, Real b, Real eps=Param::epsilon())
returns true iff a > b + eps
SPxSense spxSense() const
Returns the optimization sense.
int & index(int n)
Reference to index of n 'th nonzero.
Postsolves row singletons.
virtual void changeMaxObj(const VectorBase< R > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled...
std::ostream & operator<<(std::ostream &s, const VectorBase< R > &vec)
Output operator.
Result simplifyRows(SPxLP &lp, bool &again)
performs simplification steps on the rows of the LP.
bool checkSolution(SPxLP &lp, DVector sol)
checks a solution for feasibility
#define MSG_INFO2(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO2.
#define MSG_ERROR(x)
Prints out message x if the verbosity level is at least SPxOut::ERROR.
friend class DoubletonEquationPS
Postsolves doubleton equations combined with a column singleton.
Postsolves free column singletons.
virtual void changeLower(const VectorBase< R > &newLower, bool scale=false)
Changes vector of lower bounds to newLower. scale determines whether the new data should be scaled...
virtual void changeRhs(const VectorBase< R > &newRhs, bool scale=false)
Changes right hand side vector for constraints to newRhs. scale determines whether the new data shoul...
comparator for class SVector::Element: compare nonzeros according to value
R obj(int i) const
Returns objective value of column i.
const VectorBase< R > & lhs() const
Returns left hand side vector.
DataArray< int > m_cIdx
column index vector in original LP.
Result m_result
result of the simplification.
variable set to its upper bound.
bool GTrel(Real a, Real b, Real eps=Param::epsilon())
returns true iff relDiff(a,b) > eps
void SPxQuicksort(T *keys, int end, COMPARATOR &compare, int start=0, bool type=true)
Generic QuickSort implementation.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void changeBounds(const VectorBase< R > &newLower, const VectorBase< R > &newUpper, bool scale=false)
Changes variable bounds to newLower and newUpper. scale determines whether the new data should be sca...
primal infeasibility was detected
const VectorBase< R > & maxRowObj() const
bool GErel(Real a, Real b, Real eps=Param::epsilon())
returns true iff relDiff(a,b) > -eps
variable set to its lower bound.
Generic QuickSort implementation.
Array< DSVector > m_dupCols
arrange duplicate columns w.r.t. their pClass values
int m_remRows
number of removed rows
#define MSG_INFO3(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO3.
void add(int i, const R &v)
Append one nonzero (i,v).
virtual void changeUpper(const VectorBase< R > &newUpper, bool scale=false)
Changes vector of upper bounds to newUpper. scale determines whether the new data should be scaled...
Postsolves row objectives.
bool EQ(Real a, Real b, Real eps=Param::epsilon())
returns true iff |a-b| <= eps
virtual void changeObj(const VectorBase< R > &newObj, bool scale=false)
Changes objective vector to newObj. scale determines whether the new data should be scaled...
DataArray< int > m_rIdx
row index vector in original LP.
Postsolves column singletons with zero objective.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void addCol(const LPColBase< R > &col, bool scale=false)
int dim() const
Dimension of vector.
Exception base class.This class implements a base class for our SoPlex exceptions We provide a what()...
bool m_keepbounds
keep some bounds (for boundflipping)
Everything should be within this namespace.
virtual void changeRange(const VectorBase< R > &newLhs, const VectorBase< R > &newRhs, bool scale=false)
Changes left and right hand side vectors. scale determines whether the new data should be scaled...
bool EQrel(Real a, Real b, Real eps=Param::epsilon())
returns true iff |relDiff(a,b)| <= eps
virtual bool checkBasisDim(DataArray< SPxSolver::VarStatus > rows, DataArray< SPxSolver::VarStatus > cols) const
friend class ForceConstraintPS
void handleRowObjectives(SPxLP &lp)
handle row objectives
primal unboundedness was detected
Result aggregateVars(SPxLP &lp, const SVector &row, int &i)
aggregate two variables that appear in an equation.
#define MSG_WARNING(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::WARNING.
Result duplicateRows(SPxLP &lp, bool &again)
removes duplicate rows.
Real m_cutoffbound
the cutoff bound that is found by heuristics
const VectorBase< R > & maxObj() const
Returns objective vector for maximization problem.
friend class AggregationPS
Exception class for incorrect usage of interface methods.
Result multiaggregation(SPxLP &lp, bool &again)
performs multi-aggregations of variable based upon constraint activitu.
Save arrays of arbitrary types.
Real m_objoffset
objective offset
friend class DuplicateColsPS
bool NErel(Real a, Real b, Real eps=Param::epsilon())
returns true iff |relDiff(a,b)| > eps
const SVectorBase< R > & rowVector(int i) const
Gets row vector of row i.
comparator for class SVector::Element: compare nonzeros according to index
virtual void changeRowObj(const VectorBase< R > &newRowObj, bool scale=false)
Changes row objective function vector to newRowObj. scale determines whether the new data should be s...
void trivialHeuristic(SPxLP &lp)
tries to find good lower bound solutions by applying some trivial heuristics
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
int m_chgBnds
number of changed bounds
Postsolves duplicate columns.
Result removeEmpty(SPxLP &lp)
removed empty rows and empty columns.
int size() const
return nr. of elements.
Postsolves forcing constraints.
Result simplifyDual(SPxLP &lp, bool &again)
performs simplification steps on the LP based on dual concepts.
Postsolves unconstraint constraints.
int pos(int i) const
Position of index i.
bool isConsistent() const
Consistency check.
Postsolves variable bound tightening from pseudo objective propagation.
#define MSG_INFO1(spxout, x)
Prints out message x if the verbosity level is at least SPxOut::INFO1.
int m_remCols
number of removed columns
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
const SVectorBase< R > & colVector(int i) const
Returns column vector of column i.
Postsolves variable fixing.
int nCols() const
Returns number of columns in LP.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void changeElement(int i, int j, const R &val, bool scale=false)
Changes LP element (i, j) to val. scale determines whether the new data should be scaled...
friend class FreeColSingletonPS
bool LErel(Real a, Real b, Real eps=Param::epsilon())
returns true iff relDiff(a,b) <= eps
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
virtual void changeLhs(const VectorBase< R > &newLhs, bool scale=false)
Changes left hand side vector for constraints to newLhs. scale determines whether the new data should...
Real m_pseudoobj
the pseudo objective function value
friend class FreeZeroObjVariablePS
void computeMinMaxValues(SPxLP &lp, Real side, Real val, Real minRes, Real maxRes, Real &minVal, Real &maxVal)
calculate min/max value for the multi aggregated variables
int m_addedcols
columns added by handleRowObjectives()
friend class ZeroObjColSingletonPS
bool isZero(Real a, Real eps=Param::epsilon())
returns true iff |a| <= eps
void removeRow(SPxLP &lp, int i)
removes a row in the LP.
friend class EmptyConstraintPS
virtual void reset()=0
initialize timer, set timing accounts to zero.
SPxOut * spxout
message handler
Save arrays of data objects.
SVectorBase< R > & colVector_w(int i)
Returns the LP as an LPRowSet.
int m_chgLRhs
number of change right-hand sides
Result simplifyCols(SPxLP &lp, bool &again)
performs simplification steps on the columns of the LP.
Array< DSVector > m_dupRows
arrange duplicate rows using bucket sort w.r.t. their pClass values
void reSize(int newsize)
reset size to newsize.
DVector m_slack
unsimplified slack vector.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
const VectorBase< R > & lower() const
Returns (internal and possibly scaled) lower bound vector.
virtual void execute(DVector &x, DVector &y, DVector &s, DVector &r, DataArray< SPxSolver::VarStatus > &cBasis, DataArray< SPxSolver::VarStatus > &rBasis, bool isOptimal) const
Set of indices.Class IdxSet provides a set of indices. At construction it must be given an array of i...
void spx_free(T &p)
Release memory.
DataArray< SPxSolver::VarStatus > m_cBasisStat
basis status of columns.
void propagatePseudoobj(SPxLP &lp)
tightens variable bounds by propagating the pseudo objective function value.
dual infeasibility was detected
Array< DSVector > m_classSetRows
stores parallel classes with non-zero colum entry
friend class FixVariablePS
DVector m_redCost
unsimplified reduced cost vector.