Skip to content

Commit 95f3e7b

Browse files
committed
WIP: begin support for vector-valued objectives
To be read in conjunction with jump-dev/MathOptInterface.jl#2070 A proof-of-concept solver and JuMP examples are available at jump-dev/MultiObjectiveAlgorithms.jl#2 The issue #2099 discussed two approaches for implementing MO in JuMP. 1. Treat multicriteria as a vector of scalar objectives and a vector of scalar senses. This would let someone write [Min, Max], [f(x), g(x)]. The main reason for this approach is that it matches what users want to do. 2. Treat multicriteria as an optimization problem with a vector-valued objective function. Users could write only Min, f(x) where f(x) is a vector. The main reason for this approach is that it matches what MathOptInterface wants. This PR implements option 2. The strongest reason in support of option 2 is that it requires very little code to implement, suggesting that it is a natural extension of MOI. The biggest downside is that it doesn't overcome the Min-Max issue; but I think we can work around this with user-facing cosmetic tooling in JuMP; solvers would be forced to accept a single sense.
1 parent 5bd9f56 commit 95f3e7b

File tree

2 files changed

+21
-5
lines changed

2 files changed

+21
-5
lines changed

src/objective.jl

+13-3
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ end
2626
Return the best known bound on the optimal objective value after a call to
2727
`optimize!(model)`.
2828
"""
29-
function objective_bound(model::Model)::Float64
29+
function objective_bound(model::Model)
3030
return MOI.get(model, MOI.ObjectiveBound())
3131
end
3232

@@ -38,7 +38,7 @@ most-recent solution returned by the solver.
3838
3939
See also: [`result_count`](@ref).
4040
"""
41-
function objective_value(model::Model; result::Int = 1)::Float64
41+
function objective_value(model::Model; result::Int = 1)
4242
return MOI.get(model, MOI.ObjectiveValue(result))
4343
end
4444

@@ -90,7 +90,7 @@ functions; the recommended way to set the objective is with the
9090
"""
9191
function set_objective_function end
9292

93-
function set_objective_function(model::Model, func::MOI.AbstractScalarFunction)
93+
function set_objective_function(model::Model, func::MOI.AbstractFunction)
9494
attr = MOI.ObjectiveFunction{typeof(func)}()
9595
if !MOI.supports(backend(model), attr)
9696
error(
@@ -123,6 +123,16 @@ function set_objective_function(model::Model, func::Real)
123123
)
124124
end
125125

126+
function set_objective_function(
127+
model::Model,
128+
func::AbstractVector{<:AbstractJuMPScalar},
129+
)
130+
for f in func
131+
check_belongs_to_model(f, model)
132+
end
133+
return set_objective_function(model, moi_function(func))
134+
end
135+
126136
function set_objective_function(model::AbstractModel, func)
127137
return error("The objective function `$(func)` is not supported by JuMP.")
128138
end

src/solution_summary.jl

+8-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ struct _SolutionSummary
1616
has_values::Bool
1717
has_duals::Bool
1818
# Candidate solution
19-
objective_value::Union{Missing,Float64}
20-
objective_bound::Union{Missing,Float64}
19+
objective_value::Union{Missing,Float64,Vector{Float64}}
20+
objective_bound::Union{Missing,Float64,Vector{Float64}}
2121
relative_gap::Union{Missing,Float64}
2222
dual_objective_value::Union{Missing,Float64}
2323
primal_solution::Union{Missing,Dict{String,Float64}}
@@ -216,3 +216,9 @@ function _print_if_not_missing(io, header, value::Real)
216216
println(io, header, Printf.@sprintf("%.5e", value))
217217
return
218218
end
219+
220+
function _print_if_not_missing(io, header, value::Vector{<:Real})
221+
array = join([Printf.@sprintf("%.5e", v) for v in value], ",")
222+
println(io, header, "[", array, "]")
223+
return
224+
end

0 commit comments

Comments
 (0)