Skip to content

Commit c8c05ee

Browse files
author
Skye Vidler
committed
Added multi-objective support, modifed relevant doc strings and added an instructional subsection to the objective document.
1 parent ecabacb commit c8c05ee

4 files changed

Lines changed: 56 additions & 13 deletions

File tree

docs/src/guide/objective.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ One key idea is that the objective must evaluate to a finite expression which me
1414
it must only explicitly contain finite variables and point variables. Infinite
1515
expressions must be summarized by a measure (e.g., taking the expectation of a random variable).
1616

17+
1718
## [Basic Usage](@id obj_basic)
1819
Principally, the objective function is specified via
1920
[`@objective`](https://jump.dev/JuMP.jl/v1/api/JuMP/#JuMP.@objective)
@@ -139,3 +140,17 @@ more efficient at parsing expressions.
139140
[`@objective`](https://jump.dev/JuMP.jl/v1/api/JuMP/#JuMP.@objective)
140141
since it is more stable and efficient than the `set_objective_[aspect]`
141142
methods due to its enhanced methodology for parsing expressions.
143+
144+
### Multi-Objective Problems
145+
`InfiniteOpt` also supports multi-objective problems by supplying the model with a vector of scalar values.
146+
Instead of a `JuMP.AbstractJuMPScalar`, these become `AbstractVector` within the model.
147+
148+
These models are defined the same way as scalar, single-objective models with `@objective`, with some slight differences in definition. Looking at the aforementioned example and modifying it a bit, it becomes:
149+
150+
```jldoctest obj_multi
151+
julia> @objective(model, Max, [0.5x[1], 0.5x[2]])
152+
0.5 x[1]
153+
0.5 x[2]
154+
```
155+
If a scalarization method of solving the model is the goal, the individual `@expression` scalars within the vector can be compiled into a single objective. The weight- or priority- of these expressions can be changed by multiplying each component in the vector by fractions, with the sum of the fractions being 1.
156+
In hierarchical model solving, the order of the scalars determines the priority of the model.

src/TranscriptionOpt/transcribe.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -565,6 +565,15 @@ function transcription_expression(
565565
return zero(JuMP.AffExpr) + num
566566
end
567567

568+
# Vectors
569+
function transcription_expression(
570+
func::AbstractVector,
571+
backend::TranscriptionBackend,
572+
support::Vector{Float64}
573+
)
574+
return map(f -> transcription_expression(f, backend, support), func)
575+
end
576+
568577
################################################################################
569578
# MEASURE TRANSCRIPTION METHODS
570579
################################################################################
@@ -750,7 +759,7 @@ end
750759
function _process_constraint(
751760
backend::TranscriptionBackend,
752761
constr::JuMP.VectorConstraint,
753-
func::Vector{<:JuMP.AbstractJuMPScalar},
762+
func::AbstractVector,
754763
set::MOI.AbstractVectorSet,
755764
raw_supp::Vector{Float64},
756765
name::String

src/datatypes.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,7 +1398,7 @@ mutable struct InfiniteModel <: JuMP.AbstractModel
13981398

13991399
# Objective Data
14001400
objective_sense::MOI.OptimizationSense
1401-
objective_function::JuMP.AbstractJuMPScalar
1401+
objective_function::Union{JuMP.AbstractJuMPScalar, AbstractVector{<:JuMP.AbstractJuMPScalar}}
14021402
objective_has_measures::Bool
14031403

14041404
# Operator Registration

src/objective.jl

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,24 @@ function JuMP.objective_sense(model::InfiniteModel)::MOI.OptimizationSense
1818
end
1919

2020
"""
21-
JuMP.objective_function(model::InfiniteModel)::JuMP.AbstractJuMPScalar
21+
JuMP.objective_function(model::InfiniteModel)::Union{JuMP.AbstractJuMPScalar, AbstractVector}
2222
2323
Extend `JuMP.objective_function` to return the objective of infinite model
24-
`model`.
24+
`model`. Supports scalar values or vectors of scalar values.
2525
2626
**Example**
2727
```julia-repl
28-
julia> objective_function(model)
29-
1
28+
julia> objective_function(scalar_model)
29+
2 x + 1
30+
31+
```julia-repl
32+
julia> objective_function(multiobjective_model)
33+
2 x + 1
34+
5 y - 1
35+
3036
```
3137
"""
32-
function JuMP.objective_function(model::InfiniteModel)::JuMP.AbstractJuMPScalar
38+
function JuMP.objective_function(model::InfiniteModel)::Union{JuMP.AbstractJuMPScalar, AbstractVector}
3339
return model.objective_function
3440
end
3541

@@ -74,23 +80,30 @@ end
7480
################################################################################
7581
"""
7682
JuMP.set_objective_function(model::InfiniteModel,
77-
func::JuMP.AbstractJuMPScalar)::Nothing
83+
func::Union{JuMP.AbstractJuMPScalar, AbstractVector})::Nothing
7884
7985
Extend `JuMP.set_objective_function` to set the objective expression of
8086
infinite model `model`. Errors if `func` contains infinite variables and/or
81-
parameters. Also errors if `func` contains invalid variables.
87+
parameters. Also errors if `func` contains invalid variables.
88+
Supports scalar values or vectors of scalar values.
8289
8390
**Example**
8491
```julia-repl
8592
julia> set_objective_function(model, 2x + 1)
8693
8794
julia> objective_function(model)
8895
2 x + 1
96+
97+
julia> set_objective_function(model, [2x + 1, 5y - 1)
98+
99+
julia> objective_function(model)
100+
2 x + 1
101+
5 y - 1
89102
```
90103
"""
91104
function JuMP.set_objective_function(
92105
model::InfiniteModel,
93-
func::JuMP.AbstractJuMPScalar
106+
func::Union{JuMP.AbstractJuMPScalar, AbstractVector}
94107
)::Nothing
95108
# gather the unique list of variable references for testing and mapping
96109
new_vrefs = all_expression_variables(func)
@@ -172,24 +185,30 @@ end
172185

173186
"""
174187
JuMP.set_objective(model::InfiniteModel, sense::MOI.OptimizationSense,
175-
func::Union{JuMP.AbstractJuMPScalar, Real})::Nothing
188+
func::Union{JuMP.AbstractJuMPScalar, AbstractVector, Real})::Nothing
176189
177190
Extend `JuMP.set_objective` to set the objective of infinite model
178191
`model`. Errors if `func` contains infinite variables and/or parameters, or if
179-
it does not belong to the model.
192+
it does not belong to the model. Supports scalar values or vectors of scalar values.
180193
181194
**Example**
182195
```julia-repl
183196
julia> set_objective(model, MOI.MIN_SENSE, 2x + 1)
184197
185198
julia> objective_function(model)
186199
2 x + 1
200+
201+
julia> set_objective(model, MOI.MIN_SENSE, [2x + 1, 5y - 1])
202+
203+
julia> objective_function(model)
204+
2 x + 1
205+
5 y - 1
187206
```
188207
"""
189208
function JuMP.set_objective(
190209
model::InfiniteModel,
191210
sense::MOI.OptimizationSense,
192-
func::Union{JuMP.AbstractJuMPScalar, Real}
211+
func::Union{JuMP.AbstractJuMPScalar, AbstractVector, Real}
193212
)::Nothing
194213
JuMP.set_objective_sense(model, sense)
195214
JuMP.set_objective_function(model, func)

0 commit comments

Comments
 (0)