নোট

এই পৃষ্ঠাটি docs/tutorials/02_converters_for_quadratic_programs.ipynb থেকে বানানো হয়েছে।

# দ্বিঘাত (কোয়াড্রাটিক) প্রোগ্রামগুলির জন্য পরিবর্তক (কনভার্টার)#

Optimization problems in Qiskit optimization module are represented with the QuadraticProgram class, which is a generic and powerful representation for optimization problems. In general, optimization algorithms are defined for a certain formulation of a quadratic program, and we need to convert our problem to the right type.

For instance, Qiskit optimization provides several optimization algorithms that can handle Quadratic Unconstrained Binary Optimization (QUBO) problems. These are mapped to Ising Hamiltonians, for which Qiskit optimization uses the qiskit.quantum_info.SparsePauliOp object, and then their ground state is approximated. For this optimization, commonly known algorithms such as VQE or QAOA can be used as underlying routine. See the following tutorial about the Minimum Eigen Optimizer for more detail. Note that also other algorithms exist that work differently, such as the GroverOptimizer.

To map a problem to the correct input format, the optimization module of Qiskit optimization offers a variety of converters. In this tutorial we’re providing an overview on this functionality. Currently, Qiskit optimization contains the following converters.

• InequalityToEquality: convert inequality constraints into equality constraints with additional slack variables.

• IntegerToBinary: convert integer variables into binary variables and corresponding coefficients.

• LinearEqualityToPenalty: convert equality constraints into additional terms of the objective function.

• LinearInequalityToPenalty: convert inequality constraints into additional terms of the objective function.

• MaximizeToMinimize: convert to the equivalent minimization problem.

• MinimizeToMaximize: convert to the equivalent maximization problem.

• QuadraticProgramToQubo: a wrapper that includes InequalityToEquality, IntegerToBinary, LinearEqualityToPenalty, LinearInequalityToPenalty, and MaximizeToMinimize for convenience.

## InequalityToEquality#

InequalityToEqualityConverter টি QuadraticProgram থেকে অসমতার সীমাবদ্ধতা অপসারণ করতে অতিরিক্ত স্ল্যাক চল রাশির সাথে অসমতার সীমাবদ্ধতায় রূপান্তর করে। উপরের সীমা (আবদ্ধ) এবং স্ল্যাক ভেরিয়েবলের নিম্নসীমা বাম দিক এবং সীমাবদ্ধতার ডান দিকের পার্থক্য থেকে গণনা করা হবে। স্ল্যাক চল রাশির চিহ্নগুলি $$\leq$$ এবং $$\geq$$ এর মতো সীমাবদ্ধতার মধ্যে চিহ্নগুলির উপর নির্ভর করে।

নীচে দুটি অসমতার সীমাবদ্ধতার সাথে সর্বাধিক সমস্যার একটি উদাহরণ রয়েছে। চল রাশি $$x$$ এবং $$y$$ বাইনারি চল রাশি এবং চল রাশি : $$z$$ একটি পূর্ণসংখ্যার চল রাশি ।

QuadraticProgram এর সাহায্যে সমস্যার একটি অপ্টিমাইজেশন মডেল নীচে লেখা আছে।

[1]:

from qiskit_optimization import QuadraticProgram
from qiskit_optimization.translators.docplex_mp import to_docplex_mp

[2]:

qp = QuadraticProgram()
qp.binary_var("x")
qp.binary_var("y")
qp.integer_var(lowerbound=0, upperbound=7, name="z")

qp.maximize(linear={"x": 3, "y": 2, "z": 1})
qp.linear_constraint(linear={"x": 1, "y": 1, "z": 1}, sense="LE", rhs=5.5, name="xyz_leq")
qp.linear_constraint(linear={"x": 1, "y": 1, "z": 1}, sense="GE", rhs=2.5, name="xyz_geq")
print(qp.prettyprint())

Problem name:

Maximize
3*x + 2*y + z

Subject to
Linear constraints (2)
x + y + z <= 5.5  'xyz_leq'
x + y + z >= 2.5  'xyz_geq'

Integer variables (1)
0 <= z <= 7

Binary variables (2)
x y



রূপান্তর করতে InequalityToEquality এর convert পদ্ধতিটি কল করুন।

[3]:

from qiskit_optimization.converters import InequalityToEquality

