Presolve and multistart¶
Presolve¶
result = pympcc.solve(problem, strategy="scholtes", presolve=True)
Two passes run when presolve=True:
Pinned-variable elimination — variables with
xl[j] == xu[j]are substituted out of the optimisation; results are auto-expanded back to the original variable space.Linear FBBT — feasibility-based bound tightening on rows detected as linear by a single bounded perturbation. Up to 50 fixed-point sweeps; detected infeasibility falls back to the identity map and emits a
UserWarning.
When nothing can be eliminated, the presolve is a no-op.
For finer control:
from pympcc import presolve
reduced_problem, pmap = presolve(problem)
result = pympcc.solve(reduced_problem)
expanded_x = pmap.expand(result.x) # back to original n
Multistart¶
ms = pympcc.multistart(
problem,
n_starts=20,
perturb_scale=0.5,
seed=0,
strategy="scholtes", # forwarded as solve_kwargs
)
ms.best # MPCCResult — best run by objective among successes
ms.runs # list[MPCCResult] — every start
Useful when the MPCC has multiple stationary points (typical for bilevel and equilibrium models). Each start perturbs x0 by perturb_scale * randn(n). Currently sequential; parallel n_jobs is on the roadmap (§6.1).