Skip to content

Commit d5ffacc

Browse files
committed
Now getting through to postsolve after eliminating a slack in presolve for adlittle
1 parent 14c13c9 commit d5ffacc

File tree

5 files changed

+81
-15
lines changed

5 files changed

+81
-15
lines changed

src/lp_data/Highs.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ HighsStatus Highs::run() {
12521252
bool have_optimal_solution = false;
12531253
// ToDo Put solution of presolved problem in a separate method
12541254

1255-
if (!this->options_.presolve_remove_slacks) {
1255+
// if (!this->options_.presolve_remove_slacks) {
12561256
HighsLp& reduced_lp = presolve_.getReducedProblem();
12571257
HighsInt num_double_slack = 0;
12581258
HighsInt num_slack = 0;
@@ -1271,19 +1271,20 @@ HighsStatus Highs::run() {
12711271
continue;
12721272
}
12731273
if (reduced_lp.row_lower_[iRow] != reduced_lp.row_upper_[iRow]) continue;
1274+
num_slack++;
1275+
printf("Column %d is slack\n", int(iCol));
12741276
double coeff = std::fabs(reduced_lp.a_matrix_.value_[reduced_lp.a_matrix_.start_[iCol]]);
12751277
if (coeff == 1.0) num_unit_coeff_slack++;
12761278
min_slack_coeff = std::min(coeff,min_slack_coeff);
12771279
max_slack_coeff = std::max(coeff,max_slack_coeff);
12781280
found_slack[iRow] = true;
1279-
num_slack++;
12801281
if (reduced_lp.col_cost_[iCol] == 0) num_zero_cost_slack++;
12811282
}
12821283
printf("grepSlack,model,col,slack,unit coeff,zero_cost,double,min coeff, max_coeff\n");
12831284
printf("grepSlack,%s,%d, %d, %d, %d, %d, %g, %g\n", this->model_.lp_.model_name_.c_str(),
12841285
int(reduced_lp.num_col_), int(num_slack), int(num_unit_coeff_slack), int(num_zero_cost_slack), int(num_double_slack),
12851286
min_slack_coeff, max_slack_coeff);
1286-
}
1287+
// }
12871288

