Guía de Migración de Qiskit Optimization v0.5#

Este tutorial te guiará a través del proceso de migración de tu código de Qiskit Optimization v0.4 a v0.5.

Descripción General#

Qiskit Terra v0.22 presenta nuevas implementaciones de algoritmos que aprovechan las Primitivas de Qiskit (Estimator y Sampler). Las implementaciones de algoritmos anteriores que aprovechan el flujo de operaciones quedarán obsoletas en la versión futura.

Qiskit Optimization v0.5 es compatible con los algoritmos nuevos y anteriores de Qiskit Terra v0.22 hasta que los algoritmos anteriores queden obsoletos.

No es la intención proporcionar explicaciones detalladas de las primitivas en esta guía de migración. Te sugerimos que leas los recursos correspondientes de la documentación de Qiskit Terra en su lugar.

Usamos qiskit.primitives.Sampler en esta guía como un ejemplo de implementación de Sampler, que sigue a la interfaz qiskit.primitives.BaseSampler. Los usuarios también pueden utilizar otras implementaciones de Sampler como BackendSampler (qiskit-terra), AerSampler (qiskit-aer) y Qiskit Runtime Sampler (qiskit-ibm-runtime).

MinimumEigenOptimizer#

Los algoritmos anteriores existen en qiskit.algorithms.minimum_eigen_solvers y podemos acceder a ellos mediante qiskit.algorithms.*. Por otro lado, los nuevos algoritmos existen en qiskit.algorithms.minimum_eigensolvers y podemos acceder a ellos mediante qiskit.algorithms.minimum_eigensolvers.*. Ten en cuenta que la diferencia es minimum_eigen_solvers (anterior) y minimum_eigensolvers (nuevo).

MinimumEigenOptimizer de Qiskit Optimization puede usar la interfaz qiskit.algorithms.MinimumEigenSolver de los algoritmos anteriores y la interfaz qiskit.algorithms.minimum_eigensolvers.SamplingMinimumEigensolver de los algoritmos nuevos. Ten en cuenta que MinimumEigenOptimizer básicamente no puede manejar qiskit.algorithms.minimum_eigensolvers.MinimumEigensolver de los algoritmos nuevos. Pero hay una excepción. MinimumEigenOptimizer puede manejar algorithms.minimum_eigensolver.NumPyMinimumEigensolver aunque hereda de qiskit.algorithms.minimum_eigensolvers.MinimumEigensolver. Es porque algorithms.minimum_eigensolver.NumPyMinimumEigensolver tiene una extensión que permite a los usuarios acceder a los estados propios.

La siguiente es la tabla correspondiente.

Algoritmo anterior

Algoritmo nuevo

qiskit.algorithms.MinimumEigenSolver

qiskit.algorithms.minimum_eigensolvers.SamplingMinimumEigensolver

qiskit.algorithms.NumPyMinimumEigensolver

qiskit.algorithms.minimum_eigensolver.NumPyMinimumEigensolver

qiskit.algorithms.QAOA

qiskit.algorithms.minimum_eigensolvers.QAOA

qiskit.algorithms.VQE

qiskit.algorithms.minimum_eigensolvers.SamplingVQE

Configuración de un problema

from qiskit_optimization import QuadraticProgram

problem = QuadraticProgram("sample")
problem.binary_var("x")
problem.binary_var("y")
problem.maximize(linear={"x": 1, "y": -2})
print(problem.prettyprint())
Problem name: sample

Maximize
  x - 2*y

Subject to
  No constraints

  Binary variables (2)
    x y

NumPyMinimumEigensolver#

Previamente

from qiskit.algorithms import NumPyMinimumEigensolver

from qiskit_optimization.algorithms import MinimumEigenOptimizer

mes = NumPyMinimumEigensolver()
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Nuevo

from qiskit.algorithms.minimum_eigensolvers import NumPyMinimumEigensolver

from qiskit_optimization.algorithms import MinimumEigenOptimizer

mes = NumPyMinimumEigensolver()
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

QAOA#

Previamente

from qiskit import BasicAer
from qiskit.algorithms import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.utils import QuantumInstance

from qiskit_optimization.algorithms import MinimumEigenOptimizer

backend = BasicAer.get_backend("qasm_simulator")
shots = 1000
qins = QuantumInstance(backend=backend, shots=shots)
mes = QAOA(optimizer=COBYLA(), quantum_instance=qins)
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Nuevo

from qiskit.algorithms.minimum_eigensolvers import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler

from qiskit_optimization.algorithms import MinimumEigenOptimizer

shots = 1000
mes = QAOA(sampler=Sampler(), optimizer=COBYLA())
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

VQE (anterior) → SamplingVQE (nuevo)#

Previamente

from qiskit import BasicAer
from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import COBYLA
from qiskit.circuit.library import RealAmplitudes
from qiskit.utils import QuantumInstance

from qiskit_optimization.algorithms import MinimumEigenOptimizer

backend = BasicAer.get_backend("qasm_simulator")
shots = 1000
qins = QuantumInstance(backend=backend, shots=shots)
mes = VQE(ansatz=RealAmplitudes(), optimizer=COBYLA(), quantum_instance=qins)
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Nuevo

