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
 B      37       1        13  55.50%   6.133333333     7.999889051       23.33%      351     56    442      6559     0.6s
 T      92       0        25  98.46%   6.133333333     6.133333333        0.00%      424     62    517      9902     0.7s

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.)
                    4.40758540776e-13 (int. viol.)
                    0 (row viol.)
  Timing            0.71 (total)
                    0.00 (presolve)
                    0.00 (postsolve)
  Nodes             94
  LP iterations     9928 (total)
                    3706 (strong br.)
                    260 (separation)
                    3316 (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.