[4]:

ineq2eq = InequalityToEquality()
qp_eq = ineq2eq.convert(qp)
print(qp_eq.prettyprint())

Problem name:

Maximize
3*x + 2*y + z

Subject to
Linear constraints (2)
x + xyz_leq@int_slack + y + z == 5  'xyz_leq'
x - xyz_geq@int_slack + y + z == 3  'xyz_geq'

Integer variables (3)
0 <= z <= 7
0 <= xyz_leq@int_slack <= 5
0 <= xyz_geq@int_slack <= 6

Binary variables (2)
x y



After converting, the formulation of the problem looks like the above output. As we can see, the inequality constraints are replaced with equality constraints with additional integer slack variables, $$xyz\_leg\text{@}int\_slack$$ and $$xyz\_geq\text{@}int\_slack$$.

Let us explain how the conversion works. For example, the lower bound of the left side of the first constraint is $$0$$ which is the case of $$x=0$$, $$y=0$$, and $$z=0$$. Thus, the upper bound of the additional integer variable must be $$5$$ to be able to satisfy even the case of $$x=0$$, $$y=0$$, and $$z=0$$. Note that we cut off the part after the decimal point in the converted formulation since the left side of the first constraint in the original formulation can be only integer values. For the second constraint, basically we apply the same approach. However, the symbol in the second constraint is $$\geq$$, so we add minus before $$xyz\_geq\text{@}int\_slack$$ to be able to satisfy even the case of $$x=1, y=1$$, and $$z=7$$.

Let us see how the interpret method works. The purpose of this method is to convert the solution of the converted problem back to that of the original problem. To use this method, we would first require to solve the problem. For the purpose of this tutorial, we will use docplex to solve. We will first translate the quadratic problem into a docplex.mp model.

[5]:

from qiskit_optimization.algorithms import CplexOptimizer

cplex_optimizer = CplexOptimizer()

[6]:

result_orig = cplex_optimizer.solve(qp)
print(result_orig)

fval=8.0, x=1.0, y=1.0, z=3.0, status=SUCCESS

[7]:

result_eq = cplex_optimizer.solve(qp_eq)
print(result_eq)

fval=8.0, x=1.0, y=1.0, z=3.0, xyz_leq@int_slack=0.0, xyz_geq@int_slack=2.0, status=SUCCESS


The result result_eq of qp_eq has 5 variable values (x=1.0, y=1.0, z=3.0, xyz_leq@int_slack=0.0, xyz_geq@int_slack=2.0) while result result_orig of the original qp has three values (x=1.0, y=1.0, z=3.0). We can call InequalityToEquality.interpret method by passing a list or an array to the method that has values of qp_eq.variables as follows. result_eq.x has the list of values that each variable takes in the solution in correspondence to their position in the variable list qp_eq.variables.

[8]:

print("interpreting values of result_eq:", ineq2eq.interpret(result_eq.x))
print("values of result_orig:", result_orig.x)

interpreting values of result_eq: [1. 1. 3.]
values of result_orig: [1. 1. 3.]


We notice that $$[1., 1., 3.]$$ are the values taken in the solution of the converted problem for the common variables between converted and original problems (variables: $$x$$, $$y$$, $$z$$). The interpret method shows the same values are the solution of the original problem. This is because the objective function for the converted and original problems is exactly the same. The slack variables are just ensuring equality in the constraints of the converted problem, where the constraints are also exactly same between the original and converted problems, except that the original problem has inequality constraints.

## IntegerToBinary#

IntegerToBinary পূর্ণসংখ্যার চল রাশিগুলিকে বাইনারি চল রাশি এবং সহগগুলিকে QuadraticProgram থেকে পূর্ণসংখ্য ভেরিয়েবলগুলি সরাতে রূপান্তর করে। রূপান্তর করার জন্য, প্রস্তাবিত সীমাবদ্ধ-গুণফলের এনকোডিং arxiv:1706.01945 (Eq. (5)) ব্যবহৃত হয়। এনকোডিং পদ্ধতির আরও বিশদের জন্য দয়া করে গবেষণাটি দেখুন।

We use the output of InequalityToEquality as a starting point. Variables $$x$$ and $$y$$ are binary variables, while the variable $$z$$ and the slack variables $$xyz\_leq\text{@}int\_slack$$ and $$xyz\_geq\text{@}int\_slack$$ are integer variables. We print the problem again for reference.

