@@ -49,22 +49,45 @@ class MOManager {
49
49
// / Prepare next multiobj iteration?
50
50
// / @note Call this before a MO iteration.
51
51
// / @return true iff the model is ready for the next iteration.
52
- bool PrepareMOIteration () {
52
+ bool PrepareMOIteration (
53
+ std::function<sol::Status(void )> get_stt, std::function<Solution(void )> get_sol) {
53
54
switch (status_) {
54
55
case MOManagerStatus::NOT_SET:
55
- MP_RAISE (" FlatConverter: MultiobjManager not started " );
56
+ MP_RAISE (" FlatConverter: MultiobjManager not set up " );
56
57
case MOManagerStatus::NOT_ACTIVE:
57
58
MP_RAISE (" FlatConverter: MultiobjManager not running" );
58
59
case MOManagerStatus::RUNNING:
59
- return DoPrepareNextMultiobjSolve ();
60
+ return DoPrepareNextMultiobjSolve (get_stt, get_sol );
60
61
case MOManagerStatus::FINISHED:
61
62
return false ;
62
63
}
63
64
return false ;
64
65
}
65
66
67
+ // / Obtain and process a postsolved solution of the current iteration.
68
+ // / Can implicitly call ProcessMOIterationUnpostsolvedSolution().
69
+ // / @return (whether we should continue, solve_result).
70
+ std::pair<bool , sol::Status> ProcessMOIterationPostsolvedSolution (
71
+ std::function<sol::Status(void )> get_stt, std::function<Solution(void )> get_sol) {
72
+ auto solst = get_stt ();
73
+ assert (sol::Status::NOT_SET != solst);
74
+ assert (IsMOActive ());
75
+ assert (MOManagerStatus::FINISHED != status_);
76
+ if ((sol::IsProblemSolvedOrFeasible ((sol::Status)solst)
77
+ // || sol::IsProblemMaybeSolved(solst) // Use this?
78
+ ) && !sol::IsProblemUnbounded ((sol::Status)solst) // Don't want unbounded
79
+ ) { // (but LIMIT can have this undiscovered)
80
+ get_sol (); // This implicitly calls ProcessMOIterationUnpostsolvedSolution().
81
+ return { true , solst };
82
+ // We ignore the solution here - but having it provided
83
+ // guarantees that the postsolve has been run.
84
+ }
85
+ status_ = MOManagerStatus::FINISHED;
86
+ return { false , solst };
87
+ }
88
+
66
89
// / Process an unpostsolved solution of the current iteration.
67
- // / Necessary to be called.
90
+ // / This is called from solution postsolve initiated by solution getter .
68
91
// / @note Can be called before or after the postsolved solution.
69
92
void ProcessMOIterationUnpostsolvedSolution (pre::ModelValuesDbl& sol) {
70
93
if (IsMOActive ()) {
@@ -79,24 +102,6 @@ class MOManager {
79
102
}
80
103
}
81
104
82
- // / Process a postsolved solution of the current iteration.
83
- // / Necessary to be called.
84
- // / @note Can be called before or after unpostsolved solution.
85
- // / Should contain at least valid solve status.
86
- void ProcessMOIterationPostsolvedSolution (const Solution& , int solst) {
87
- assert (sol::Status::NOT_SET != solst);
88
- assert (IsMOActive ());
89
- assert (MOManagerStatus::FINISHED != status_);
90
- if ((sol::IsProblemSolvedOrFeasible ((sol::Status)solst)
91
- // || sol::IsProblemMaybeSolved(solst) // Use this?
92
- ) && !sol::IsProblemUnbounded ((sol::Status)solst))
93
- {} // continue
94
- else
95
- status_ = MOManagerStatus::FINISHED;
96
- // We ignore the solution here - but having it provided
97
- // guarantees that the postsolve has been run.
98
- }
99
-
100
105
101
106
protected:
102
107
void SetupMultiobjEmulation () {
@@ -161,7 +166,8 @@ class MOManager {
161
166
}
162
167
163
168
// / Do prepare next solve
164
- bool DoPrepareNextMultiobjSolve () {
169
+ bool DoPrepareNextMultiobjSolve (
170
+ std::function<sol::Status(void )> get_stt, std::function<Solution(void )> get_sol) {
165
171
if (++i_current_obj_ >= obj_new_.size ()) {
166
172
status_ = MOManagerStatus::FINISHED;
167
173
MPD ( GetEnv () ).Print (
@@ -176,8 +182,20 @@ class MOManager {
176
182
" MULTI-OBJECTIVE MODE: objective {} (out of {}) ...\n "
177
183
" ==============================================================================\n\n "
178
184
, i_current_obj_+1 , obj_new_.size ());
179
- if (i_current_obj_)
185
+ if (i_current_obj_) {
186
+ auto proc_sol = ProcessMOIterationPostsolvedSolution (get_stt, get_sol);
187
+ if (!proc_sol.first ) {
188
+ if (MPD ( GetEnv () ).verbose_mode ())
189
+ MPD ( GetEnv () ).Print (
190
+ " \n "
191
+ " MULTI-OBJECTIVE MODE: objective {} (out of {}):\n "
192
+ " ABORTING due to the previous iteration's solve result ({}).\n "
193
+ " ==============================================================================\n\n "
194
+ , i_current_obj_+1 , obj_new_.size (), proc_sol.second );
195
+ return false ;
196
+ }
180
197
RestrictLastObjVal ();
198
+ }
181
199
MPD ( FillConstraintCounters ( MPD ( GetModelAPI () ), *MPD ( GetModelInfoWrt () ) ) ); // @todo a hack.
182
200
MPD ( GetModelAPI () ).InitProblemModificationPhase ( // For adding the new constraint. @todo a hack.
183
201
MPD ( GetModelInfo () )); // Ideally Model would notice changes and notify
0 commit comments