Solving QUBO

QUBODrivers samplers are MathOptInterface optimizers, so the usual JuMP workflow applies: choose an optimizer, build a binary or spin model, call optimize!, and query results with JuMP or MOI.

Build and Solve a Binary QUBO

The built-in ExactSampler.Optimizer is deterministic and enumerates all states, making it useful for small examples and correctness checks.

using JuMP
using QUBODrivers

model = Model(ExactSampler.Optimizer)

Q = [
    -1.0  2.0  2.0
     2.0 -1.0  2.0
     2.0  2.0 -1.0
]

@variable(model, x[1:3], Bin)
@objective(model, Min, x' * Q * x)

optimize!(model)

Query Results

Samplers may return more than one result. Use result_count(model) to iterate through the available states.

solutions = [
    (round.(Int, value.(x; result = i)), objective_value(model; result = i))
    for i in 1:result_count(model)
]

minimum(last, solutions)
-1.0

The same results are available through MOI:

MOI = QUBODrivers.MOI

MOI.get(backend(model), MOI.ResultCount())

Set Sampler Attributes

Sampler options can be set with standard MOI raw optimizer attributes or JuMP's set_optimizer_attribute.

using JuMP
using QUBODrivers

model = Model(RandomSampler.Optimizer)
set_optimizer_attribute(model, "num_reads", 10)
set_optimizer_attribute(model, "seed", 123)

@variable(model, x[1:3], Bin)
@objective(model, Min, -x[1] - x[2] - x[3] + 2x[1] * x[2])

optimize!(model)

result_count(model)
6

Typed attributes generated by QUBODrivers.@setup can also be used directly through MOI:

optimizer = RandomSampler.Optimizer()
MOI.set(optimizer, RandomSampler.NumberOfReads(), 10)
MOI.set(optimizer, RandomSampler.RandomSeed(), 123)

Fixed Variables and Starts

QUBODrivers supports binary variables, spin variables, fixed variable constraints, and MOI.VariablePrimalStart. In JuMP, fixed variables can be created with fix.

using JuMP
using QUBODrivers

model = Model(ExactSampler.Optimizer)

@variable(model, x[1:2], Bin)
fix(x[1], 1; force = true)
@objective(model, Min, -x[1] + x[1] * x[2])

optimize!(model)

round.(Int, value.(x; result = 1))
2-element Vector{Int64}:
 1
 0

Use IdentitySampler.Optimizer when you want the sampler result to be exactly the provided warm-start state. Set starts through MOI.VariablePrimalStart before optimization:

MOI.set(model, MOI.VariablePrimalStart(), variable, start_value)

Supported Model Shape

QUBODrivers samplers accept unconstrained binary or spin models with linear, quadratic, or single-variable objectives. MOI bridges may reformulate some JuMP input, but sampler backends ultimately receive a QUBOTools model in one domain:

  • boolean variables in $\{0, 1\}$;
  • spin variables in $\{-1, 1\}$;
  • minimization or maximization objective sense;
  • optional fixed variables folded into the internal model before sampling.