Problem modeling¶
Optimistic semantics¶
Construct the lower problem with blvpy.LowerProblem, then pass it to
blvpy.BilevelProblem.
The same lower decision-variable objects may appear in the upper objective and constraints.
BLVPY preserves those objects, so the upper problem can choose the most
favorable member of a nonsingleton lower solution set.
x = cp.Variable(name="x")
y = cp.Variable(name="y")
lower = bp.LowerProblem(
cp.Minimize(0.0 * y),
[y >= x, y <= 1.0],
parameters=[x],
)
problem = bp.BilevelProblem(
cp.Minimize(cp.square(x) + cp.square(y - 1.0)),
lower,
upper_constraints=[x >= 0.0, x <= 1.0],
)
Every variable in LowerProblem.parameters is an upper variable that BLVPY
holds fixed inside the lower problem. BLVPY clones the lower expression tree
and replaces each listed variable with a generated CVXPY parameter of matching
shape and domain.
Unlisted variables remain the original lower variables.
Structural requirements¶
The complete model must satisfy all of the following:
The upper problem is a real-valued continuous optimization problem with a scalar
cp.Minimizeorcp.Maximizeobjective.The assembled upper objective and upper constraints are compliant with CVXPY’s DNLP rules.
The lower problem is a real-valued continuous convex optimization problem: either
cp.Minimizewith a convex objective expression orcp.Maximizewith a concave objective expression.The lower problem contains at least one canonical optimization variable; constant-only lower problems are not supported.
The lower problem is DCP and DPP with respect to every linked upper variable.
Every unlinked CVXPY parameter already has a finite value.
CVXPY produces only zero, nonnegative, second-order, exponential, and 3D power-cone blocks when canonicalization is requested with a linear conic objective.
This includes linear programs, quadratic programs that CVXPY converts exactly
to the accepted conic form, second-order cone programs, and models whose exact
cp.power(..., approx=False) or cp.pnorm(..., approx=False) graphs use 3D
power cones. Exact exponential-family atoms and scalar, vector, or matrix
cp.ExpCone constraints are also accepted.
Call blvpy.BilevelProblem.validate() to obtain a specific exception for an unsupported model.
See Troubleshooting for the exception categories.
BLVPY also audits every nonlinear node in the lower source expression tree. See Supported atoms for the complete allowlist, exactness conditions, and unsupported atom families.
Objective senses and canonicalization¶
BLVPY preserves the objective objects supplied by the model. In particular,
objective returns the original cp.Minimize or
cp.Maximize object.
Internally, a lower cp.Maximize(f) objective is changed to the equivalent
cp.Minimize(-f) objective immediately before conic canonicalization. The
canonical vectors and offsets, KKT conditions, and residuals therefore always
use a minimization convention. For lower maximization, the canonical objective
\(c(x)^T u+d(x)\) equals the negative of the modeled lower objective \(f(x,y)\).
This sign convention also applies to advanced canonical inspection.
Parameters and fixed data¶
The word parameters in LowerProblem refers to upper CVXPY variables.
Ordinary CVXPY parameters may still appear as fixed lower data, but they must
have values when the model is first canonicalized.
BLVPY freezes those values into the canonical family.
Change them only by constructing and canonicalizing a new BilevelProblem.
Linked variables may be scalar, vector, or matrix valued.
Their relevant CVXPY domain attributes and native bounds= data are copied to
the generated parameters and enforced by the lifted model.
Variable values and bounds¶
Variable names are optional; CVXPY creates names automatically. Explicit names are recommended because they make initialization and validation messages more useful.
A pre-solve .value is only an initialization hint.
In ordinary deterministic solving, BLVPY uses an existing value, otherwise a
point derived from finite bounds, otherwise zero. It then applies
variable-attribute projection and a best-effort projection onto DCP upper
constraints.
The dynamically assigned variable.sample_bounds attribute is sampling-only
metadata used by explicit best_of searches.
See Best-of search for local solutions.