12881289
switch (model_presolve_status_) {
12891290
case HighsPresolveStatus::kNotPresolved: {

src/presolve/HPresolve.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4360,6 +4360,11 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
43604360
break;
43614361
}
43624362

4363+
// Now consider removing slacks
4364+
if (options->presolve_remove_slacks) {
4365+
HPRESOLVE_CHECKED_CALL(removeSlacks(postsolve_stack));
4366+
}
4367+
43634368
report();
43644369
} else {
43654370
highsLogUser(options->log_options, HighsLogType::kInfo,
@@ -4375,6 +4380,62 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
43754380
return Result::kOk;
43764381
}
43774382

4383+
HPresolve::Result HPresolve::removeSlacks(HighsPostsolveStack& postsolve_stack) {
4384+
// singletonColumns data structure appears not to be retained
4385+
// throughout presolve
4386+
//
4387+
bool unit_coeff_only = true;
4388+
for (HighsInt iCol = 0; iCol != model->num_col_; ++iCol) {
4389+
if (colDeleted[iCol]) continue;
4390+
if (colsize[iCol] != 1) continue;
4391+
if (model->integrality_[iCol] == HighsVarType::kInteger) continue;
4392+
HighsInt coliter = colhead[iCol];
4393+
HighsInt iRow = Arow[coliter];
4394+
assert(Acol[coliter] == iCol);
4395+
assert(!rowDeleted[iRow]);
4396+
if (model->row_lower_[iRow] != model->row_upper_[iRow]) continue;
4397+
double lower = model->col_lower_[iCol];
4398+
double upper = model->col_upper_[iCol];
4399+
double cost = model->col_cost_[iCol];
4400+
double rhs = model->row_lower_[iRow];
4401+
double coeff = Avalue[coliter];
4402+
printf("Col %d is continuous and is singleton in equality row %d with cost %g, bounds [%g, %g], coeff %g and RHS = %g\n", int(iCol), int(iRow), cost, lower, upper, coeff, rhs);
4403+
if (unit_coeff_only && std::fabs(coeff) != 1.0) continue;
4404+
assert(coeff);
4405+
// Slack is s = (rhs - a^Tx)/coeff
4406+
//
4407+
if (coeff > 0) {
4408+
// Constraint bounds become [rhs - coeff * lower, rhs - coeff *
4409+
// upper]
4410+
model->col_lower_[iCol] = rhs - coeff * lower;
4411+
model->col_upper_[iCol] = rhs - coeff * upper;
4412+
} else {
4413+
// Constraint bounds become [rhs - coeff * upper, rhs - coeff *
4414+
// lower]
4415+
model->col_lower_[iCol] = rhs - coeff * upper;
4416+
model->col_upper_[iCol] = rhs - coeff * lower;
4417+
}
4418+
if (cost) {
4419+
// Cost is (cost * rhs / coeff) + (col_cost - (cost/coeff) row_values)^Tx
4420+
double multiplier = cost / coeff;
4421+
for (const HighsSliceNonzero& nonzero : getRowVector(iRow)) {
4422+
HighsInt local_iCol = nonzero.index();
4423+
double local_value = nonzero.value();
4424+
model->col_cost_[local_iCol] -= multiplier * local_value;
4425+
}
4426+
model->offset_ += multiplier * rhs;
4427+
}
4428+
//
4429+
postsolve_stack.slackColSubstitution(iRow, iCol, rhs, cost, lower, upper, coeff,
4430+
getColumnVector(iCol));
4431+
markColDeleted(iCol);
4432+
4433+
unlink(coliter);
4434+
4435+
}
4436+
return Result::kOk;
4437+
}
4438+
43784439
HPresolve::Result HPresolve::checkLimits(HighsPostsolveStack& postsolve_stack) {
43794440
size_t numreductions = postsolve_stack.numReductions();
43804441

src/presolve/HPresolve.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,8 @@ class HPresolve {
269269

270270
Result presolve(HighsPostsolveStack& postsolve_stack);
271271

272+
Result removeSlacks(HighsPostsolveStack& postsolve_stack);
273+
272274
Result checkLimits(HighsPostsolveStack& postsolve_stack);
273275

274276
void storeCurrentProblemSize();

src/presolve/HighsPostsolveStack.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,6 +1355,11 @@ void HighsPostsolveStack::SlackColSubstitution::undo(
13551355
const HighsOptions& options, const std::vector<Nonzero>& rowValues,
13561356
const std::vector<Nonzero>& colValues, HighsSolution& solution,
13571357
HighsBasis& basis) {
1358+
1359+
assert(111==222);
1360+
1361+
1362+
13581363
// a (removed) cut may have been used in this reduction.
13591364
bool isModelRow = static_cast<size_t>(row) < solution.row_value.size();
13601365

@@ -1396,7 +1401,7 @@ void HighsPostsolveStack::SlackColSubstitution::undo(
13961401

13971402
basis.col_status[col] = HighsBasisStatus::kBasic;
13981403
if (isModelRow)
1399-
basis.row_status[row] = computeRowStatus(solution.row_dual[row], rowType);
1404+
basis.row_status[row] = computeRowStatus(solution.row_dual[row], RowType::kEq);
14001405
}
14011406

14021407
} // namespace presolve

src/presolve/HighsPostsolveStack.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,11 @@ class HighsPostsolveStack {
222222
struct SlackColSubstitution {
223223
double rhs;
224224
double colCost;
225+
double colLower;
226+
double colUpper;
227+
double colCoeff;
225228
HighsInt row;
226229
HighsInt col;
227-
RowType rowType;
228230

229231
void undo(const HighsOptions& options,
230232
const std::vector<Nonzero>& rowValues,
@@ -337,21 +339,16 @@ class HighsPostsolveStack {
337339
reductionAdded(ReductionType::kFreeColSubstitution);
338340
}
339341

340-
template <typename RowStorageFormat, typename ColStorageFormat>
342+
template <typename ColStorageFormat>
341343
void slackColSubstitution(HighsInt row, HighsInt col, double rhs,
342-
double colCost, RowType rowType,
343-
const HighsMatrixSlice<RowStorageFormat>& rowVec,
344-
const HighsMatrixSlice<ColStorageFormat>& colVec) {
345-
rowValues.clear();
346-
for (const HighsSliceNonzero& rowVal : rowVec)
347-
rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());
348-
344+
double colCost, double colLower, double colUpper, double colCoeff,
345+
const HighsMatrixSlice<ColStorageFormat>& colVec) {
349346
colValues.clear();
350347
for (const HighsSliceNonzero& colVal : colVec)
351348
colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());
352349

353-
reductionValues.push(SlackColSubstitution{rhs, colCost, origRowIndex[row],
354-
origColIndex[col], rowType});
350+
reductionValues.push(SlackColSubstitution{rhs, colCost, colLower, colUpper, colCoeff, origRowIndex[row],
351+
origColIndex[col]});
355352
reductionValues.push(rowValues);
356353
reductionValues.push(colValues);
357354
reductionAdded(ReductionType::kSlackColSubstitution);

0 commit comments

Comments
 (0)