Skip to content

Commit b32cfd0

Browse files
committed
Tidied and formatted
1 parent b14bbe1 commit b32cfd0

File tree

9 files changed

+98
-88
lines changed

9 files changed

+98
-88
lines changed

check/TestPresolve.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ TEST_CASE("presolve-slacks", "[highs_test_presolve]") {
616616
lp.a_matrix_.index_ = {0, 0};
617617
lp.a_matrix_.value_ = {1, 1};
618618
Highs h;
619-
// h.setOptionValue("output_flag", dev_run);
619+
h.setOptionValue("output_flag", dev_run);
620620
REQUIRE(h.passModel(lp) == HighsStatus::kOk);
621621
REQUIRE(h.presolve() == HighsStatus::kOk);
622622
REQUIRE(h.getPresolvedLp().num_col_ == 0);
@@ -632,10 +632,10 @@ TEST_CASE("presolve-slacks", "[highs_test_presolve]") {
632632
lp.a_matrix_.start_ = {0, 2, 4, 5, 6};
633633
lp.a_matrix_.index_ = {0, 1, 0, 1, 0, 1};
634634
lp.a_matrix_.value_ = {1, 1, 2, 4, 1, 1};
635-
635+
REQUIRE(h.setOptionValue("presolve_remove_slacks", true) == HighsStatus::kOk);
636636
REQUIRE(h.passModel(lp) == HighsStatus::kOk);
637637
REQUIRE(h.run() == HighsStatus::kOk);
638638
REQUIRE(h.presolve() == HighsStatus::kOk);
639-
// REQUIRE(h.getPresolvedLp().num_col_ == 2);
640-
// REQUIRE(h.getPresolvedLp().num_row_ == 2);
639+
REQUIRE(h.getPresolvedLp().num_col_ == 2);
640+
REQUIRE(h.getPresolvedLp().num_row_ == 2);
641641
}

src/lp_data/Highs.cpp

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,40 +1251,46 @@ HighsStatus Highs::run() {
12511251
// Run solver.
12521252
bool have_optimal_solution = false;
12531253
// ToDo Put solution of presolved problem in a separate method
1254-
1254+
12551255
// if (!this->options_.presolve_remove_slacks) {
1256-
HighsLp& reduced_lp = presolve_.getReducedProblem();
1257-
HighsInt num_double_slack = 0;
1258-
HighsInt num_slack = 0;
1259-
HighsInt num_zero_cost_slack = 0;
1260-
HighsInt num_unit_coeff_slack = 0;
1261-
double min_slack_coeff = kHighsInf;
1262-
double max_slack_coeff = -kHighsInf;
1263-
std::vector<bool> found_slack;
1264-
found_slack.assign(reduced_lp.num_row_, false);
1265-
for (HighsInt iCol = 0; iCol < reduced_lp.num_col_; iCol++) {
1266-
HighsInt nnz = reduced_lp.a_matrix_.start_[iCol+1] - reduced_lp.a_matrix_.start_[iCol];
1267-
if (nnz != 1) continue;
1268-
HighsInt iRow = reduced_lp.a_matrix_.index_[reduced_lp.a_matrix_.start_[iCol]];
1269-
if (found_slack[iRow]) {
1270-
num_double_slack++;
1271-
continue;
1272-
}
1273-
if (reduced_lp.row_lower_[iRow] != reduced_lp.row_upper_[iRow]) continue;
1274-
num_slack++;
1275-
printf("Column %d is slack\n", int(iCol));
1276-
double coeff = std::fabs(reduced_lp.a_matrix_.value_[reduced_lp.a_matrix_.start_[iCol]]);
1277-
if (coeff == 1.0) num_unit_coeff_slack++;
1278-
min_slack_coeff = std::min(coeff,min_slack_coeff);
1279-
max_slack_coeff = std::max(coeff,max_slack_coeff);
1280-
found_slack[iRow] = true;
1281-
if (reduced_lp.col_cost_[iCol] == 0) num_zero_cost_slack++;
1256+
HighsLp& reduced_lp = presolve_.getReducedProblem();
1257+
HighsInt num_double_slack = 0;
1258+
HighsInt num_slack = 0;
1259+
HighsInt num_zero_cost_slack = 0;
1260+
HighsInt num_unit_coeff_slack = 0;
1261+
double min_slack_coeff = kHighsInf;
1262+
double max_slack_coeff = -kHighsInf;
1263+
std::vector<bool> found_slack;
1264+
found_slack.assign(reduced_lp.num_row_, false);
1265+
for (HighsInt iCol = 0; iCol < reduced_lp.num_col_; iCol++) {
1266+
HighsInt nnz = reduced_lp.a_matrix_.start_[iCol + 1] -
1267+
reduced_lp.a_matrix_.start_[iCol];
1268+
if (nnz != 1) continue;
1269+
HighsInt iRow =
1270+
reduced_lp.a_matrix_.index_[reduced_lp.a_matrix_.start_[iCol]];
1271+
if (found_slack[iRow]) {
1272+
num_double_slack++;
1273+
continue;
12821274
}
1283-
printf("grepSlack,model,col,slack,unit coeff,zero_cost,double,min coeff, max_coeff\n");
1284-
printf("grepSlack,%s,%d, %d, %d, %d, %d, %g, %g\n", this->model_.lp_.model_name_.c_str(),
1285-
int(reduced_lp.num_col_), int(num_slack), int(num_unit_coeff_slack), int(num_zero_cost_slack), int(num_double_slack),
1286-
min_slack_coeff, max_slack_coeff);
1287-
// }
1275+
if (reduced_lp.row_lower_[iRow] != reduced_lp.row_upper_[iRow]) continue;
1276+
num_slack++;
1277+
printf("Column %d is slack\n", int(iCol));
1278+
double coeff = std::fabs(
1279+
reduced_lp.a_matrix_.value_[reduced_lp.a_matrix_.start_[iCol]]);
1280+
if (coeff == 1.0) num_unit_coeff_slack++;
1281+
min_slack_coeff = std::min(coeff, min_slack_coeff);
1282+
max_slack_coeff = std::max(coeff, max_slack_coeff);
1283+
found_slack[iRow] = true;
1284+
if (reduced_lp.col_cost_[iCol] == 0) num_zero_cost_slack++;
1285+
}
1286+
printf(
1287+
"grepSlack,model,col,slack,unit coeff,zero_cost,double,min coeff, "
1288+
"max_coeff\n");
1289+
printf("grepSlack,%s,%d, %d, %d, %d, %d, %g, %g\n",
1290+
this->model_.lp_.model_name_.c_str(), int(reduced_lp.num_col_),
1291+
int(num_slack), int(num_unit_coeff_slack), int(num_zero_cost_slack),
1292+
int(num_double_slack), min_slack_coeff, max_slack_coeff);
1293+
// }
12881294

12891295
switch (model_presolve_status_) {
12901296
case HighsPresolveStatus::kNotPresolved: {
@@ -1310,7 +1316,7 @@ HighsStatus Highs::run() {
13101316
break;
13111317
}
13121318
case HighsPresolveStatus::kReduced: {
1313-
HighsLp& reduced_lp = presolve_.getReducedProblem();
1319+
HighsLp& reduced_lp = presolve_.getReducedProblem();
13141320
reduced_lp.setMatrixDimensions();
13151321
if (kAllowDeveloperAssert) {
13161322
// Validate the reduced LP

src/lp_data/HighsOptions.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,7 @@ struct HighsOptionsStruct {
508508
presolve_substitution_maxfillin(0),
509509
presolve_rule_off(0),
510510
presolve_rule_logging(false),
511-
presolve_remove_slacks(false),
511+
presolve_remove_slacks(false),
512512
simplex_initial_condition_check(false),
513513
no_unnecessary_rebuild_refactor(false),
514514
simplex_initial_condition_tolerance(0.0),
@@ -1326,9 +1326,9 @@ class HighsOptions : public HighsOptionsStruct {
13261326
advanced, &presolve_rule_logging, false);
13271327
records.push_back(record_bool);
13281328

1329-
record_bool = new OptionRecordBool(
1330-
"presolve_remove_slacks", "Remove slacks after presolve",
1331-
advanced, &presolve_remove_slacks, true);//false);
1329+
record_bool = new OptionRecordBool("presolve_remove_slacks",
1330+
"Remove slacks after presolve", advanced,
1331+
&presolve_remove_slacks, false);
13321332
records.push_back(record_bool);
13331333

13341334
record_int = new OptionRecordInt(

src/presolve/HPresolve.cpp

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4380,7 +4380,8 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
43804380
return Result::kOk;
43814381
}
43824382

4383-
HPresolve::Result HPresolve::removeSlacks(HighsPostsolveStack& postsolve_stack) {
4383+
HPresolve::Result HPresolve::removeSlacks(
4384+
HighsPostsolveStack& postsolve_stack) {
43844385
// singletonColumns data structure appears not to be retained
43854386
// throughout presolve
43864387
//
@@ -4399,7 +4400,10 @@ HPresolve::Result HPresolve::removeSlacks(HighsPostsolveStack& postsolve_stack)
43994400
double cost = model->col_cost_[iCol];
44004401
double rhs = model->row_lower_[iRow];
44014402
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+
printf(
4404+
"Col %d is continuous and is singleton in equality row %d with cost "
4405+
"%g, bounds [%g, %g], coeff %g and RHS = %g\n",
4406+
int(iCol), int(iRow), cost, lower, upper, coeff, rhs);
44034407
if (unit_coeff_only && std::fabs(coeff) != 1.0) continue;
44044408
assert(coeff);
44054409
// Slack is s = (rhs - a^Tx)/coeff
@@ -4409,26 +4413,27 @@ HPresolve::Result HPresolve::removeSlacks(HighsPostsolveStack& postsolve_stack)
44094413
// For coeff > 0 [rhs - coeff * upper, rhs - coeff * lower]
44104414
//
44114415
// For coeff < 0 [rhs - coeff * lower, rhs - coeff * upper]
4412-
model->row_lower_[iRow] = coeff > 0 ? rhs - coeff * upper : rhs - coeff * lower;
4413-
model->row_upper_[iRow] = coeff > 0 ? rhs - coeff * lower : rhs - coeff * upper;
4416+
model->row_lower_[iRow] =
4417+
coeff > 0 ? rhs - coeff * upper : rhs - coeff * lower;
4418+
model->row_upper_[iRow] =
4419+
coeff > 0 ? rhs - coeff * lower : rhs - coeff * upper;
44144420
if (cost) {
44154421
// Cost is (cost * rhs / coeff) + (col_cost - (cost/coeff) row_values)^Tx
44164422
double multiplier = cost / coeff;
44174423
for (const HighsSliceNonzero& nonzero : getRowVector(iRow)) {
4418-
HighsInt local_iCol = nonzero.index();
4419-
double local_value = nonzero.value();
4420-
model->col_cost_[local_iCol] -= multiplier * local_value;
4424+
HighsInt local_iCol = nonzero.index();
4425+
double local_value = nonzero.value();
4426+
model->col_cost_[local_iCol] -= multiplier * local_value;
44214427
}
44224428
model->offset_ += multiplier * rhs;
44234429
}
4424-
//
4425-
postsolve_stack.slackColSubstitution(iRow, iCol, rhs, cost, lower, upper, //coeff,
4426-
getRowVector(iRow),
4427-
getColumnVector(iCol));
4430+
//
4431+
postsolve_stack.slackColSubstitution(iRow, iCol, rhs, cost,
4432+
getRowVector(iRow));
4433+
44284434
markColDeleted(iCol);
44294435

44304436
unlink(coliter);
4431-
44324437
}
44334438
return Result::kOk;
44344439
}

src/presolve/HPresolve.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ class HPresolve {
270270
Result presolve(HighsPostsolveStack& postsolve_stack);
271271

272272
Result removeSlacks(HighsPostsolveStack& postsolve_stack);
273-
273+
274274
Result checkLimits(HighsPostsolveStack& postsolve_stack);
275275

276276
void storeCurrentProblemSize();

src/presolve/HighsPostsolveStack.cpp

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1353,9 +1353,7 @@ void HighsPostsolveStack::DuplicateColumn::transformToPresolvedSpace(
13531353

13541354
void HighsPostsolveStack::SlackColSubstitution::undo(
13551355
const HighsOptions& options, const std::vector<Nonzero>& rowValues,
1356-
const std::vector<Nonzero>& colValues, HighsSolution& solution,
1357-
HighsBasis& basis) {
1358-
1356+
HighsSolution& solution, HighsBasis& basis) {
13591357
// Taken from HighsPostsolveStack::FreeColSubstitution::undo(
13601358
//
13611359
// a (removed) cut may have been used in this reduction.
@@ -1378,33 +1376,47 @@ void HighsPostsolveStack::SlackColSubstitution::undo(
13781376

13791377
assert(colCoef != 0);
13801378
// Row values aren't fully postsolved, so why do this?
1381-
if (isModelRow) solution.row_value[row] =
1379+
if (isModelRow)
1380+
solution.row_value[row] =
13821381
double(rowValue + colCoef * solution.col_value[col]);
1383-
printf("HighsPostsolveStack::SlackColSubstitution::undo rowValue = %g\n", double(rowValue));
1382+
13841383
solution.col_value[col] = double((rhs - rowValue) / colCoef);
1384+
printf(
1385+
"\nHighsPostsolveStack::SlackColSubstitution::undo rowValue = %g; "
1386+
"colValue = %g\n",
1387+
double(rowValue), solution.col_value[col]);
13851388

13861389
// if no dual values requested, return here
13871390
if (!solution.dual_valid) return;
13881391

13891392
// compute the row dual value such that reduced cost of basic column is 0
1393+
double save_row_dual = solution.row_dual[row];
13901394
if (isModelRow) {
13911395
solution.row_dual[row] = 0;
1392-
HighsCDouble dualval = colCost;
1393-
for (const auto& colVal : colValues) {
1394-
if (static_cast<size_t>(colVal.index) < solution.row_dual.size())
1395-
dualval -= colVal.value * solution.row_dual[colVal.index];
1396-
}
1396+
HighsCDouble dualval = HighsCDouble(colCost);
1397+
dualval = -colCoef * solution.row_dual[row];
13971398
solution.row_dual[row] = double(dualval / colCoef);
13981399
}
13991400

14001401
solution.col_dual[col] = 0;
1402+
printf(
1403+
"HighsPostsolveStack::SlackColSubstitution::undo OgRowDual = %g; rowDual "
1404+
"= %g; colDual = %g\n",
1405+
save_row_dual, solution.row_dual[row], solution.col_dual[col]);
14011406

14021407
// set basis status if necessary
14031408
if (!basis.valid) return;
14041409

14051410
basis.col_status[col] = HighsBasisStatus::kBasic;
1411+
HighsBasisStatus save_row_basis_status = basis.row_status[row];
14061412
if (isModelRow)
1407-
basis.row_status[row] = computeRowStatus(solution.row_dual[row], RowType::kEq);
1413+
basis.row_status[row] =
1414+
computeRowStatus(solution.row_dual[row], RowType::kEq);
1415+
printf(
1416+
"HighsPostsolveStack::SlackColSubstitution::undo OgRowStatus = %d; "
1417+
"RowStatus = %d; ColStatus = %d\n",
1418+
int(save_row_basis_status), int(basis.row_status[row]),
1419+
int(basis.col_status[col]));
14081420
}
14091421

14101422
} // namespace presolve

src/presolve/HighsPostsolveStack.h

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -222,15 +222,11 @@ class HighsPostsolveStack {
222222
struct SlackColSubstitution {
223223
double rhs;
224224
double colCost;
225-
double colLower;
226-
double colUpper;
227-
// double colCoeff;
228225
HighsInt row;
229226
HighsInt col;
230227

231228
void undo(const HighsOptions& options,
232-
const std::vector<Nonzero>& rowValues,
233-
const std::vector<Nonzero>& colValues, HighsSolution& solution,
229+
const std::vector<Nonzero>& rowValues, HighsSolution& solution,
234230
HighsBasis& basis);
235231
};
236232

@@ -339,24 +335,17 @@ class HighsPostsolveStack {
339335
reductionAdded(ReductionType::kFreeColSubstitution);
340336
}
341337

342-
template <typename RowStorageFormat, typename ColStorageFormat>
338+
template <typename RowStorageFormat>
343339
void slackColSubstitution(HighsInt row, HighsInt col, double rhs,
344-
double colCost, double colLower, double colUpper, //double colCoeff,
345-
const HighsMatrixSlice<RowStorageFormat>& rowVec,
346-
const HighsMatrixSlice<ColStorageFormat>& colVec) {
340+
double colCost,
341+
const HighsMatrixSlice<RowStorageFormat>& rowVec) {
347342
rowValues.clear();
348343
for (const HighsSliceNonzero& rowVal : rowVec)
349344
rowValues.emplace_back(origColIndex[rowVal.index()], rowVal.value());
350345

351-
colValues.clear();
352-
for (const HighsSliceNonzero& colVal : colVec)
353-
colValues.emplace_back(origRowIndex[colVal.index()], colVal.value());
354-
355-
reductionValues.push(SlackColSubstitution{rhs, colCost, colLower, colUpper, //colCoeff,
356-
origRowIndex[row],
357-
origColIndex[col]});
346+
reductionValues.push(SlackColSubstitution{rhs, colCost, origRowIndex[row],
347+
origColIndex[col]});
358348
reductionValues.push(rowValues);
359-
reductionValues.push(colValues);
360349
reductionAdded(ReductionType::kSlackColSubstitution);
361350
}
362351

@@ -749,10 +738,9 @@ class HighsPostsolveStack {
749738
}
750739
case ReductionType::kSlackColSubstitution: {
751740
SlackColSubstitution reduction;
752-
reductionValues.pop(colValues);
753741
reductionValues.pop(rowValues);
754742
reductionValues.pop(reduction);
755-
reduction.undo(options, rowValues, colValues, solution, basis);
743+
reduction.undo(options, rowValues, solution, basis);
756744
break;
757745
}
758746
default:
@@ -934,10 +922,9 @@ class HighsPostsolveStack {
934922
}
935923
case ReductionType::kSlackColSubstitution: {
936924
SlackColSubstitution reduction;
937-
reductionValues.pop(colValues);
938925
reductionValues.pop(rowValues);
939926
reductionValues.pop(reduction);
940-
reduction.undo(options, rowValues, colValues, solution, basis);
927+
reduction.undo(options, rowValues, solution, basis);
941928
break;
942929
}
943930
}

src/qpsolver/dantzigpricing.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ class DantzigPricing : public Pricing {
5252

5353
public:
5454
DantzigPricing(Runtime& rt, Basis& bas, ReducedCosts& rc)
55-
// clang-format off
55+
// clang-format off
5656
: runtime(rt), basis(bas), redcosts(rc) {};
5757
// clang-format on
5858
HighsInt price(const QpVector& x, const QpVector& gradient) {

src/qpsolver/devexpricing.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ class DevexPricing : public Pricing {
5858
: runtime(rt),
5959
basis(bas),
6060
redcosts(rc),
61-
// clang-format off
61+
// clang-format off
6262
weights(std::vector<double>(rt.instance.num_var, 1.0)) {};
6363
// clang-format on
6464

0 commit comments

Comments
 (0)