Two-stage stochastic modelsΒΆ
from collections import namedtuple
import examodels as exa
nscen = 3
Row = namedtuple("Row", "i t")
rows = [Row(i, 0.5 * i) for i in range(nscen * 4)]
core = exa.TwoStageCore(nscen)
d = exa.add_var(core, 2) # design, shared
v = exa.add_var(core, exa.EachScenario(), 4) # recourse, per scenario
exa.add_obj(core, lambda r: (v[r.i] - r.t)**2, over=rows)
exa.add_con(core, exa.EachScenario(), lambda i: v[i] - d[0],
over=range(nscen * 4))
EachScenario() marks a declaration as recourse rather than design. A per-scenario
variable declaration is replicated by the backend, so the block holds nscen times what
was asked for and is indexed flat. A per-scenario constraint is tagged rather than
replicated: supply the full index set, spanning all scenarios.
Once built:
model = exa.Model(core)
exa.get_nscen(model) # how many scenarios
exa.get_var_scen(model) # scenario of each variable, 0 for the shared first stage
exa.get_con_scen(model) # scenario of each constraint row
Tags are available directly β FirstStageTag, SecondStageTag,
FirstStageConstraintTag, SecondStageConstraintTag β and new_tag(name, kind) defines
one of your own, which can be attached with tag= on a declaration.