@@ -11,6 +11,9 @@ point on the frontier, corresponding to solving each objective in order.
1111
1212## Supported optimizer attributes
1313
14+ * `MOI.TimeLimitSec()`: terminate if the time limit is exceeded and return the
15+ current best solutions.
16+
1417 * `MOA.LexicographicAllPermutations()`: Controls whether to return the
1518 lexicographic solution for all permutations of the scalar objectives (when
1619 `true`), or only the solution corresponding to the lexicographic solution of
@@ -62,37 +65,54 @@ function MOI.set(alg::Lexicographic, ::LexicographicAllPermutations, val::Bool)
6265end
6366
6467function optimize_multiobjective! (algorithm:: Lexicographic , model:: Optimizer )
68+ start_time = time ()
6569 sequence = 1 : MOI. output_dimension (model. f)
6670 if ! MOI. get (algorithm, LexicographicAllPermutations ())
67- return _solve_in_sequence (algorithm, model, sequence)
71+ return _solve_in_sequence (algorithm, model, sequence, start_time )
6872 end
6973 solutions = SolutionPoint[]
74+ status = MOI. OPTIMAL
7075 for sequence in Combinatorics. permutations (sequence)
71- status, solution = _solve_in_sequence (algorithm, model, sequence)
76+ status, solution =
77+ _solve_in_sequence (algorithm, model, sequence, start_time)
78+ if ! isempty (solution)
79+ push! (solutions, solution[1 ])
80+ end
7281 if ! _is_scalar_status_optimal (status)
73- return status, nothing
82+ break
7483 end
75- push! (solutions, solution[1 ])
7684 end
7785 sense = MOI. get (model. inner, MOI. ObjectiveSense ())
78- return MOI . OPTIMAL , filter_nondominated (sense, solutions)
86+ return status , filter_nondominated (sense, solutions)
7987end
8088
8189function _solve_in_sequence (
8290 algorithm:: Lexicographic ,
8391 model:: Optimizer ,
8492 sequence:: AbstractVector{Int} ,
93+ start_time:: Float64 ,
8594)
8695 variables = MOI. get (model. inner, MOI. ListOfVariableIndices ())
8796 constraints = Any[]
8897 scalars = MOI. Utilities. eachscalar (model. f)
98+ solution = SolutionPoint[]
99+ status = MOI. OPTIMAL
89100 for i in sequence
101+ if _time_limit_exceeded (model, start_time)
102+ status = MOI. TIME_LIMIT
103+ break
104+ end
90105 f = scalars[i]
91106 MOI. set (model. inner, MOI. ObjectiveFunction {typeof(f)} (), f)
92107 MOI. optimize! (model. inner)
93108 status = MOI. get (model. inner, MOI. TerminationStatus ())
109+ primal_status = MOI. get (model. inner, MOI. PrimalStatus ())
110+ if _is_scalar_status_feasible_point (primal_status)
111+ X, Y = _compute_point (model, variables, model. f)
112+ solution = [SolutionPoint (X, Y)]
113+ end
94114 if ! _is_scalar_status_optimal (status)
95- return status, nothing
115+ break
96116 end
97117 X, Y = _compute_point (model, variables, f)
98118 rtol = MOI. get (algorithm, ObjectiveRelativeTolerance (i))
@@ -103,9 +123,8 @@ function _solve_in_sequence(
103123 end
104124 push! (constraints, MOI. add_constraint (model, f, set))
105125 end
106- X, Y = _compute_point (model, variables, model. f)
107126 for c in constraints
108127 MOI. delete (model, c)
109128 end
110- return MOI . OPTIMAL, [ SolutionPoint (X, Y)]
129+ return status, solution
111130end
0 commit comments