[9]:

print(qp_eq.prettyprint())

Problem name:

Maximize
3*x + 2*y + z

Subject to
Linear constraints (2)
x + xyz_leq@int_slack + y + z == 5  'xyz_leq'
x - xyz_geq@int_slack + y + z == 3  'xyz_geq'

Integer variables (3)
0 <= z <= 7
0 <= xyz_leq@int_slack <= 5
0 <= xyz_geq@int_slack <= 6

Binary variables (2)
x y



রূপান্তর করতে IntegerToBinary এর convert পদ্ধতিটি কল করুন।.

[10]:

from qiskit_optimization.converters import IntegerToBinary

[11]:

int2bin = IntegerToBinary()
qp_eq_bin = int2bin.convert(qp_eq)
print(qp_eq_bin.prettyprint())

Problem name:

Maximize
3*x + 2*y + z@0 + 2*z@1 + 4*z@2

Subject to
Linear constraints (2)
x + xyz_leq@int_slack@0 + 2*xyz_leq@int_slack@1 + 2*xyz_leq@int_slack@2 + y
+ z@0 + 2*z@1 + 4*z@2 == 5  'xyz_leq'
x - xyz_geq@int_slack@0 - 2*xyz_geq@int_slack@1 - 3*xyz_geq@int_slack@2 + y
+ z@0 + 2*z@1 + 4*z@2 == 3  'xyz_geq'

Binary variables (11)
x y z@0 z@1 z@2 xyz_leq@int_slack@0 xyz_leq@int_slack@1 xyz_leq@int_slack@2
xyz_geq@int_slack@0 xyz_geq@int_slack@1 xyz_geq@int_slack@2



After converting, the integer variable $$z$$ is replaced with three binary variables $$z\text{@}0$$, $$z\text{@}1$$ and $$z\text{@}2$$ with coefficients 1, 2 and 4, respectively as the above. The slack variables $$xyz\_leq\text{@}int\_slack$$ and $$xyz\_geq\text{@}int\_slack$$ that were introduced by InequalityToEquality are also both replaced with three binary variables with coefficients 1, 2, 2, and 1, 2, 3, respectively.

টীকা: মূলত সহগের অর্থ হল সহগের সাথে এই বাইনারি চল রাশি গুলির যোগফল $$\{1, 2, 4\}$$, $$\{1, 2, 2\}$$,এবং $$\{1, 2, 3\}$$ এর একটি সাবসেটের যোগফল হতে পারে এবং সেই গ্রহণযোগ্য মানগুলি উপস্থাপন করে $$\{0, \ldots, 7\}$$, $$\{0, \ldots, 5\}$$, এবং $$\{0, \ldots, 6\}$$, যা নীচের বাউন্ড এবং মূল সংখ্যার ভেরিয়েবলের উপরের সীমানাকে সঠিকভাবে মেনে চলে ।

IntegerToBinary also provides interpret method that is the functionality to translate a given binary result back to the original integer representation. Let us see how the interpret method works.

[12]:

result_eq = cplex_optimizer.solve(qp_eq)
print(result_eq)

fval=8.0, x=1.0, y=1.0, z=3.0, xyz_leq@int_slack=0.0, xyz_geq@int_slack=2.0, status=SUCCESS

[13]:

result_eq_bin = cplex_optimizer.solve(qp_eq_bin)
print(result_eq_bin)

fval=8.0, x=1.0, y=1.0, z@0=1.0, z@1=1.0, z@2=0.0, xyz_leq@int_slack@0=0.0, xyz_leq@int_slack@1=0.0, xyz_leq@int_slack@2=0.0, xyz_geq@int_slack@0=0.0, xyz_geq@int_slack@1=1.0, xyz_geq@int_slack@2=0.0, status=SUCCESS


result_eq_bin has more binary variables due to the conversion by IntegerToBinary.convert. IntegerToBinary.interpret translates them back to the integer values by aggregating binary variables values associated with the original integer variables of qp_eq.

[14]:

print("interpreting values of result_eq_bin:", int2bin.interpret(result_eq_bin.x))
print("values of result_eq:", result_eq.x)

interpreting values of result_eq_bin: [1. 1. 3. 0. 2.]
values of result_eq: [1. 1. 3. 0. 2.]


