Using GAS with Qiskit¶
In thie Jupyter notebook, we will learn how to use Grover Adaptive Search in Qiskit Oprimization module.
Let's start with a QUBO problem we have covered in QAOA section.
To solve this using GAS, we need to define a GroverOptimizer
object as follows:
- GroverOptimizer: Qiskit doc.
In [1]:
Copied!
from qiskit_optimization.algorithms import GroverOptimizer
from qiskit_optimization.problems import QuadraticProgram
from qiskit_algorithms.utils import algorithm_globals
from qiskit_ibm_runtime import QiskitRuntimeService # Sampler from qiskit_ibm_runtime can flag error
from qiskit_optimization.translators import from_docplex_mp
from qiskit.primitives import Sampler
from docplex.mp.model import Model
from qiskit_optimization.algorithms import GroverOptimizer
from qiskit_optimization.problems import QuadraticProgram
from qiskit_algorithms.utils import algorithm_globals
from qiskit_ibm_runtime import QiskitRuntimeService # Sampler from qiskit_ibm_runtime can flag error
from qiskit_optimization.translators import from_docplex_mp
from qiskit.primitives import Sampler
from docplex.mp.model import Model
In [6]:
Copied!
# Get the real machine
service = QiskitRuntimeService(instance="ibm-q/open/main")
backend_name = service.least_busy(operational=True, simulator=False)
print(backend_name)
#backend = service.backend(backend_name, instance="ibm-q/open/main")
# Get the real machine
service = QiskitRuntimeService(instance="ibm-q/open/main")
backend_name = service.least_busy(operational=True, simulator=False)
print(backend_name)
#backend = service.backend(backend_name, instance="ibm-q/open/main")
<IBMBackend('ibm_sherbrooke')>
In [7]:
Copied!
qp = QuadraticProgram()
qp = QuadraticProgram()
In [8]:
Copied!
model = Model()
x0 = model.binary_var(name="x0")
x1 = model.binary_var(name="x1")
model.minimize( 2 * x0 + 2 * x1 - 3 * x0 * x1)
qp = from_docplex_mp(model)
print(qp.prettyprint())
model = Model()
x0 = model.binary_var(name="x0")
x1 = model.binary_var(name="x1")
model.minimize( 2 * x0 + 2 * x1 - 3 * x0 * x1)
qp = from_docplex_mp(model)
print(qp.prettyprint())
Problem name: docplex_model1 Minimize -3*x0*x1 + 2*x0 + 2*x1 Subject to No constraints Binary variables (2) x0 x1
In [9]:
Copied!
# grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler(mode = backend))
# This can flag 'The instruction h on qubits (0,) is not supported by the target system. Circuits that do not match the target hardware definition are no longer supported after March 4, 2024. See the transpilation documentation (https://docs.quantum.ibm.com/guides/transpile) for instructions to transform circuits and the primitive examples (https://docs.quantum.ibm.com/guides/primitives-examples) to see this coupled with operator transformations.'
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
# grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler(mode = backend))
# This can flag 'The instruction h on qubits (0,) is not supported by the target system. Circuits that do not match the target hardware definition are no longer supported after March 4, 2024. See the transpilation documentation (https://docs.quantum.ibm.com/guides/transpile) for instructions to transform circuits and the primitive examples (https://docs.quantum.ibm.com/guides/primitives-examples) to see this coupled with operator transformations.'
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
/var/folders/kz/_mr3r3b55qd2r5hd025yvpfw0000gn/T/ipykernel_13619/2281955874.py:4: DeprecationWarning: The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2. It will be removed no earlier than 3 months after the release date. All implementations of the `BaseSamplerV1` interface have been deprecated in favor of their V2 counterparts. The V2 alternative for the `Sampler` class is `StatevectorSampler`. grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
objective function value: 0.0 variable values: x0=0.0, x1=0.0 status: SUCCESS
Let's try $3x + 2y - 3z + 3xy$.
In [10]:
Copied!
# Example 2
# Define one more variable
x2 = model.binary_var(name="x2")
# Example 2
# Define one more variable
x2 = model.binary_var(name="x2")
In [11]:
Copied!
# Establish the model
model.minimize( 3 * x0 + 2 * x1 - 3 * x2 + 3 * x0 * x1)
qp = from_docplex_mp(model)
print(qp.prettyprint())
# Find the minima
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
# Establish the model
model.minimize( 3 * x0 + 2 * x1 - 3 * x2 + 3 * x0 * x1)
qp = from_docplex_mp(model)
print(qp.prettyprint())
# Find the minima
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
Problem name: docplex_model1 Minimize 3*x0*x1 + 3*x0 + 2*x1 - 3*x2 Subject to No constraints Binary variables (3) x0 x1 x2
/var/folders/kz/_mr3r3b55qd2r5hd025yvpfw0000gn/T/ipykernel_13619/4279303789.py:7: DeprecationWarning: The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2. It will be removed no earlier than 3 months after the release date. All implementations of the `BaseSamplerV1` interface have been deprecated in favor of their V2 counterparts. The V2 alternative for the `Sampler` class is `StatevectorSampler`. grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
objective function value: -3.0 variable values: x0=0.0, x1=0.0, x2=1.0 status: SUCCESS
In [12]:
Copied!
# Example 3
model.minimize(-x0 + 2 * x1 - 3 * x2 - 2 * x0 * x2 - 1 * x1 * x2)
qp = from_docplex_mp(model)
print(qp.prettyprint())
# Find the minima
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
# Example 3
model.minimize(-x0 + 2 * x1 - 3 * x2 - 2 * x0 * x2 - 1 * x1 * x2)
qp = from_docplex_mp(model)
print(qp.prettyprint())
# Find the minima
grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
Problem name: docplex_model1 Minimize -2*x0*x2 - x1*x2 - x0 + 2*x1 - 3*x2 Subject to No constraints Binary variables (3) x0 x1 x2
/var/folders/kz/_mr3r3b55qd2r5hd025yvpfw0000gn/T/ipykernel_13619/1049609804.py:7: DeprecationWarning: The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2. It will be removed no earlier than 3 months after the release date. All implementations of the `BaseSamplerV1` interface have been deprecated in favor of their V2 counterparts. The V2 alternative for the `Sampler` class is `StatevectorSampler`. grover_optimizer = GroverOptimizer(6, num_iterations=10, sampler=Sampler())
objective function value: -6.0 variable values: x0=1.0, x1=0.0, x2=1.0 status: SUCCESS
Constrained QUBO
In [13]:
Copied!
qp = QuadraticProgram()
qp.binary_var('x')
qp.binary_var('y')
qp.binary_var('z')
qp.minimize(linear= {'x':2}, quadratic= {('x', 'z'):1, ('z', 'y'):-2})
qp.linear_constraint(linear= {'x':2, 'y': -1, 'z':1}, sense= "<=", rhs = 2)
print(qp.export_as_lp_string())
#print(qp.prettyprint())
qp = QuadraticProgram()
qp.binary_var('x')
qp.binary_var('y')
qp.binary_var('z')
qp.minimize(linear= {'x':2}, quadratic= {('x', 'z'):1, ('z', 'y'):-2})
qp.linear_constraint(linear= {'x':2, 'y': -1, 'z':1}, sense= "<=", rhs = 2)
print(qp.export_as_lp_string())
#print(qp.prettyprint())
\ This file has been generated by DOcplex \ ENCODING=ISO-8859-1 \Problem name: CPLEX Minimize obj: 2 x + [ 2 x*z - 4 y*z ]/2 Subject To c0: 2 x - y + z <= 2 Bounds 0 <= x <= 1 0 <= y <= 1 0 <= z <= 1 Binaries x y z End
In [14]:
Copied!
from qiskit_optimization.converters import QuadraticProgramToQubo
qp_to_qubo = QuadraticProgramToQubo()
qubo = qp_to_qubo.convert(qp)
print(qubo.export_as_lp_string())
from qiskit_optimization.converters import QuadraticProgramToQubo
qp_to_qubo = QuadraticProgramToQubo()
qubo = qp_to_qubo.convert(qp)
print(qubo.export_as_lp_string())
\ This file has been generated by DOcplex \ ENCODING=ISO-8859-1 \Problem name: CPLEX Minimize obj: - 46 x + 24 y - 24 z - 24 c0@int_slack@0 - 48 c0@int_slack@1 + [ 48 x^2 - 48 x*y + 50 x*z + 48 x*c0@int_slack@0 + 96 x*c0@int_slack@1 + 12 y^2 - 28 y*z - 24 y*c0@int_slack@0 - 48 y*c0@int_slack@1 + 12 z^2 + 24 z*c0@int_slack@0 + 48 z*c0@int_slack@1 + 12 c0@int_slack@0^2 + 48 c0@int_slack@0*c0@int_slack@1 + 48 c0@int_slack@1^2 ]/2 + 24 Subject To Bounds 0 <= x <= 1 0 <= y <= 1 0 <= z <= 1 0 <= c0@int_slack@0 <= 1 0 <= c0@int_slack@1 <= 1 Binaries x y z c0@int_slack@0 c0@int_slack@1 End
Solving QUBO
In [15]:
Copied!
# Solving QUBO
grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
results = grover_optimizer.solve(qubo)
print(results.prettyprint())
# Solving QUBO
grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
results = grover_optimizer.solve(qubo)
print(results.prettyprint())
/var/folders/kz/_mr3r3b55qd2r5hd025yvpfw0000gn/T/ipykernel_13619/521563221.py:1: DeprecationWarning: The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2. It will be removed no earlier than 3 months after the release date. All implementations of the `BaseSamplerV1` interface have been deprecated in favor of their V2 counterparts. The V2 alternative for the `Sampler` class is `StatevectorSampler`. grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
objective function value: -2.0 variable values: x=0.0, y=1.0, z=1.0, c0@int_slack@0=0.0, c0@int_slack@1=1.0 status: SUCCESS
Solving qp
In [ ]:
Copied!
grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
results = grover_optimizer.solve(qp)
print(results.prettyprint())
/var/folders/kz/_mr3r3b55qd2r5hd025yvpfw0000gn/T/ipykernel_13619/2588980930.py:1: DeprecationWarning: The class ``qiskit.primitives.sampler.Sampler`` is deprecated as of qiskit 1.2. It will be removed no earlier than 3 months after the release date. All implementations of the `BaseSamplerV1` interface have been deprecated in favor of their V2 counterparts. The V2 alternative for the `Sampler` class is `StatevectorSampler`. grover_optimizer = GroverOptimizer(10, num_iterations=4, sampler=Sampler())
objective function value: -2.0 variable values: x=0.0, y=1.0, z=1.0 status: SUCCESS
You should get the exact result like the qubo but without slack variables.