from qiskit.algorithms.minimum_eigensolvers import SamplingVQE
from qiskit.algorithms.optimizers import COBYLA
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Sampler

from qiskit_optimization.algorithms import MinimumEigenOptimizer

mes = SamplingVQE(sampler=Sampler(), ansatz=RealAmplitudes(), optimizer=COBYLA())
meo = MinimumEigenOptimizer(min_eigen_solver=mes)
result = meo.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Se produce un error debido a VQE con Estimator. Puedes usar SamplingVQE con Sampler en su lugar (ver la celda anterior).

from qiskit.algorithms.minimum_eigensolvers import VQE
from qiskit.algorithms.optimizers import COBYLA
from qiskit.circuit.library import RealAmplitudes
from qiskit.primitives import Estimator

from qiskit_optimization.algorithms import MinimumEigenOptimizer

mes = VQE(estimator=Estimator(), ansatz=RealAmplitudes(), optimizer=COBYLA())
try:
    meo = MinimumEigenOptimizer(min_eigen_solver=mes)
except TypeError as ex:
    print(ex)
MinimumEigenOptimizer does not support this VQE. You can use  qiskit.algorithms.minimum_eigensolvers.SamplingVQE instead.

WarmStartQAOAOptimizer#

WarmStartQAOAOptimizer puede usar tanto el qiskit.algorithms.QAOA anterior como el qiskit.algorithms.minimum_eigensolvers.QAOA nuevo de la siguiente manera.

Previamente

from qiskit import BasicAer
from qiskit.algorithms import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.utils import QuantumInstance

from qiskit_optimization.algorithms import WarmStartQAOAOptimizer, SlsqpOptimizer

backend = BasicAer.get_backend("qasm_simulator")
shots = 1000
qins = QuantumInstance(backend=backend, shots=shots)
qaoa = QAOA(optimizer=COBYLA(), quantum_instance=qins)
optimizer = WarmStartQAOAOptimizer(
    pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True, qaoa=qaoa, epsilon=0.25
)
result = optimizer.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Nuevo

from qiskit.algorithms.minimum_eigensolvers import QAOA
from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler

from qiskit_optimization.algorithms import WarmStartQAOAOptimizer, SlsqpOptimizer

qaoa = QAOA(sampler=Sampler(), optimizer=COBYLA())
optimizer = WarmStartQAOAOptimizer(
    pre_solver=SlsqpOptimizer(), relax_for_pre_solver=True, qaoa=qaoa, epsilon=0.25
)
result = optimizer.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

GroverOptimizer#

GroverOptimizer admite tanto QuantumInstance como BaseSampler. Pero los usuarios deben especificar uno de ellos.

Previamente

from qiskit import BasicAer
from qiskit.algorithms.optimizers import COBYLA
from qiskit.utils import QuantumInstance

from qiskit_optimization.algorithms import GroverOptimizer

backend = BasicAer.get_backend("qasm_simulator")
shots = 1000
qins = QuantumInstance(backend=backend, shots=shots)
optimizer = GroverOptimizer(num_value_qubits=3, num_iterations=3, quantum_instance=qins)
result = optimizer.solve(problem)
print(result)
fval=1.0, x=1.0, y=0.0, status=SUCCESS

Nuevo

from qiskit.algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler

from qiskit_optimization.algorithms import GroverOptimizer

optimizer = GroverOptimizer(num_value_qubits=3, num_iterations=3, sampler=Sampler())
result = optimizer.solve(problem)
print(result)
fval=0.0, x=0.0, y=0.0, status=SUCCESS

Se produce un error porque tanto quantum_instance como sampler están configurados. Puedes configurar solo uno de ellos.

from qiskit import BasicAer
from qiskit.algorithms.optimizers import COBYLA
from qiskit.utils import QuantumInstance
from qiskit.primitives import Sampler

from qiskit_optimization.algorithms import GroverOptimizer

backend = BasicAer.get_backend("qasm_simulator")
shots = 1000
qins = QuantumInstance(backend=backend, shots=shots)
try:
    optimizer = GroverOptimizer(
        num_value_qubits=3, num_iterations=3, quantum_instance=qins, sampler=Sampler()
    )
    # raises an error because both quantum_instance and sampler are set.
except ValueError as ex:
    print(ex)
Only one of quantum_instance or sampler can be passed, not both!
import qiskit.tools.jupyter

%qiskit_version_table
%qiskit_copyright

Version Information

Qiskit SoftwareVersion
qiskit-terra0.23.0
qiskit-aer0.11.1
qiskit-optimization0.5.0
qiskit-machine-learning0.6.0
System information
Python version3.9.15
Python compilerClang 14.0.0 (clang-1400.0.29.102)
Python buildmain, Oct 11 2022 22:27:25
OSDarwin
CPUs4
Memory (Gb)16.0
Tue Dec 06 22:08:13 2022 JST

This code is a part of Qiskit

© Copyright IBM 2017, 2022.

This code is licensed under the Apache License, Version 2.0. You may
obtain a copy of this license in the LICENSE.txt file in the root directory
of this source tree or at http://www.apache.org/licenses/LICENSE-2.0.

Any modifications or derivative works of this code must retain this
copyright notice, and modified files need to carry a notice indicating
that they have been altered from the originals.