using JuMP
import HiGHS
import MultiObjectiveAlgorithms as MOA
model = JuMP.Model(() -> MOA.Optimizer(HiGHS.Optimizer))
set_attribute(model, MOA.Algorithm(), MOA.Lexicographic())
Is it possible to set the attribute of optimizer in the iteration of _solve_in_sequence in Lexicographic? For example, modify the time_limit.I would like to modify the code above to achieve something similar to the following sample code:
for i in sequence
if i <= 2
set_attribute(model, "time_limit", 1000.0)
else
set_attribute(model, "time_limit", 500.0)
end
if _time_limit_exceeded(model, start_time)
status = MOI.TIME_LIMIT
break
end
# ....
end
but that might be a bit complicated to be helpful.
One approach is to write a new algorithm,
import MultiObjectiveAlgorithms as MOA
import MathOptInterface as MOI
import Combinatorics
mutable struct CustomLexicographic <: MOA.AbstractAlgorithm end
function MOA.optimize_multiobjective!(
algorithm::CustomLexicographic,
model::MOA.Optimizer,
)
start_time = time()
sequence = 1:MOI.output_dimension(model.f)
solutions = MOA.SolutionPoint[]
status = MOI.OPTIMAL
for sequence in Combinatorics.permutations(sequence)
status, solution =
_solve_in_sequence(algorithm, model, sequence, start_time)
if !isempty(solution)
push!(solutions, solution[1])
end
if !MOA._is_scalar_status_optimal(status)
break
end
end
sense = MOI.get(model.inner, MOI.ObjectiveSense())
return status, MOA.filter_nondominated(sense, solutions)
end
function _solve_in_sequence(
::CustomLexicographic,
model::MOA.Optimizer,
sequence::AbstractVector{Int},
start_time::Float64,
)
variables = MOI.get(model.inner, MOI.ListOfVariableIndices())
constraints = Any[]
scalars = MOI.Utilities.eachscalar(model.f)
solution = MOA.SolutionPoint[]
status = MOI.OPTIMAL
for i in sequence
if MOA._time_limit_exceeded(model, start_time)
status = MOI.TIME_LIMIT
break
end
f = scalars[i]
# Do something here...
MOI.set(model.inner, MOI.ObjectiveFunction{typeof(f)}(), f)
MOI.optimize!(model.inner)
status = MOI.get(model.inner, MOI.TerminationStatus())
primal_status = MOI.get(model.inner, MOI.PrimalStatus())
if MOA._is_scalar_status_feasible_point(primal_status)
X, Y = MOA._compute_point(model, variables, model.f)
solution = [MOA.SolutionPoint(X, Y)]
end
if !MOA._is_scalar_status_optimal(status)
break
end
X, Y = MOA._compute_point(model, variables, f)
rtol = 1e-3
set = if MOI.get(model.inner, MOI.ObjectiveSense()) == MOI.MIN_SENSE
MOI.LessThan(Y + rtol * abs(Y))
else
MOI.GreaterThan(Y - rtol * abs(Y))
end
ci = MOI.Utilities.normalize_and_add_constraint(model, f, set)
push!(constraints, ci)
end
for c in constraints
MOI.delete(model, c)
end
return status, solution
end
@odow Thanks for the answer, the method you provided for using MOA is exactly what we are trying. However, I don’t know how to modify the attribute of the optimizer in the _solve_in_sequence function, and have tried several methods that have failed. For example,