Using QuadraticToBinary
QuadraticToBinary.jl is a package that converts quadratic terms in constraints and objectives. To do so the package 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┌ Warning: primal_var_dual_quad_slack field is deprecated, use primal_var_in_quad_obj_to_dual_slack_var instead
└ @ Dualization ~/.julia/packages/Dualization/lt5ES/src/structures.jl:251
┌ Warning: primal_parameter field is deprecated, use primal_parameter_to_dual_parameter instead
└ @ Dualization ~/.julia/packages/Dualization/lt5ES/src/structures.jl:248
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 86 0.0s
B 19 1 7 12.50% 6.133333333 7.999880288 23.33% 390 59 354 8671 1.0s
T 54 0 12 50.01% 6.133333333 6.133333333 0.00% 433 65 369 9835 1.0s
Solving report
Status Optimal
Primal bound 6.13333333333
Dual bound 6.13333333333
Gap 0% (tolerance: 0.01%)
Solution status feasible
6.13333333333 (objective)
0 (bound viol.)
0 (int. viol.)
0 (row viol.)
Timing 1.01 (total)
0.00 (presolve)
0.00 (postsolve)
Nodes 60
LP iterations 9922 (total)
1968 (strong br.)
246 (separation)
6442 (heuristics)However, this might lead to some solver not supporting certain functionality like SCIP. In this case we need to:
using SCIPSCIP 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 a constructor and not an instance of an object.
This page was generated using Literate.jl.