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
383 rows, 224 cols, 1095 nonzeros
359 rows, 151 cols, 975 nonzeros
359 rows, 151 cols, 975 nonzeros

Solving MIP model with:
   359 rows
   151 cols (27 binary, 0 integer, 0 implied int., 124 continuous)
   975 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      2         9     0.0s
 R       0       0         0   0.00%   6.133333333     6.160714286        0.44%       51     11      4        58     0.0s

25.9% inactive integer columns, restarting

Solving report
  Status            Optimal
  Primal bound      6.16071428571
  Dual bound        6.16071428571
  Gap               0% (tolerance: 0.01%)
  Solution status   feasible
                    6.16071428571 (objective)
                    0 (bound viol.)
                    0 (int. viol.)
                    0 (row viol.)
  Timing            0.03 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             0
  LP iterations     400 (total)
                    0 (strong br.)
                    59 (separation)
                    322 (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.