## LinearEqualityToPenalty#

LinearEqualityToPenalty converts linear equality constraints into additional quadratic penalty terms of the objective function to map QuadraticProgram to an unconstrained form. An input to the converter has to be a QuadraticProgram with only linear equality constraints. Those equality constraints, e.g. $$\sum_i a_i x_i = b$$ where $$a_i$$ and $$b$$ are numbers and $$x_i$$ is a variable, will be added to the objective function in the form of $$M(b - \sum_i a_i x_i)^2$$ where $$M$$ is a large number as penalty factor. By default $$M= 1e5$$. The sign of the term depends on whether the problem type is a maximization or minimization.

We use the output of IntegerToBinary as a starting point, where all variables are binary variables and all inequality constraints have been mapped to equality constraints. We print the problem again for reference.

[15]:

print(qp_eq_bin.prettyprint())

Problem name:

Maximize
3*x + 2*y + z@0 + 2*z@1 + 4*z@2

Subject to
Linear constraints (2)
x + xyz_leq@int_slack@0 + 2*xyz_leq@int_slack@1 + 2*xyz_leq@int_slack@2 + y
+ z@0 + 2*z@1 + 4*z@2 == 5  'xyz_leq'
x - xyz_geq@int_slack@0 - 2*xyz_geq@int_slack@1 - 3*xyz_geq@int_slack@2 + y
+ z@0 + 2*z@1 + 4*z@2 == 3  'xyz_geq'

Binary variables (11)
x y z@0 z@1 z@2 xyz_leq@int_slack@0 xyz_leq@int_slack@1 xyz_leq@int_slack@2
xyz_geq@int_slack@0 xyz_geq@int_slack@1 xyz_geq@int_slack@2



রূপান্তর করতে LinearEqualityToPenalty এর convert পদ্ধতিটি কল করুন।.

[16]:

from qiskit_optimization.converters import LinearEqualityToPenalty

[17]:

lineq2penalty = LinearEqualityToPenalty()
qubo = lineq2penalty.convert(qp_eq_bin)
print(qubo.prettyprint())

Problem name:

Maximize
-26*x^2 + 26*x*xyz_geq@int_slack@0 + 52*x*xyz_geq@int_slack@1
+ 78*x*xyz_geq@int_slack@2 - 26*x*xyz_leq@int_slack@0
- 52*x*xyz_leq@int_slack@1 - 52*x*xyz_leq@int_slack@2 - 52*x*y - 52*x*z@0
- 104*x*z@1 - 208*x*z@2 - 13*xyz_geq@int_slack@0^2
- 52*xyz_geq@int_slack@0*xyz_geq@int_slack@1
- 78*xyz_geq@int_slack@0*xyz_geq@int_slack@2 - 52*xyz_geq@int_slack@1^2
- 156*xyz_geq@int_slack@1*xyz_geq@int_slack@2 - 117*xyz_geq@int_slack@2^2
- 13*xyz_leq@int_slack@0^2 - 52*xyz_leq@int_slack@0*xyz_leq@int_slack@1
- 52*xyz_leq@int_slack@0*xyz_leq@int_slack@2 - 52*xyz_leq@int_slack@1^2
- 104*xyz_leq@int_slack@1*xyz_leq@int_slack@2 - 52*xyz_leq@int_slack@2^2
+ 26*y*xyz_geq@int_slack@0 + 52*y*xyz_geq@int_slack@1
+ 78*y*xyz_geq@int_slack@2 - 26*y*xyz_leq@int_slack@0
- 52*y*xyz_leq@int_slack@1 - 52*y*xyz_leq@int_slack@2 - 26*y^2 - 52*y*z@0
- 104*y*z@1 - 208*y*z@2 + 26*z@0*xyz_geq@int_slack@0
+ 52*z@0*xyz_geq@int_slack@1 + 78*z@0*xyz_geq@int_slack@2
- 26*z@0*xyz_leq@int_slack@0 - 52*z@0*xyz_leq@int_slack@1
- 52*z@0*xyz_leq@int_slack@2 - 26*z@0^2 - 104*z@0*z@1 - 208*z@0*z@2
+ 52*z@1*xyz_geq@int_slack@0 + 104*z@1*xyz_geq@int_slack@1
+ 156*z@1*xyz_geq@int_slack@2 - 52*z@1*xyz_leq@int_slack@0
- 104*z@1*xyz_leq@int_slack@1 - 104*z@1*xyz_leq@int_slack@2 - 104*z@1^2
- 416*z@1*z@2 + 104*z@2*xyz_geq@int_slack@0 + 208*z@2*xyz_geq@int_slack@1
+ 312*z@2*xyz_geq@int_slack@2 - 104*z@2*xyz_leq@int_slack@0
- 208*z@2*xyz_leq@int_slack@1 - 208*z@2*xyz_leq@int_slack@2 - 416*z@2^2
+ 211*x - 78*xyz_geq@int_slack@0 - 156*xyz_geq@int_slack@1
- 234*xyz_geq@int_slack@2 + 130*xyz_leq@int_slack@0 + 260*xyz_leq@int_slack@1
+ 260*xyz_leq@int_slack@2 + 210*y + 209*z@0 + 418*z@1 + 836*z@2 - 442

