Using QuadraticToBinary
QuadraticToBinary.jl is a package that converts quadratic terms in constraints and objective. To do so the pack acts like a solver on top of the real solver and most data is forwarded directly to the solver itself. For many solvers it is enough to use:
using BilevelJuMP, QuadraticToBinary, HiGHS
SOLVER = HiGHS.Optimizer()
Q_SOLVER = QuadraticToBinary.Optimizer{Float64}(SOLVER, lb = -10, ub = 10)
model = BilevelModel(()->Q_SOLVER, mode = BilevelJuMP.ProductMode(1e-6))
@variable(Lower(model), x)
@variable(Upper(model), y)
@objective(Upper(model), Min, 3x + y)
@constraints(Upper(model), begin
x <= 5
y <= 8
y >= 0
end)
@objective(Lower(model), Min, -x)
@constraints(Lower(model), begin
x + y <= 8
4x + y >= 8
2x + y <= 13
2x - 7y <= 0
end)
optimize!(model)
objective_value(model)
@assert abs(objective_value(model) - (3 * (3.5 * 8/15) + 8/15)) < 1e-1 # src
Running HiGHS 1.5.1 [date: 1970-01-01, git hash: 93f1876e4] Copyright (c) 2023 HiGHS under MIT licence terms Presolving model 503 rows, 224 cols, 1453 nonzeros 408 rows, 193 cols, 1235 nonzeros Solving MIP model with: 408 rows 193 cols (56 binary, 0 integer, 0 implied int., 137 continuous) 1235 nonzeros Nodes | B&B Tree | Objective Bounds | Dynamic Constraints | Work Proc. InQueue | Leaves Expl. | BestBound BestSol Gap | Cuts InLp Confl. | LpIters Time 0 0 0 0.00% 0 inf inf 0 0 0 0 0.0s 0 0 0 0.00% 6.133333333 inf inf 0 0 4 87 0.0s L 0 0 0 0.00% 6.133333333 6.133333333 0.00% 432 90 38 366 0.2s Solving report Status Optimal Primal bound 6.13333333338 Dual bound 6.13333333333 Gap 0% (tolerance: 0.01%) Solution status feasible 6.13333333338 (objective) 0 (bound viol.) 0 (int. viol.) 0 (row viol.) Timing 0.20 (total) 0.00 (presolve) 0.00 (postsolve) Nodes 1 LP iterations 823 (total) 0 (strong br.) 279 (separation) 457 (heuristics)
However, this might lead to some solver not supporting certain functionality like SCIP. In this case we need to:
using SCIP
SCIP requires a non-standard installation procedure in windows. See SCIP.jl for more details.
SOLVER = SCIP.Optimizer()
CACHED_SOLVER = MOI.Utilities.CachingOptimizer(
MOI.Utilities.UniversalFallback(MOI.Utilities.Model{Float64}()), SOLVER)
Q_SOLVER = QuadraticToBinary.Optimizer{Float64}(CACHED_SOLVER)
BilevelModel(()->Q_SOLVER, mode = BilevelJuMP.ProductMode(1e-5))
An Abstract JuMP Model Feasibility problem with: Variables: 0 Upper Constraints: 0 Lower Constraints: 0 Bilevel Model Solution method: BilevelJuMP.ProductMode{Float64}(1.0e-5, false, 0, nothing) Solver name: QuadraticToBinary [SCIP]
Note that we used ()->Q_SOLVER
instead of just Q_SOLVER
because BilevelModel
requires as constructor and not an instance of an object.
This page was generated using Literate.jl.