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)

 

 

\exp(x) \approx 1 + x + x^2/2 + \dots + x^n/n!

Second option (Kronecker Delta)

\exp(x) = \sum_{y =\underline x}^{\overline x} \exp(y) \cdot \delta(x, y)

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?

?

Made with Slides.com