Skip to content

Commit

Permalink
Multi-obj: HiGHS model update #239
Browse files Browse the repository at this point in the history
  • Loading branch information
glebbelov committed May 22, 2024
1 parent 79aa163 commit 9cf6faa
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 23 deletions.
2 changes: 1 addition & 1 deletion include/mp/backend-std.h
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,7 @@ class StdBackend :
while (GetMM().PrepareSolveIteration()) {
Solve();
SetStatus( GetSolveResult() ); // before GetSolution()
sol_last_ = GetSolution();
sol_last_ = GetSolution(); // @todo don't need it in the last iteration
GetMM().ProcessIterationSolution(sol_last_, status_.first);
}
}
Expand Down
23 changes: 19 additions & 4 deletions include/mp/flat/converter_multiobj.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,21 +107,36 @@ class MOManager {
obj_new_ = MPD( get_objectives() ); // no linking
if (MPD( GetEnv() ).verbose_mode())
MPD( GetEnv() ).Print(
"\n\nMULTIOBJECTIVE MODE WITH {} OBJECTIVES.\n", obj_new_.size());
"\n\n"
"==============================================================================\n"
"MULTI-OBJECTIVE MODE: starting with {} objectives ...\n"
"==============================================================================\n"
"==============================================================================\n\n"
, obj_new_.size());
}

/// Do prepare next solve
bool DoPrepareNextMultiobjSolve() {
if (++i_current_obj_ >= obj_new_.size()) {
status_ = MOManagerStatus::FINISHED;
MPD( GetEnv() ).Print(
"\n\n"
"==============================================================================\n"
"MULTI-OBJECTIVE MODE: done.\n\n");
return false; // all done
}
if (MPD( GetEnv() ).verbose_mode())
MPD( GetEnv() ).Print(
"\n\n"
"MULTI-OBJECTIVE MODE: objective {} (out of {}) ...\n"
"==============================================================================\n\n"
, i_current_obj_+1, obj_new_.size());
MPD( GetModelAPI() ).InitProblemModificationPhase(
MPD( GetModelInfo() ));
ReplaceCurrentObj();
if (i_current_obj_)
RestrictLastObjVal();
if (MPD( GetEnv() ).verbose_mode())
MPD( GetEnv() ).Print(
"\n\nMULTIOBJECTIVE MODE: OBJECTIVE {} OUT OF {}.\n", i_current_obj_+1, obj_new_.size());
MPD( GetModelAPI() ).FinishProblemModificationPhase();
return true;
}

Expand Down
36 changes: 20 additions & 16 deletions solvers/highsmp/highsmpmodelapi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@ void HighsModelAPI::AddVariables(const VarArrayDef& v) {

void HighsModelAPI::SetLinearObjective( int iobj, const LinearObjective& lo ) {
if (iobj < 1) {
// Highs_changeObjectiveOffset(highs, offset); TODO offset?
HIGHS_CCALL(Highs_changeColsCostBySet(lp(), lo.num_terms(),
lo.vars().data(), lo.coefs().data()));
// Highs_changeObjectiveOffset(highs, offset); TODO offset?
std::vector<double> objc_new(NumVars()); // dense vector to
for (auto i=lo.vars().size(); i--; )
objc_new[lo.vars()[i]] = lo.coefs()[i];
HIGHS_CCALL(Highs_changeColsCostByRange(lp(), 0, NumVars()-1, objc_new.data()));
HIGHS_CCALL(Highs_changeObjectiveSense(lp(),
obj::Type::MAX==lo.obj_sense() ?
kHighsObjSenseMaximize : kHighsObjSenseMinimize) );
obj::Type::MAX==lo.obj_sense() ?
kHighsObjSenseMaximize : kHighsObjSenseMinimize) );
} else {
throw std::runtime_error("HighS does not support multiple objectives.");
}
Expand Down Expand Up @@ -77,26 +79,28 @@ void HighsModelAPI::SetQuadraticObjective(int iobj, const QuadraticObjective& qo
}

void HighsModelAPI::AddConstraint(const LinConRange& lc) {
AccConstraints.add(lc);
acc_constraints_.add(lc);
}
void HighsModelAPI::AddConstraint(const LinConLE& lc) {
AccConstraints.add(lc);
acc_constraints_.add(lc);
}
void HighsModelAPI::AddConstraint(const LinConEQ& lc) {
AccConstraints.add(lc);
acc_constraints_.add(lc);
}
void HighsModelAPI::AddConstraint(const LinConGE& lc) {
AccConstraints.add(lc);
acc_constraints_.add(lc);
}

void HighsModelAPI::FinishProblemModificationPhase() {
HIGHS_CCALL(Highs_addRows(lp(),
AccConstraints.lb.size(),
AccConstraints.lb.data(),
AccConstraints.ub.data(),
AccConstraints.coeffs.size(),
AccConstraints.starts.data(),
AccConstraints.indices.data(),
AccConstraints.coeffs.data()));
acc_constraints_.lb.size(),
acc_constraints_.lb.data(),
acc_constraints_.ub.data(),
acc_constraints_.coeffs.size(),
acc_constraints_.starts.data(),
acc_constraints_.indices.data(),
acc_constraints_.coeffs.data()));
acc_constraints_ = AccConstraints(); // reinitialize accumulator for model modification
}

} // namespace mp
4 changes: 2 additions & 2 deletions solvers/highsmp/highsmpmodelapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class HighsModelAPI :
USE_BASE_CONSTRAINT_HANDLERS(BaseModelAPI)


struct AccConstraints{
struct AccConstraints {
/* This is to accumulate the constraints in a format suitable for
Highs_addRows(...). Adding them one by one was killing performance
unacceptably. */
Expand Down Expand Up @@ -81,7 +81,7 @@ class HighsModelAPI :
AccConstraints() {
starts.push_back(0);
}
} AccConstraints;
} acc_constraints_;

ACCEPT_CONSTRAINT(LinConRange, Recommended, CG_Linear)
void AddConstraint(const LinConRange& lc);
Expand Down
2 changes: 2 additions & 0 deletions solvers/visitor/visitormodelapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class VisitorModelAPI :

/// Called before problem input.
/// Model info can be used to preallocate memory.
/// @note this is called before each phase of model modification
/// which can happen during iterative solving.
void InitProblemModificationPhase(const FlatModelInfo*);
/// After
void FinishProblemModificationPhase();
Expand Down

0 comments on commit 9cf6faa

Please sign in to comment.