Skip to content

Commit

Permalink
[BREAKING] Multi-obj emulator v0.1 #239
Browse files Browse the repository at this point in the history
Breaking: Backend implements GetSolveResult()

No suffixes, lexicographic in the input order
  • Loading branch information
glebbelov committed May 21, 2024
1 parent d705ed9 commit 9d20d48
Show file tree
Hide file tree
Showing 38 changed files with 495 additions and 155 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ add_prefix(MP_FLAT_HEADERS include/mp/flat/
constr_prepro.h constr_prop_down.h
context.h
converter.h converter_model.h converter_model_base.h
converter_multiobj.h
convert_functional.h
eexpr.h expr_algebraic.h expr_affine.h expr_quadratic.h
expr_bounds.h
Expand Down
3 changes: 2 additions & 1 deletion include/mp/backend-base.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class BasicBackend : public BasicSolver {
virtual void InitOptionParsing() { }
/// Chance to consider options immediately (open cloud, etc)
virtual void FinishOptionParsing() { }
/// Having everything set up, solve the problem
/// Having everything set up, (re)solve the problem.
/// This is to be overloaded by the implementation.
virtual void Solve() { }

/// Callbacks typedef
Expand Down
1 change: 1 addition & 0 deletions include/mp/backend-mip.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ class MIPBackend : public BaseBackend
this->IsProblemIndiffInfOrUnb() ) &&
GetMIPOptions().exportIIS_) {
ComputeIIS();
this->SetStatus( this->GetSolveResult() );

auto iis = GetIIS();

Expand Down
134 changes: 65 additions & 69 deletions include/mp/backend-std.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,21 +61,8 @@ DEFAULT_STD_FEATURES_TO( false )
#endif



namespace mp {

/// Solution (postsolved)
struct Solution {
/// primal
std::vector<double> primal;
/// dual
std::vector<double> dual;
/// objective values
std::vector<double> objvals;
/// Sparsity, if solver wants it
ArrayRef<int> spars_primal;
};

/// StdBackend: the standard solver API wrapper
///
/// The standard wrapper provides common functionality:
Expand Down Expand Up @@ -139,11 +126,13 @@ class StdBackend :
virtual void ObjRelTol(ArrayRef<double>) { }

/**
* MULTISOL support
* No API to overload,
* Impl should check need_multiple_solutions()
* and call ReportIntermediateSolution({x, pi, objvals}) for each
* (postsolve the values if needed)
* MULTISOL support.
* Impl can implement ReportSolutionPool()
* and call the supplied function with ({x, pi, objvals}) for each
* (postsolve the values if needed.)
*
* Alternatively, if (need_multiple_solutions()),
* call ReportIntermediateSolution() during solve.
**/
DEFINE_STD_FEATURE( MULTISOL )
ALLOW_STD_FEATURE( MULTISOL, false )
Expand Down Expand Up @@ -221,7 +210,7 @@ class StdBackend :
// exportFileMode == 2 -> do not solve, just export
if (exportFileMode() != 2)
{
Solve();
RunSolveIterations();
RecordSolveTime();

Report();
Expand All @@ -247,26 +236,44 @@ class StdBackend :
}

/// Input warm start, suffixes, and all that can modify the model.
/// This is used by the AMPLS C API
/// Usually overloaded by user and calls this one at last.
/// This is used by the AMPLS C API.
void InputExtras() override {
InputStdExtras();
}

/// Set solution file name
void SetSolutionFileName(const std::string& filename) {
GetMM().SetSolutionFileName(filename);
}
/// Report results

/// Report results.
/// Usually overloaded by user and calls this one at last.
void ReportResults() override {
ReportSuffixes();
ReportSolution();
}


protected:
/// Solve, no model modification any more.
/// Can report intermediate results via ReportIntermediateSolution() during this,
/// otherwise in ReportResults()
/// Solve, to be overloaded by the solver.
/// No model modification any more.
/// @note If using STD_FEATURE( MULTISOL ),
/// can report intermediate results
/// via ReportIntermediateSolution() during this or after
/// (check if (need_multiple_solutions()).)
virtual void Solve() override = 0;

/// Our solving procedure.
virtual void RunSolveIterations() {
while (GetMM().PrepareSolveIteration()) {
Solve();
SetStatus( GetSolveResult() ); // before GetSolution()
sol_last_ = GetSolution();
GetMM().ProcessIterationSolution(sol_last_, status_.first);
}
}

/// Report
virtual void Report() {
ReportResults();
Expand All @@ -275,6 +282,9 @@ class StdBackend :
// PrintWarnings();
}

/// User to implement
virtual std::pair<int, std::string> GetSolveResult() = 0;

/// Standard extras
virtual void InputStdExtras() {
if (multiobj()) {
Expand Down Expand Up @@ -573,62 +583,45 @@ class StdBackend :
//////////////////////// SOLUTION STATUS ACCESS ///////////////////////////////

/// Solve result number
virtual int SolveCode() const { return status_.first; }
virtual sol::Status SolveCode() const {
assert(IsSolStatusRetrieved());
return sol::Status(status_.first);
}
/// Solver result message
const char* SolveStatus() const { return status_.second.c_str(); }
/// Set solve result
void SetStatus(std::pair<int, std::string> stt) { status_=stt; }

//////////////////////// SOLUTION STATUS ADAPTERS ///////////////////////////////
/** Following the taxonomy of the enum sol, returns true if
/** Following the taxonomy of the enum sol::Status, returns true if
we have an optimal solution or a feasible solution for a
satisfaction problem */
virtual bool IsProblemSolved() const {
assert(IsSolStatusRetrieved());
return sol::SOLVED<=SolveCode()
&& SolveCode()<=sol::SOLVED_LAST;
}
virtual bool IsProblemSolved() const
{ return sol::IsProblemSolved(SolveCode()); }

/// Solved or feasible
virtual bool IsProblemSolvedOrFeasible() const {
assert( IsSolStatusRetrieved() );
return
(sol::SOLVED_LAST>=SolveCode() &&
sol::SOLVED<=SolveCode())
||
(sol::LIMIT_FEAS>=SolveCode() &&
sol::LIMIT_FEAS_LAST<=SolveCode())
||
(sol::UNBOUNDED_FEAS>=SolveCode() &&
sol::UNBOUNDED_NO_FEAS_LAST<=SolveCode());
}
virtual bool IsProblemSolvedOrFeasible() const
{ return sol::IsProblemSolvedOrFeasible(SolveCode()); }

/// Undecidedly infeas or unbnd
virtual bool IsProblemIndiffInfOrUnb() const {
assert( IsSolStatusRetrieved() );
return sol::LIMIT_INF_UNB<=SolveCode()
&& SolveCode()<=sol::LIMIT_INF_UNB_LAST;
}
virtual bool IsProblemIndiffInfOrUnb() const
{ return sol::IsProblemIndiffInfOrUnb(SolveCode()); }

/// Infeasible or unbounded
virtual bool IsProblemInfOrUnb() const {
assert( IsSolStatusRetrieved() );
auto sc = SolveCode();
return
(sol::INFEASIBLE<=sc
&& sol::UNBOUNDED_NO_FEAS_LAST>=sc)
|| IsProblemIndiffInfOrUnb();
}
virtual bool IsProblemInfeasible() const {
assert( IsSolStatusRetrieved() );
auto sc = SolveCode();
return sol::INFEASIBLE<=sc && sol::INFEASIBLE_LAST>sc;
}
virtual bool IsProblemUnbounded() const {
assert( IsSolStatusRetrieved() );
auto sc = SolveCode();
return sol::UNBOUNDED_FEAS<=sc
&& sol::UNBOUNDED_NO_FEAS_LAST>=sc;
}
virtual bool IsProblemInfOrUnb() const
{ return sol::IsProblemInfOrUnb(SolveCode()); }

/// Problem infeasible?
virtual bool IsProblemInfeasible() const
{ return sol::IsProblemInfeasible(SolveCode()); }

/// Problem unbounded?
virtual bool IsProblemUnbounded() const
{ return sol::IsProblemUnbounded(SolveCode()); }

/// Is sol status retrieved?
virtual bool IsSolStatusRetrieved() const {
return sol::NOT_SET!=SolveCode();
return sol::NOT_SET!=status_.first;
}


Expand Down Expand Up @@ -661,6 +654,7 @@ class StdBackend :
std::pair<int, std::string> status_ { sol::NOT_SET, "status not set" };
int kIntermSol_ = 0; // last written intermed solution index
std::pair<double, double> objIntermSol_ { -1e100, 1e100 };
Solution sol_last_;

///////////////////////// STORING SOLVER MESSAGES //////////////////////
private:
Expand Down Expand Up @@ -981,8 +975,10 @@ class StdBackend :
int flg=0;
if ( IMPL_HAS_STD_FEATURE(MULTISOL) )
flg |= BasicSolver::MULTIPLE_SOL;
/// Allow native or emulated multiobj
flg |= BasicSolver::MULTIPLE_OBJ;
if ( IMPL_HAS_STD_FEATURE(MULTIOBJ) )
flg |= BasicSolver::MULTIPLE_OBJ;
flg |= BasicSolver::MULTIPLE_OBJ_NATIVE;
return flg;
}

Expand Down
Loading

0 comments on commit 9d20d48

Please sign in to comment.