注釈
このページは、 docs/tutorials/11_using_classical_optimization_solvers_and_models.ipynb によって生成されました。
Qiskit Optimization での古典的最適化ソルバーとモデルの使用#
Qiskit Optimization では、古典的な最適化ソルバー (CPLEXとGroubi) を使用できます。Docplexと Groubipy は、それぞれ CPLEX と Gurobi の Python API です。 Docplex と Gurobipy で最適化モデルをロードして保存し、QuadraticProgram
に CPLEX と Gurobi を適用することができます。
CPLEX ソルバーを使用したい場合は、pip install 'qiskit-optimization[cplex]'
でインストールする必要があります。Qiskit Optimization をインストールすると、Docplex は依存関係として自動的にインストールされます。
Gurobi と Gurobipy を使いたい場合は、pip install 'qiskit-optimization[gurobi]'
でインストールする必要があります。
Note: pipを通してインストールされるこれらのソルバーはフリーバージョンであり、変数の数などのいくつか制限があります。以下のリンクに詳細が掲載されています。
CplexSolver と GurobiSolver#
Qiskit Optimization は、それぞれ CplexSolver
と GurobiSolver
として CPLEX とGurobi の古典的ソルバーをサポートしています。CplexSolver
と GurobiSolver
で QuadraticProgram
を解くことができます。
[1]:
from qiskit_optimization.problems import QuadraticProgram
# define a problem
qp = QuadraticProgram()
qp.binary_var("x")
qp.integer_var(name="y", lowerbound=-1, upperbound=4)
qp.maximize(quadratic={("x", "y"): 1})
qp.linear_constraint({"x": 1, "y": -1}, "<=", 0)
print(qp.prettyprint())
Problem name:
Maximize
x*y
Subject to
Linear constraints (1)
x - y <= 0 'c0'
Integer variables (1)
-1 <= y <= 4
Binary variables (1)
x
[2]:
from qiskit_optimization.algorithms import CplexOptimizer, GurobiOptimizer
cplex_result = CplexOptimizer().solve(qp)
gurobi_result = GurobiOptimizer().solve(qp)
print("cplex")
print(cplex_result.prettyprint())
print()
print("gurobi")
print(gurobi_result.prettyprint())
Restricted license - for non-production use only - expires 2025-11-24
cplex
objective function value: 4.0
variable values: x=1.0, y=4.0
status: SUCCESS
gurobi
objective function value: 4.0
variable values: x=1.0, y=4.0
status: SUCCESS
CPLEX のソルバー・パラメーターは、次のように設定できます。 CPLEX のソルバー・メッセージを表示するには disp=True
を設定します。 CPLEX パラメーターの詳細については、 Parameters of CPLEX を参照してください。
[3]:
result = CplexOptimizer(disp=True, cplex_parameters={"threads": 1, "timelimit": 0.1}).solve(qp)
print(result.prettyprint())
Version identifier: 22.1.1.0 | 2023-02-11 | 22d6266e5
CPXPARAM_Read_DataCheck 1
CPXPARAM_Threads 1
CPXPARAM_TimeLimit 0.10000000000000001
Found incumbent of value 0.000000 after 0.00 sec. (0.00 ticks)
Found incumbent of value 4.000000 after 0.00 sec. (0.00 ticks)
Root node processing (before b&c):
Real time = 0.00 sec. (0.00 ticks)
Sequential b&c:
Real time = 0.00 sec. (0.00 ticks)
------------
Total (root+branch&cut) = 0.00 sec. (0.00 ticks)
objective function value: 4.0
variable values: x=1.0, y=4.0
status: SUCCESS
QAOA でも同様に最適解を得ることができます。
[4]:
from qiskit_optimization.algorithms import MinimumEigenOptimizer
from qiskit_algorithms import QAOA
from qiskit_algorithms.optimizers import COBYLA
from qiskit.primitives import Sampler
meo = MinimumEigenOptimizer(QAOA(sampler=Sampler(), optimizer=COBYLA(maxiter=100)))
result = meo.solve(qp)
print(result.prettyprint())
print("\ndisplay the best 5 solution samples")
for sample in result.samples[:5]:
print(sample)
objective function value: 4.0
variable values: x=1.0, y=4.0
status: SUCCESS
display the best 5 solution samples
SolutionSample(x=array([1., 4.]), fval=4.0, probability=0.024179976472345502, status=<OptimizationResultStatus.SUCCESS: 0>)
SolutionSample(x=array([1., 3.]), fval=3.0, probability=0.05819514104929059, status=<OptimizationResultStatus.SUCCESS: 0>)
SolutionSample(x=array([1., 2.]), fval=2.0, probability=0.16262615426689528, status=<OptimizationResultStatus.SUCCESS: 0>)
SolutionSample(x=array([1., 1.]), fval=1.0, probability=0.1342595428408242, status=<OptimizationResultStatus.SUCCESS: 0>)
SolutionSample(x=array([0., 0.]), fval=0.0, probability=0.048555539627953996, status=<OptimizationResultStatus.SUCCESS: 0>)
QuadraticProgram
と Docplex/Gurobipy のトランスレーター#
Qiskit Optimization は、Docplex モデルと Gurobipy モデルから QuadraticProgram
をロードできます。
まず、Docplex および Gurobipy によって最適化問題を定義します。
[5]:
# docplex model
from docplex.mp.model import Model
docplex_model = Model("docplex")
x = docplex_model.binary_var("x")
y = docplex_model.integer_var(-1, 4, "y")
docplex_model.maximize(x * y)
docplex_model.add_constraint(x <= y)
docplex_model.prettyprint()
// This file has been generated by DOcplex
// model name is: docplex
// single vars section
dvar bool x;
dvar int y;
maximize
[ x*y ];
subject to {
x <= y;
}
[23]:
# gurobi model
from io import StringIO
from tempfile import NamedTemporaryFile
from os import remove
import gurobipy as gp
def gpy_display(mdl):
"""Convenience function to pretty-print a Gurobipy-Model."""
with NamedTemporaryFile(suffix=".lp") as tmp_file:
mdl.write(tmp_file.name)
with open(tmp_file.name, "r") as f:
print(f.read())
gurobipy_model = gp.Model("gurobi")
x = gurobipy_model.addVar(vtype=gp.GRB.BINARY, name="x")
y = gurobipy_model.addVar(vtype=gp.GRB.INTEGER, lb=-1, ub=4, name="y")
gurobipy_model.setObjective(x * y, gp.GRB.MAXIMIZE)
gurobipy_model.addConstr(x - y <= 0)
gurobipy_model.update()
gpy_display(gurobipy_model)
\ Model gurobi
\ LP format - for model browsing. Use MPS format to capture full model detail.
Maximize
[ 2 x * y ] / 2
Subject To
R0: x - y <= 0
Bounds
-1 <= y <= 4
Binaries
x
Generals
y
End
Docplex と Groubipy の両方のモデルから QuadraticProgram
オブジェクトを生成することができます。Docplex と Gurobipy から生成された2つの QuadraticProgram
オブジェクトが同じであることを見てみましょう。
[7]:
from qiskit_optimization.translators import from_docplex_mp, from_gurobipy
qp = from_docplex_mp(docplex_model)
print("QuadraticProgram obtained from docpblex")
print(qp.prettyprint())
print("-------------")
print("QuadraticProgram obtained from gurobipy")
qp2 = from_gurobipy(gurobipy_model)
print(qp2.prettyprint())
QuadraticProgram obtained from docpblex
Problem name: docplex
Maximize
x*y
Subject to
Linear constraints (1)
x - y <= 0 'c0'
Integer variables (1)
-1 <= y <= 4
Binary variables (1)
x
-------------
QuadraticProgram obtained from gurobipy
Problem name: gurobi
Maximize
x*y
Subject to
Linear constraints (1)
x - y <= 0 'R0'
Integer variables (1)
-1 <= y <= 4
Binary variables (1)
x
QuadraticProgram
から Docplex モデルと Gurobipy モデルを生成することもできます。
[25]:
from qiskit_optimization.translators import to_gurobipy, to_docplex_mp
gmod = to_gurobipy(from_docplex_mp(docplex_model))
print("convert docplex to gurobipy via QuadraticProgram")
gpy_display(gmod)
dmod = to_docplex_mp(from_gurobipy(gurobipy_model))
print("\nconvert gurobipy to docplex via QuadraticProgram")
print(dmod.export_as_lp_string())
convert docplex to gurobipy via QuadraticProgram
\ Model docplex
\ LP format - for model browsing. Use MPS format to capture full model detail.
Maximize
[ 2 x * y ] / 2
Subject To
c0: x - y <= 0
Bounds
-1 <= y <= 4
Binaries
x
Generals
y
End
convert gurobipy to docplex via QuadraticProgram
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: gurobi
Maximize
obj: [ 2 x*y ]/2
Subject To
R0: x - y <= 0
Bounds
0 <= x <= 1
-1 <= y <= 4
Binaries
x
Generals
y
End
Docplex のインディケーター制約#
from_docplex_mp
は Docplex モデルを QuadraticProgram
に変換する時、インディケーター制約、すなわち u = 0 => x + y <= z
(u: バイナリー変数) をサポートします。それはインディケーター制約を big-M 定式化で線形制約に変換します。
[9]:
ind_mod = Model("docplex")
x = ind_mod.binary_var("x")
y = ind_mod.integer_var(-1, 2, "y")
z = ind_mod.integer_var(-1, 2, "z")
ind_mod.maximize(3 * x + y - z)
ind_mod.add_indicator(x, y >= z, 1)
print(ind_mod.export_as_lp_string())
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: docplex
Maximize
obj: 3 x + y - z
Subject To
lc1: x = 1 -> y - z >= 0
Bounds
0 <= x <= 1
-1 <= y <= 2
-1 <= z <= 2
Binaries
x
Generals
y z
End
インディケーター制約のあるモデルの解を比較してみましょう
CPLEX を直接 Docplex モデルに適用する (
QuadraticProgram
に変換せずに。CPLEX ソルバーはインディケーター制約をネイティブにサポートします)QAOA を
from_docplex_mp
から得たQuadraticProgram
に適用する
解は同じになります。
[10]:
qp = from_docplex_mp(ind_mod)
result = meo.solve(qp) # apply QAOA to QuadraticProgram
print("QAOA")
print(result.prettyprint())
print("-----\nCPLEX")
print(ind_mod.solve()) # apply CPLEX directly to the Docplex model
QAOA
objective function value: 6.0
variable values: x=1.0, y=2.0, z=-1.0
status: SUCCESS
-----
CPLEX
solution for: docplex
objective: 6
status: OPTIMAL_SOLUTION(2)
x=1
y=2
z=-1
[11]:
import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright
Version Information
Software | Version |
---|---|
qiskit | 0.45.1 |
qiskit_optimization | 0.7.0 |
qiskit_algorithms | 0.2.1 |
System information | |
Python version | 3.10.13 |
Python compiler | GCC 13.2.1 20230728 (Red Hat 13.2.1-1) |
Python build | main, Aug 28 2023 00:00:00 |
OS | Linux |
CPUs | 12 |
Memory (Gb) | 31.056411743164062 |
Wed Dec 06 10:30:30 2023 CET |
This code is a part of Qiskit
© Copyright IBM 2017, 2023.
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.