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
Warning

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.