Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions FEATURES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ Forcing column reduction now checks the bound on the column dual rather than whe

Now handling correctly the case where an infeasible MIP has a feasible relaxation, so no ray is computed fixing [#2415](https://github.com/ERGO-Code/HiGHS/issues/2415)

Fixed minor bug exposed by [#2441](https://github.com/ERGO-Code/HiGHS/issues/2441) in Highs::setSolution() for a sparse user solution when the moidel is empty, and only clearing the dual data before solving with modified objective in Highs::multiobjectiveSolve() so that user-supplied solution is not cleared.


11 changes: 11 additions & 0 deletions highs/Highs.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ class Highs {
*/
HighsStatus clearSolver();

/**
* @brief Clear all dual data associated with the model
*/
HighsStatus clearSolverDualData();

/**
* Methods for model input
*/
Expand Down Expand Up @@ -1542,6 +1547,12 @@ class Highs {
// invalidateRanging(), invalidateInfo(), invalidateEkk() and
// invalidateIis()
void invalidateSolverData();

// Invalidates all solver dual data in Highs class members by calling
// invalidateModelStatus(), invalidateRanging(), and invalidateInfo()
//
// Used when only the objective changes
void invalidateSolverDualData();
//
// Invalidates the model status, solution_ and info_
void invalidateModelStatusSolutionAndInfo();
Expand Down
24 changes: 18 additions & 6 deletions highs/lp_data/Highs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,13 @@ HighsStatus Highs::clearSolver() {
return returnFromHighs(return_status);
}

HighsStatus Highs::clearSolverDualData() {
HighsStatus return_status = HighsStatus::kOk;
clearDerivedModelProperties();
invalidateSolverDualData();
return returnFromHighs(return_status);
}

HighsStatus Highs::setOptionValue(const std::string& option, const bool value) {
if (setLocalOptionValue(options_.log_options, option, options_.records,
value) == OptionStatus::kOk)
Expand Down Expand Up @@ -2261,16 +2268,17 @@ HighsStatus Highs::setSolution(const HighsSolution& solution) {
HighsStatus Highs::setSolution(const HighsInt num_entries,
const HighsInt* index, const double* value) {
HighsStatus return_status = HighsStatus::kOk;
if (model_.lp_.num_col_ == 0) return return_status;
// Warn about duplicates in index
HighsInt num_duplicates = 0;
std::vector<bool> is_set;
is_set.assign(model_.lp_.num_col_, false);
for (HighsInt iX = 0; iX < num_entries; iX++) {
HighsInt iCol = index[iX];
if (iCol < 0 || iCol > model_.lp_.num_col_) {
if (iCol < 0 || iCol >= model_.lp_.num_col_) {
highsLogUser(options_.log_options, HighsLogType::kError,
"setSolution: User solution index %d has value %d out of "
"range [0, %d)",
"range [0, %d)\n",
int(iX), int(iCol), int(model_.lp_.num_col_));
return HighsStatus::kError;
} else if (value[iX] < model_.lp_.col_lower_[iCol] -
Expand All @@ -2280,7 +2288,7 @@ HighsStatus Highs::setSolution(const HighsInt num_entries,
value[iX]) {
highsLogUser(options_.log_options, HighsLogType::kError,
"setSolution: User solution value %d of %g is infeasible "
"for bounds [%g, %g]",
"for bounds [%g, %g]\n",
int(iX), value[iX], model_.lp_.col_lower_[iCol],
model_.lp_.col_upper_[iCol]);
return HighsStatus::kError;
Expand Down Expand Up @@ -3634,15 +3642,19 @@ void Highs::clearStandardFormLp() {
}

void Highs::invalidateSolverData() {
invalidateModelStatus();
invalidateSolverDualData();
invalidateSolution();
invalidateBasis();
invalidateRanging();
invalidateInfo();
invalidateEkk();
invalidateIis();
}

void Highs::invalidateSolverDualData() {
invalidateModelStatus();
invalidateRanging();
invalidateInfo();
}

void Highs::invalidateModelStatusSolutionAndInfo() {
invalidateModelStatus();
invalidateSolution();
Expand Down
7 changes: 6 additions & 1 deletion highs/lp_data/HighsInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3948,7 +3948,12 @@ HighsStatus Highs::multiobjectiveSolve() {
highsLogUser(options_.log_options, HighsLogType::kInfo, "%s",
multi_objective_log->str().c_str());
}
this->clearSolver();
// Solving with a different objective, but don't call
// this->clearSolver() since this loses the current solution - that
// may have been provided by the user (#2419). Just clear the dual
// data.
//
this->clearSolverDualData();
if (this->options_.blend_multi_objectives) {
// Objectives are blended by weight and minimized
lp.offset_ = 0;
Expand Down
Loading