制約付き量子オプティマイザー - AqariosによるQiskit関数
APIリファレンスを参照してください
Qiskit Functions これらは、 IBM Quantum® Premium Plan、Flex Plan、および On-Prem ( IBM Quantum Platform API経由)プランのユーザーのみが利用できる実験的な機能です。 これらはプレビュー版であり、変更される可能性があります。
概要
Aqarios社の「Constrained Quantum Optimizer」を使用すれば、手動による再定式化や回路マッピングを行うことなく、 IBM® の量子ハードウェア上で制約付き二値最適化問題を解くことができます。 問題をLPファイル、MPSファイル、または Lunaモデルとしてご提供ください。 この関数は、再定式化、回路合成、トランスパイル、およびハードウェア実行を自動的に処理します。 このソルバーは、量子近似最適化アルゴリズム(QAOA)の制約ネイティブ拡張である FlexQAOA アルゴリズムの反復的ウォームスタート法 [1] を採用している。
このオプティマイザーは、制約付き二値問題を対象としています。 特に、ワンホット制約やセットパッキング制約は、XY-ミキサーを使用することでネイティブに適用することができます。 その他の制約の種類は、自動的にペナルティ項として再定式化されます。
この関数は離散的な問題のみを解きます。 すべての決定変数は、量子ビットにエンコードできるよう、二値であるか、あるいは明示的な下限と上限を持つ整数でなければならない。 連続(実数値)変数はサポートされていません。これらを含むモデルは、エラーコード とともに拒否されます 4710。
説明
パフォーマンスは、問題のインスタンスと、それに続く処理ステップの両方に左右される場合があります。 場合によっては、古典的なサンプルと量子生成されたサンプルは、同等の後処理を施した後、同等の最終的な解の品質を達成することがある。 したがって、評価にあたっては、最適化ワークフロー全体を考慮すべきである。
制約付き量子オプティマイザーは、反復型ウォームスタートXYミキサーQAOA(IWS-QAOA) [1] を実装している。 このアルゴリズムは、量子ハードウェア上で固定角度のQAOA回路を実行し、前回の反復における測定結果を用いて、各回路の初期のウォームスタート確率を更新する。 変分パラメータの学習は必要なく、代わりに固定の線形ランプパラメータ化が採用される。
XYミキサーを用いてワンホット制約を適用することで、制約付き問題の解の質を飛躍的に向上させることができます。これは、探索空間が実質的により小さな実行可能な部分空間に縮小されるためであり、かつ、最適化ランドスケープにペナルティ項による追加の複雑さが生じないからです。
ワークフロー
この関数のワークフローは以下の通りです:
- 前処理 :回路合成の前に、最適化アルゴリズムは入力問題の制約構造を分析します:
- グラフの前処理: 問題に応じて、変数間の関係を辺で表すグラフとして分析を行う。 このグラフ解析により、前処理に関する2つの問題の改善が可能となります。 まず、クリーク結合を用いることで、個々の制約を1つの大きな制約に集約することができ、その結果、それらは単一のXYミキサーによって表現されるようになる。 第二に、隣接する変数が1つしかない変数は決定論的に固定できるため、問題の規模と複雑さを軽減できる。
- 制約の解決: プリプロセッサは各制約を個別に処理します。制約がワンホット制約である場合、XYミキサーを用いてその制約を適用することができます。 セットパッキング制約である場合、まずワンホット制約に変換されます。 等式制約は二次ペナルティによって、不等式制約は不均衡ペナルティによって処理される。
- ペナルティの導出: ワンホット等式制約として表現できない制約は、ペナルティ項に変換される。 オプティマイザは、問題の構造からペナルティの強さを自動的に導出します。
- 反復的ウォームスタート :オプティマイザは、複数のウォームスタートチェーンを並列に実行する。 各チェーンは、変数の割り当てに関する確率分布を保持しており、これはQAOA回路の初期確率(ウォームスタート状態)として用いられる。 各反復において、チェーンは量子回路からサンプルを抽出し、古典的な事後処理を適用し、サンプルの出現状況に基づいてその分布を更新する。 反復処理を通じて、これにより、変分最適化ループを用いることなく、高品質な解の探索に焦点を絞ることができます。
チェーン数(num_parallel)、チェーンごとの総ショット予算(total_shots)、およびQAOAの反復回数(reps)は、解の品質と実行時間のバランスを調整するための主要な制御パラメータである。
ベンチマーク
以下のベンチマーク結果から、Qiskitの「Constrained Quantum Optimizer」関数は、100をはるかに超える二値変数を持つ制約付き最適化問題に対して、高品質で実現可能な解を見出すことができることが示されています。 精度は、求まった目的関数値と既知の最適値との比率である。 実行時間は、関数の呼び出しから結果の返却までの実時間です。 QPU使用量は、課金対象となる量子コンピューティング時間です。
2つの問題が検討された。すなわち、「 最大独立集合 (MIS)」問題と、「最大 -カット」問題である。後者は、よく知られた「 MaxCut 」問題を2つ以上のカテゴリに拡張したものである。 Max- -Cutは、グラフ着色決定問題に相当する最適化問題でもあります(すべての辺が切断されたとき、そのグラフは -着色可能となります)。
問題点 | 変数 | 制約 | 量子ビット | 正確性 | 実現可能性 | 合計実行時間(秒) | QPU使用時間(秒) | シュート総数 |
|---|---|---|---|---|---|---|---|---|
| MIS es60fst02 | 186 | 280 | 124 | 100.0% | はい | 940.2 | 147.0 | 25.0k |
| MIS sloane_2dc_128 | 128 | 5173 | 74 | 100.0% | はい | 347.6 | 106.0 | 12.5k |
| Max-3-Cut 空手部 | 99 | 33 | 99 | 98.7% | はい | 279.5 | 166.0 | 25.0k |
| Max-4-Cut 空手部 | 132 | 33 | 132 | 100.0% | はい | 258.3 | 200.0 | 25.0k |
ベンチマークの注意事項
- 上記の結果は、Heron
ibm_marrakeshr2 プロセッサ上で、デフォルトのオプションを設定し、を有効use_sessionにした状態で得られたものです。 例えばsloane_2dc_128、…が使用されましたtotal_shots=12500。 - MISのインスタンスにおける量子ビット数の減少(変数数128および186に対して74および124)は、前処理における変数の固定を反映している。
- MISの問題インスタンスは、 Quantum Optimization Benchmarking Libraryから採用されている。- Max- -Cut問題のインスタンスは、色数が5である「 Zachary Karate Club 」グラフである。
使用を開始する
このガイドでは、Constrained Quantum Optimizer の関数を読み込み、簡単な問題を解く方法を示すことで、その基本的な使い方を解説します。 より詳細なチュートリアルについては、「 Aqarios制約付き量子最適化ツールを使用した最大独立集合の探索」 をご覧ください。
IBM Quantum のAPIキーとインスタンス CRN を使用して認証を行い、カタログから関数を読み込んでください。
以下のコードは、認証情報を保存済みであることを前提としています。 設定を行うには、「 IBM Cloud アカウントの認証情報を保存する 」の手順に従ってください。
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
# Verify that you have access to the function
catalog.list()Output:
[QiskitFunction(aqarios/constrained-quantum-optimizer)]
# Load the function
optimizer = catalog.load("aqarios/constrained-quantum-optimizer")# Check the list of backends you have access to
catalog.backends()Output:
[<IBMBackend('ibm_pittsburgh')>,
<IBMBackend('ibm_boston')>,
<IBMBackend('ibm_phoenix')>,
<IBMBackend('ibm_fez')>,
<IBMBackend('ibm_miami')>,
<IBMBackend('ibm_marrakesh')>,
<IBMBackend('ibm_kingston')>]
# Select the backend you want to use
backend = catalog.backend("ibm_phoenix")例 1:単純な制約付き問題
最初の例では、オペレーションズ・リサーチで一般的に用いられる最適化問題の仕様であるLPファイルを用いて、この関数をどのように使用するかを示しています。 5つの二値変数からなる以下の任意の最適化問題 を、2つの制約条件の下で定式化してください:
1. 問題の定式化
数学式を、以下のLP文字列形式で直接記述してください:
lp_str = """\\Problem name: Example
Minimize
obj: [ 2 x_1 x_2 + 4 x_2 x_3 - 2 x_3 x_4 - 4 x_4 x_5 - 4 x_1 x_3 - 8 x_2 x_5 ] / 2
Subject To
c1: x_1 + x_2 + x_3 <= 1
c2: x_3 - x_4 + x_5 = 0
Binaries
x_1 x_2 x_3 x_4 x_5
End
"""なお、 は LP の標準規格において、二次目的関数に必須の表記である [...] / 2 ことに留意されたい。
2. オプティマイザーを実行する
オプティマイザーを使って問題を解決してください。
# Set up low-resource options for the simple problem
options = {"total_shots": 2000, "num_parallel": 5, "use_session": True}
# Dispatch the job
job_1 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)
print(f"Job ID: {job_1.job_id}")Output:
Job ID: 2e06a3a8-7c29-4c76-94d7-194293363f4a
# Monitor the job status
job_1.status()Output:
'RUNNING: WAITING_FOR_QPU'
3. 結果を取得する
変数名とそれに対応する代入値を関連付けるという解決策は、結果によって示されています。
result = job_1.result()
resultOutput:
{'solutions': [{'x_1': 0, 'x_2': 1, 'x_3': 0, 'x_4': 1, 'x_5': 1}],
'solution_bitstrings': ['01011'],
'raw_energy': -6.0,
'objective_value': -6.0,
'feasible': True,
'metadata': {'resource_usage': {'RUNNING: MAPPING': {'CPU': 5.405},
'RUNNING: OPTIMIZING_FOR_HARDWARE': {'CPU': 9.902},
'RUNNING: WAITING_FOR_QPU': {'CPU': 25.456},
'RUNNING: EXECUTING_QPU': {'CPU': 25.202},
'RUNNING: POST_PROCESSING': {'CPU': 6.481}},
'circuit_metrics': {'before_transpilation': {'num_qubits': 6,
'gate_count': 42,
'depth': 15,
'two_qubit_gate_count': 12,
'two_qubit_gate_depth': 7,
'operations': {'rz': 12,
'p': 8,
'ry': 7,
'rzz': 4,
'cx': 3,
'xx_plus_yy': 3,
'global_phase': 2,
'cry': 2,
'x': 1}},
'after_transpilation': {'num_qubits': 6,
'gate_count': 254,
'depth': 100,
'two_qubit_gate_count': 48,
'two_qubit_gate_depth': 33,
'operations': {'rz': 78, 'sx': 122, 'cz': 48, 'measure': 6, 'x': 0}}},
'solver_info': {'variable_mapping': {'x_1': 0,
'x_2': 1,
'x_3': 2,
'x_4': 3,
'x_5': 4}}}}
リターン辞書のこのフィールド solutions には、見つかったすべての縮退した最適解が、各変数名とその代入値を対応付ける辞書として格納されています。 これらの解は、ビット文字列としても返されます。 solution_bitstrings; を使用すると、ビット文字列のどの文字位置がどの変数に対応しているかがわかります metadata.solver_info.variable_mapping 。 ソリューションデータに加え、 objective_value、フラグ feasible 、および追加のデータ metadata が提供されています。
例 2:最大独立集合
最大独立集合(MIS)問題とは、グラフ内の頂点の最大の部分集合で、その部分集合内のどの2つの頂点も辺を共有しないものを求める問題である。 この例では、12ノードの正則グラフ上でMISを解きます。 この問題に関する詳細や、より大規模な例については、 チュートリアルを参照してください。
この問題は、 qiskit-addon-opt-mapper を使用して構築されています。 必要に応じて、必要なパッケージをインストールしてください:
# %pip install networkx qiskit-addon-opt-mapperステップ1:問題を明確にする
ランダムな3-正則グラフを構築し、MIS最適化問題を定式化する。 各グラフのノードは二値変数となり、各辺は、その両端点のうち最大1つだけが選択されることを保証する制約を導入する。
import networkx as nx
from qiskit_addon_opt_mapper.applications import IndependentSet
from qiskit_addon_opt_mapper.translators import to_docplex_mp
# 12-node random 3-regular graph
G = nx.random_regular_graph(3, 12, seed=7)
# Build MIS problem and export as LP string
mis = IndependentSet(G)
mis_problem = mis.to_optimization_problem()
lp_str = to_docplex_mp(mis_problem).export_as_lp_string()
print(lp_str)Output:
\ This file has been generated by DOcplex
\ ENCODING=ISO-8859-1
\Problem name: Independent set
Maximize
obj: x_0 + x_1 + x_2 + x_3 + x_4 + x_5 + x_6 + x_7 + x_8 + x_9 + x_10 + x_11
Subject To
c0: x_0 + x_4 <= 1
c1: x_0 + x_9 <= 1
c2: x_0 + x_8 <= 1
c3: x_1 + x_2 <= 1
c4: x_1 + x_7 <= 1
c5: x_1 + x_3 <= 1
c6: x_2 + x_4 <= 1
c7: x_2 + x_11 <= 1
c8: x_3 + x_10 <= 1
c9: x_3 + x_11 <= 1
c10: x_4 + x_5 <= 1
c11: x_5 + x_10 <= 1
c12: x_5 + x_6 <= 1
c13: x_6 + x_8 <= 1
c14: x_6 + x_7 <= 1
c15: x_7 + x_9 <= 1
c16: x_8 + x_11 <= 1
c17: x_9 + x_10 <= 1
Bounds
0 <= x_0 <= 1
0 <= x_1 <= 1
0 <= x_2 <= 1
0 <= x_3 <= 1
0 <= x_4 <= 1
0 <= x_5 <= 1
0 <= x_6 <= 1
0 <= x_7 <= 1
0 <= x_8 <= 1
0 <= x_9 <= 1
0 <= x_10 <= 1
0 <= x_11 <= 1
Binaries
x_0 x_1 x_2 x_3 x_4 x_5 x_6 x_7 x_8 x_9 x_10 x_11
End
ステップ 2:オプティマイザーを実行する
オプティマイザーを使って問題を解決してください。
options = {"total_shots": 2000, "use_session": True}
# Dispatch the job
job_2 = optimizer.run(
problem=lp_str, backend_name=backend.name, options=options
)
print(f"Job ID: {job_2.job_id}")Output:
Job ID: f041431c-b42e-4627-afe5-522fea61faf6
# Monitor the job status
job_2.status()Output:
'QUEUED'
ステップ3:結果の取得と解釈
最後に、解を求め、その正しさを検証します。
result = job_2.result()
print(f"Feasible: {result['feasible']}")
print(f"Independent set size: {int(result['objective_value'])}")
# Extract the selected nodes
solution = result["solutions"][0]
independent_set = [
int(k.split("_")[1]) for k, v in solution.items() if v == 1
]
print(f"Selected nodes: {sorted(independent_set)}")
# Verify no two selected nodes share an edge
conflicts = [
(u, v)
for u, v in G.edges()
if u in independent_set and v in independent_set
]
print(f"Edge conflicts: {conflicts}")Output:
Feasible: True
Independent set size: 5
Selected nodes: [1, 4, 6, 9, 11]
Edge conflicts: []
例 3:グラフの 3 色塗り( Max-3-Cut )
「最大- -Cut問題」とは、グラフの頂点を つのグループに分割し、端点が異なるグループに属する辺の数を最大化する問題である。 の場合、これは、異色辺の数を最大化する 3 色着色を見つけることと同等である。
形式的には、各ノード を、二値変数 (色 )を持つ のグループのいずれかに割り当てます。各ノードに対するワンホット制約 により、一意な割り当てが保証されます。 この目的関数は、グループ間のエッジの数を最大化する:
ワンホット制約は、最適化ツールがネイティブに処理するXYミキサーに最適です。
この例では、 ザカリー空手クラブのグラフ (34ノード、78エッジ)を使用し、 Luna Model を用いてモデルを構築します。 必要に応じて、必要なパッケージをインストールしてください:
# %pip install networkx matplotlib luna-modelステップ1:問題を明確にする
まず、パッケージ luna-model を使用して二値変数を生成します。 次に、目的関数を定義し、制約条件をモデルに追加します。
import networkx as nx
from luna_model import Model, quicksum
k = 3
G = nx.karate_club_graph()
# Instantiate the Model object
model = Model(name="Max-3-Cut")
# Add binary variables
x = model.add_variables("x", shape=(G.number_of_nodes(), k))
# Add the objective by using the numpy dot abstraction
model.objective = quicksum(x[i].dot(x[j]) for i, j in G.edges)
# Bulk-add the one-hot constraints
model.add_constraints(x.sum(axis=1) == 1)
# Encode the model to send via API
model_enc = model.encode_b64()ステップ 2:オプティマイザーを実行する
オプティマイザーを使って問題を解決してください。
options = {"use_session": True}
# Dispatch the job
job_3 = optimizer.run(
problem=model_enc, backend_name=backend.name, options=options
)
print(f"Job ID: {job_3.job_id}")Output:
Job ID: df911d83-9df7-44a1-bfad-5d66e08676c3
# Monitor the job status
job_3.status()Output:
'RUNNING: WAITING_FOR_QPU'
ステップ3:結果の取得と可視化
結果を取得し、可視化します。
result = job_3.result()
solution = result["solutions"][0]
# Map each node to its assigned color group
node_group = {}
for i in G.nodes:
for c in range(k):
if solution[f"x{i},{c}"] == 1:
node_group[i] = c
print(f"Feasible: {result['feasible']}")
print(f"Violations: {int(result['objective_value'])}")
# Visualize the partition
colors = ["tab:blue", "tab:orange", "tab:green"]
node_colors = [colors[node_group[i]] for i in G.nodes()]
nx.draw(G, nx.kamada_kawai_layout(G), node_color=node_colors, node_size=200)Output:
Feasible: True
Violations: 4
変更ログ
[0.4.0] - 2026年9月22日
最新の変更
- 入力パラメータの名前を
modelに変更しましたproblem。 - 出力フィールドの名前を
obj_valueに変更しましたobjective_value。 - オプション
postprocessingを に置き換えましたpostprocessing_level。これは、文字列の[0, 3]代わりに 範囲の整数を受け取ります。 以前の値は、"off"->0、"weak"->1、"medium"->2、および"strong"-> に対応しており3、デフォルト値は のまま変更されていません3。 - 再編成されました
metadata.circuit_metrics。 現在ではnum_qubits、平均化されたゲート数の単一のフラットな辞書ではなくafter_transpilation、before_transpilationとについて、gate_count、depth、two_qubit_gate_count、two_qubit_gate_depth、、を個operations別に報告するようになっている。 このフィールドは、前処理の段階で問題が解決され、回路の実行が行われなかったNone場合(エラーコード4712)に設定されます。
特徴
- 実行ごとに回路合成と配線の再現性を確保するためのオプション
seed_transpilerを追加しました。 - この関数が送信するすべての Qiskit Runtime ジョブに、独自のタグを付与するオプション
job_tagsを追加しました。 - 出力フィールドを追加しました
solution_bitstrings。これは、と同じ解をビット列形式solutionsで返します。 - 各変数名を
metadata.solver_info.variable_mapping、のエントリ内でのその文字位置にマッピングするを追加しましたsolution_bitstrings。
資料
- 連続(実数値)変数はサポートされていないこと、および整数変数には明示的な境界を指定する必要があることが記載されています。 このようなモデルでは、エラーコード が表示され、処理が失敗します
4710。
サポートの利用
ご質問や問題がある場合は、ジョブIDを明記の上、 [email protected] までご連絡ください。
次のステップ
- Aqarios社の「Constrained Quantum Optimizer」へのアクセス権を申請してください。
- パラメータおよび出力の詳細については、 APIリファレンスをご覧ください。
- 「 Aqarios制約付き量子オプティマイザーを用いた最大独立集合の探索 」チュートリアルを試して、実際のQOBLIBベンチマーク事例について詳しく学びましょう。
- 論文「 反復ウォームスタートXYミキサーを用いた制約付き量子最適化」 を参照してください。
参照
- Bucher ら (2026)、 *反復ウォームスタートXYミキサーを用いた制約付き量子最適化 *10.1088/1367-2630/ae8ea2