Skip to content

Commit 5293d6d

Browse files
committed
Merge branch 'latest' of https://github.com/ERGO-Code/HiGHS into fix-2290
2 parents 7cf807d + f74f972 commit 5293d6d

File tree

6 files changed

+31
-29
lines changed

6 files changed

+31
-29
lines changed

check/TestMipSolver.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ TEST_CASE("MIP-distillation", "[highs_test_mip_solver]") {
2727
highs.resetGlobalScheduler(true);
2828
}
2929

30-
// Fails but the cases work separately in
31-
// MIP-rowless-1 and
30+
// Fails but the cases work separately in
31+
// MIP-rowless-1 and
3232
// MIP-rowless-2 below
3333
// TEST_CASE("MIP-rowless", "[highs_test_mip_solver]") {
3434
// Highs highs;
@@ -844,7 +844,6 @@ void rowlessMIP1(Highs& highs) {
844844
// solve(highs, kHighsOffString, require_model_status, optimal_objective);
845845
}
846846

847-
848847
void rowlessMIP2(Highs& highs) {
849848
HighsLp lp;
850849
HighsModelStatus require_model_status;

highs/lp_data/HConst.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,8 @@ enum PresolveRuleType : int {
262262
kPresolveRuleDependentFreeCols,
263263
kPresolveRuleAggregator,
264264
kPresolveRuleParallelRowsAndCols,
265-
kPresolveRuleMax = kPresolveRuleParallelRowsAndCols,
265+
kPresolveRuleProbing,
266+
kPresolveRuleMax = kPresolveRuleProbing,
266267
kPresolveRuleLastAllowOff = kPresolveRuleMax,
267268
kPresolveRuleCount,
268269
};

highs/lp_data/HighsModelUtils.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1421,6 +1421,8 @@ std::string utilPresolveRuleTypeToString(const HighsInt rule_type) {
14211421
return "Aggregator";
14221422
} else if (rule_type == kPresolveRuleParallelRowsAndCols) {
14231423
return "Parallel rows and columns";
1424+
} else if (rule_type == kPresolveRuleProbing) {
1425+
return "Probing";
14241426
}
14251427
assert(1 == 0);
14261428
return "????";

highs/mip/HighsFeasibilityJump.cpp

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -112,16 +112,6 @@ HighsModelStatus HighsMipSolverData::feasibilityJump() {
112112
status.solution + status.numVars);
113113
objective_function_value =
114114
model->offset_ + sense_multiplier * status.solutionObjectiveValue;
115-
if (verbosity > 0) {
116-
printf("Feasibility Jump has found a solution");
117-
if (model->num_col_ < 10) {
118-
printf(" [");
119-
for (HighsInt col = 0; col < std::min(10, model->num_col_); ++col)
120-
printf(" %g", col_value[col]);
121-
printf("]");
122-
}
123-
printf(" with objective %g\n", objective_function_value);
124-
}
125115
}
126116
if (status.effortSinceLastImprovement > kMaxEffortSinceLastImprovement ||
127117
status.totalEffort > kMaxTotalEffort) {
@@ -131,24 +121,13 @@ HighsModelStatus HighsMipSolverData::feasibilityJump() {
131121
}
132122
};
133123

134-
if (verbosity > 0)
135-
printf(
136-
"Feasibility Jump: kMaxTotalEffort = %zd; "
137-
"kMaxEffortSinceLastImprovement = %zd\n",
138-
kMaxTotalEffort, kMaxEffortSinceLastImprovement);
139124
solver.solve(col_value.data(), fjControlCallback);
140125

141126
if (found_integer_feasible_solution) {
142127
// Initial assignments that violate integrality or column bounds can lead to
143128
// infeasible results. Even if those initial assignments should not occur,
144129
// use trySolution rather than addIncumbent for an explicit check.
145-
bool is_really_feasible =
146-
trySolution(col_value, kSolutionSourceFeasibilityJump);
147-
if (!is_really_feasible) {
148-
highsLogUser(log_options, HighsLogType::kInfo,
149-
"Discarding infeasible result from Feasibility Jump\n");
150-
}
151-
assert(is_really_feasible);
130+
trySolution(col_value, kSolutionSourceFeasibilityJump);
152131
}
153132
return HighsModelStatus::kNotset;
154133
#endif

highs/presolve/HPresolve.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4371,7 +4371,8 @@ HPresolve::Result HPresolve::presolve(HighsPostsolveStack& postsolve_stack) {
43714371
bool trySparsify =
43724372
mipsolver != nullptr || !options->lp_presolve_requires_basis_postsolve;
43734373
#endif
4374-
bool tryProbing = mipsolver != nullptr;
4374+
bool tryProbing =
4375+
mipsolver != nullptr && analysis_.allow_rule_[kPresolveRuleProbing];
43754376
HighsInt numCliquesBeforeProbing = -1;
43764377
bool domcolAfterProbingCalled = false;
43774378
bool dependentEquationsCalled = mipsolver != nullptr;
@@ -4750,14 +4751,21 @@ HighsModelStatus HPresolve::run(HighsPostsolveStack& postsolve_stack) {
47504751
}
47514752
mipsolver->mipdata_->lower_bound = 0;
47524753
} else {
4753-
assert(model->num_row_ == 0);
4754+
// An LP with no columns must have no rows, unless the reduction
4755+
// limit has been reached
4756+
assert(model->num_row_ == 0 ||
4757+
postsolve_stack.numReductions() >= reductionLimit);
47544758
if (model->num_row_ != 0) {
47554759
presolve_status_ = HighsPresolveStatus::kNotPresolved;
47564760
return HighsModelStatus::kNotset;
47574761
}
47584762
}
47594763
presolve_status_ = HighsPresolveStatus::kReducedToEmpty;
4760-
return HighsModelStatus::kOptimal;
4764+
// Make sure that zero row activity from the column-less model is
4765+
// consistent with the bounds
4766+
return model->num_row_ == 0 || zeroRowActivityFeasible()
4767+
? HighsModelStatus::kOptimal
4768+
: HighsModelStatus::kInfeasible;
47614769
} else if (postsolve_stack.numReductions() > 0) {
47624770
// Reductions performed
47634771
presolve_status_ = HighsPresolveStatus::kReduced;
@@ -6891,6 +6899,17 @@ HPresolve::Result HPresolve::sparsify(HighsPostsolveStack& postsolve_stack) {
68916899
return Result::kOk;
68926900
}
68936901

6902+
bool HPresolve::zeroRowActivityFeasible() const {
6903+
// Check that zero row activity is feasible - called when reduced model
6904+
// has no columns to assess whether the HighsModelStatus returned is
6905+
// kOptimal or kInfeasible (as was required for 2326)
6906+
for (HighsInt iRow = 0; iRow < model->num_row_; iRow++)
6907+
if (model->row_lower_[iRow] > primal_feastol ||
6908+
model->row_upper_[iRow] < -primal_feastol)
6909+
return false;
6910+
return true;
6911+
}
6912+
68946913
HighsInt HPresolve::debugGetCheckCol() const {
68956914
const std::string check_col_name = ""; // c37";
68966915
HighsInt check_col = -1;

highs/presolve/HPresolve.h

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

395395
HighsPresolveStatus getPresolveStatus() const { return presolve_status_; }
396396

397+
bool zeroRowActivityFeasible() const;
398+
397399
HighsInt debugGetCheckCol() const;
398400
HighsInt debugGetCheckRow() const;
399401

0 commit comments

Comments
 (0)