Subject to
No constraints

Binary variables (11)
x y z@0 z@1 z@2 xyz_leq@int_slack@0 xyz_leq@int_slack@1 xyz_leq@int_slack@2
xyz_geq@int_slack@0 xyz_geq@int_slack@1 xyz_geq@int_slack@2



After converting, the equality constraints are added to the objective function as additional terms with the default penalty factor provided by Qiskit optimization. The resulting problem is now a QUBO and compatible with many quantum optimization algorithms such as VQE, QAOA and so on.

এটি আগের মতো একই ফলাফল দেয়।.

Like we did for the other converters, let us see how interpret method works for this case.

[18]:

result_eq_bin = cplex_optimizer.solve(qp_eq_bin)
print(result_eq_bin)

fval=8.0, x=1.0, y=1.0, z@0=1.0, z@1=1.0, z@2=0.0, xyz_leq@int_slack@0=0.0, xyz_leq@int_slack@1=0.0, xyz_leq@int_slack@2=0.0, xyz_geq@int_slack@0=0.0, xyz_geq@int_slack@1=1.0, xyz_geq@int_slack@2=0.0, status=SUCCESS

[19]:

result_qubo = cplex_optimizer.solve(qubo)
print(result_qubo)

fval=8.0, x=1.0, y=1.0, z@0=1.0, z@1=1.0, z@2=0.0, xyz_leq@int_slack@0=0.0, xyz_leq@int_slack@1=0.0, xyz_leq@int_slack@2=0.0, xyz_geq@int_slack@0=0.0, xyz_geq@int_slack@1=1.0, xyz_geq@int_slack@2=0.0, status=SUCCESS

[20]:

print("interpreting values of result_eq_bin:", lineq2penalty.interpret(result_qubo.x))
print("values of result_eq_bin:", result_eq_bin.x)

interpreting values of result_eq_bin: [1. 1. 1. 1. 0. 0. 0. 0. 0. 1. 0.]
values of result_eq_bin: [1. 1. 1. 1. 0. 0. 0. 0. 0. 1. 0.]


We can see that the result of the interpret method implies that both the original and converted problems have exactly the same solution. This is expected because the converted problem has exactly the same variables as the original problem, the objective has been modified in such a way that we do not have the constraints anymore in the converted problem.

Finally, let us see how we interpret the result of QUBO back to the solution of the original problem qp. The following code shows that the interpreted values are equivalent to the result of the original problem qp.

[21]:

print("result_orig.x", result_orig.x)

x = result_qubo.x
for conv in [lineq2penalty, int2bin, ineq2eq]:
x = conv.interpret(x)
print("interpreting result_qubo.x", x)

result_orig.x [1. 1. 3.]
interpreting result_qubo.x [1. 1. 3.]

[22]:

import qiskit.tools.jupyter

%qiskit_version_table


### Version Information

SoftwareVersion
qiskit0.44.1
qiskit-terra0.45.0.dev0+dcec79e
qiskit_optimization0.6.0
qiskit_algorithms0.3.0
System information
Python version3.10.13
Python compilerClang 14.0.3 (clang-1403.0.22.14.1)
Python buildmain, Aug 24 2023 22:36:46
OSDarwin
CPUs10
Memory (Gb)64.0
Thu Sep 07 12:33:31 2023 JST

### This code is a part of Qiskit

[ ]:


`