Two-Stage Optimization
ExaModels supports two-stage optimization problems. This feature enables efficient modeling of optimization problems where decisions are made in two stages:
- Design (first-stage) variables: Decisions made before uncertainty is revealed, shared across all scenarios
- Recourse (second-stage) variables: Scenario-specific decisions made after uncertainty is revealed
- Scenarios: Each scenario has its own parameters θ that affect the objective and constraints
using ExaModels, NLPModelsIpoptDefine the problem dimensions and scenario parameters:
ns = 3 ## number of scenarios
nv = 2 ## recourse variables per scenario
nd = 1 ## design variables
weight = 1.0 / ns0.3333333333333333Two annotate the scenario for each variable and constraint, we can use the scenario we need to start with a special ExaCore that supports such scenario annotations, which can be created by calling TwoStageExaCore().
core = TwoStageExaCore()An ExaCore
Float type: ...................... Float64
Array type: ...................... Vector{Float64}
Backend: ......................... Nothing
number of objective patterns: .... 0
number of constraint patterns: ... 0
Now we can define the design variable and recourse variables. The scenario keyword argument allows us to specify which scenario(s) each variable belongs to. For the design variable d, we set scenario = 0 to indicate that it is shared across all scenarios.
d = variable(core; start = 1.0, lvar = 0.0, uvar = Inf, scenario = 0) ## design variable dExaModels.Var{Int64}(1)For the recourse variables v, we specify scenario = [i for i=1:ns, j=1:nv] to indicate that each variable v[s,i] belongs to scenario s. This allows us to define scenario-specific constraints and objectives that involve these recourse variables.
v = variable(core, ns, nv; start = 1.0, lvar = 0.0, uvar = Inf, scenario = [i for i=1:ns, j=1:nv]) ## recourse variables vVariable
x ∈ R^{3 × 2}
Now we can define the constraints and objective function. The scenario keyword argument in the constraint and objective functions allows us to specify which scenario(s) each constraint or objective term belongs to.
constraint(core, v[s,1] - v[s,2]^2 for s in 1:ns; lcon = 0.0, scenario = 1:ns)
objective(core, d^2)
objective(core, weight * (v[s,i] - d)^2 for s in 1:ns, i in 1:nv)
m = ExaModel(core)An ExaModel{Float64, Vector{Float64}, ...}
Problem name: Generic
All variables: ████████████████████ 7 All constraints: ████████████████████ 3
free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 free: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
lower: ████████████████████ 7 lower: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 upper: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
low/upp: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 low/upp: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
fixed: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 fixed: ████████████████████ 3
infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0 infeas: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
nnzh: ( 21.43% sparsity) 22 linear: ⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅⋅ 0
nonlinear: ████████████████████ 3
nnzj: ( 71.43% sparsity) 6
lin_nnzj: (------% sparsity)
nln_nnzj: ( 71.43% sparsity) 6
Now we can solve the model as usual.
ipopt(m)"Execution stats: first-order stationary"If the solver knows how to exploit the scenario structure, the structure-exploiting method can be used.
This page was generated using Literate.jl.