Skip to content

Commit f50d73c

Browse files
committed
Add documentation
1 parent 62edf4d commit f50d73c

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

docs/src/manual/objective.md

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,80 @@ julia> @objective(model, Min, 2x)
157157
julia> @objective(model, Max, objective_function(model))
158158
2 x
159159
```
160+
161+
## Set a vector-valued objective
162+
163+
Define a multi-objective optimization problem by passing a vector of objectives:
164+
165+
```jldoctest; setup = :(model=Model())
166+
julia> @variable(model, x[1:2]);
167+
168+
julia> @objective(model, Min, [1 + x[1], 2 * x[2]])
169+
2-element Vector{AffExpr}:
170+
x[1] + 1
171+
2 x[2]
172+
173+
julia> f = objective_function(model)
174+
2-element Vector{AffExpr}:
175+
x[1] + 1
176+
2 x[2]
177+
```
178+
179+
In most cases, multi-objective optimization solvers will return multiple
180+
solutions, corresponding to points on the Pareto frontier. See [Multiple solutions](@ref)
181+
for information on how to query and work with multiple solutions.
182+
183+
Note that you can must set a single objective sense, that is, you cannot have
184+
both minimization and maximization objectives. Work around this limitation by
185+
choosing `Min` and negating any objectives you want to maximize:
186+
187+
```jldoctest; setup = :(model=Model())
188+
julia> @variable(model, x[1:2]);
189+
190+
julia> @expression(model, obj1, 1 + x[1])
191+
x[1] + 1
192+
193+
julia> @expression(model, obj2, 2 * x[1])
194+
2 x[1]
195+
196+
julia> @objective(model, Min, [obj1, -obj2])
197+
2-element Vector{AffExpr}:
198+
x[1] + 1
199+
-2 x[1]
200+
```
201+
202+
Defining your objectives as expressions allows flexibility in how you can solve
203+
variations of the same problem, with some objectives removed and constrained to
204+
be no worse that a fixed value.
205+
206+
```jldoctest; setup = :(model=Model())
207+
julia> @variable(model, x[1:2]);
208+
209+
julia> @expression(model, obj1, 1 + x[1])
210+
x[1] + 1
211+
212+
julia> @expression(model, obj2, 2 * x[1])
213+
2 x[1]
214+
215+
julia> @expression(model, obj3, x[1] + x[2])
216+
x[1] + x[2]
217+
218+
julia> @objective(model, Min, [obj1, obj2, obj3]) # Three-objective problem
219+
3-element Vector{AffExpr}:
220+
x[1] + 1
221+
2 x[1]
222+
x[1] + x[2]
223+
224+
julia> # optimize!(model), look at the solution, talk to stakeholders, then
225+
# decide you want to solve a new problem where the third objective is
226+
# removed and constrained to be better than 2.0.
227+
nothing
228+
229+
julia> @objective(model, Min, [obj1, obj2]) # Two-objective problem
230+
2-element Vector{AffExpr}:
231+
x[1] + 1
232+
2 x[1]
233+
234+
julia> @constraint(model, obj3 <= 2.0)
235+
x[1] + x[2] ≤ 2.0
236+
```

src/objective.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ end
2525
2626
Return the best known bound on the optimal objective value after a call to
2727
`optimize!(model)`.
28+
29+
In the case of a vector-valued objective, this returns the nadir point, that is,
30+
the point obtained if each objective was optimized independently.
2831
"""
2932
function objective_bound(model::Model)::Union{Float64,Vector{Float64}}
3033
return MOI.get(model, MOI.ObjectiveBound())
@@ -36,6 +39,9 @@ end
3639
Return the objective value associated with result index `result` of the
3740
most-recent solution returned by the solver.
3841
42+
For scalar-valued objectives, this function returns a `Float64`. For
43+
vector-valued objectives, it returns a `Vector{Float64}`.
44+
3945
See also: [`result_count`](@ref).
4046
"""
4147
function objective_value(

0 commit comments

Comments
 (0)