AnyToQUBO converter
Adam Glos
29.09.2021, Gliwice/Żory/Istanbul
Motivation
- I am in a project EuroHPC
- I have to prepare software that could be useful for the community interested in quantum computing (at least quantum annealing)
- I decided to make a package that translates the optimization model from a popupar modelling language into QUBO/HOBO
- Based on your experience I would like to improve the code
Input/Output
INPUT
- Docplex
- OR-tools
- Pyomo
- pyqubo
- qiskit
- in principle any language for modelling Integer Programming
OUTPUT
- qiskit Ising model/QUBO
- dwave-ocean-sdk
- pyqubo
- pyqubo
- qiskit
- in principle any software accepting QUBO/HOBO
# TSP
# create model
from docplex.mp.model import Model
mdl = Model('docplex model')
x = mdl.binary_var('x')
y = mdl.integer_var(lb=-1, ub=5, name='y')
mdl.minimize(x + 2 * y)
mdl.add_constraint(x - y == 3)
mdl.add_constraint((x + y) * (x - y) <= 1)
print(mdl.export_as_lp_string())
# transform to QUBO
conv = AnyToQUBO(mdl) # optionally AnyToQUBO(mdl, method="pyqubo")
conv.int_to_var(mode="binary", penalty=1000)
conv.constraints_to_objective(penalty=1000)
if conv.is_hobo():
conv.quadratize(method="pyqubo")
conv.export(package="dwave")
# solving the
solution = ...
conv.interpret(solution) # final outcome
Use case example 1
# TSP
# create model
n = 10
w_matrix = np.random.rand(n, n)
x = [Symbol(f"x{i}") for i in range(n)]
expr
for v in range(n):
for i in range(n):
for j in range(n):
expr += w[i,j] * kronecker_delta(v, i) * kronecker_delta(v+1, j)
# Make an optimization model object (to be implemented)
model = SympyOpt()
model.set_objective(expr)
# transform to QUBO
conv = AnyToQUBO(model)
conv.to_qubo(int_to_var="one-hot", penalty_int_to_var=1000) # still an abstract QUBO
conv.export(package="qiskit")
# solving the
solution = ...
conv.interpret(solution) # final outcome
Use case example 2
Conversions ways
Basic - most user friendly, it simply transforms the Integer model into QUBO/HOBO with default parameters
Intermediate - still user friendly, some parameters can be chosen but in global way (for example turn all integers into QUBO in one-hot way)
Hard - most advanced once, each integer, constraint can be transformed independently.
Transformation options
- Replace integer with bits according to some encoding (Gray, binary, unary, one-hot, mixed, etc.)
- change inequality constraint to equality constraint (slack variables)
- move equality constraint to objective function (with some penalty)
- quadratize (through pyqubo or different algorithm)
The workflow from the inside
MODEL
docplex, pyqubo, or-tools, pyomo
my general model
with sympy, maybe pyqubo
QUBO/HOBO
with sympy, maybe pyqubo
QUBO/HOBO
qiskit, pyqubo, dwave, cqirc,...
transpile
conversion
interpret
interpret
convert
SOLVER
transpile
Inside model
SymPy |
pyqubo |
---|---|
general model | only polynomials |
slow (probably) | fast |
old package | very fresh one |
arbitrary output | only QUBO as output (for now) |
no quadratization | quadratization |
- I need modelling language for processing optimization model
- it should have (advanced) arithmetic syntax and be able to simplify expressions
I plan to use both, as polynomials are very popular!
Special features
- set_var_value - for simplifying model (like in TSP)
- set_var_bounds - for changing bounds (also if modelling language do not provide this feature)
- get_logs - history of transformations
- is_qubo, is_hobo
- has_constraints, has_nonpolynomial_constraints, has_ineq_constraints, list_constraints, etc.
- has_integer_var
- is_convertable
- rm_constraint for special algorithms like QAOA+
- substitute_var(constr_name) for substituting variable according to equality constraint
Optional settings
Abstract models (we specify parameters at the very end of making QUBO)
# TSP
# create model
n = 10
w = MatrixSymbol('W', n, n)
x = [Symbol(f"x{i}") for i in range(n)]
expr
for v in range(n):
for i in range(n):
for j in range(n):
expr += w[i,j] * kronecker_delta(v, i) * kronecker_delta(v+1, j)
# Make an optimization model object (to be implemented)
model = SympyOpt()
model.set_objective(expr)
# transform to QUBO
conv = AnyToQUBO(model)
conv.to_qubo(int_to_var="one-hot", penalty_int_to_var=1000) # still an abstract QUBO
# introduce W matrix
w_matrix = np.random.rand(n, n)
conv.concretize({'W': w_matrix})
conv.export(mode="qiskit")
# solving the
solution = ...
conv.interpret(solution) # final outcome
Optional settings
removing non-polynomial operations (like Kronecker Delta, sinus, cosinus)
First option (Taylor series)
Second option (Kronecker Delta)
we only need to implement \(\delta\)
Optional settings
Mixed Integer Programming
- Some problems require both real-valued variables and integer-valued variables
- we can output mixed-integer program which after fixing real-valued variables gives QUBO
Any thoughts?
?
AnyToQUBO converter
By Adam Glos
AnyToQUBO converter
- 111