Skip to main content
IBM Quantum Platform

制約付き量子オプティマイザー - AqariosによるQiskit関数

APIリファレンスを参照してください

Note

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ミキサーを用いてワンホット制約を適用することで、制約付き問題の解の質を飛躍的に向上させることができます。これは、探索空間が実質的により小さな実行可能な部分空間に縮小されるためであり、かつ、最適化ランドスケープにペナルティ項による追加の複雑さが生じないからです。

ワークフロー

この関数のワークフローは以下の通りです:

  1. 前処理 :回路合成の前に、最適化アルゴリズムは入力問題の制約構造を分析します:
    • グラフの前処理: 問題に応じて、変数間の関係を辺で表すグラフとして分析を行う。 このグラフ解析により、前処理に関する2つの問題の改善が可能となります。 まず、クリーク結合を用いることで、個々の制約を1つの大きな制約に集約することができ、その結果、それらは単一のXYミキサーによって表現されるようになる。 第二に、隣接する変数が1つしかない変数は決定論的に固定できるため、問題の規模と複雑さを軽減できる。
    • 制約の解決: プリプロセッサは各制約を個別に処理します。制約がワンホット制約である場合、XYミキサーを用いてその制約を適用することができます。 セットパッキング制約である場合、まずワンホット制約に変換されます。 等式制約は二次ペナルティによって、不等式制約は不均衡ペナルティによって処理される。
    • ペナルティの導出: ワンホット等式制約として表現できない制約は、ペナルティ項に変換される。 オプティマイザは、問題の構造からペナルティの強さを自動的に導出します。
  2. 反復的ウォームスタート :オプティマイザは、複数のウォームスタートチェーンを並列に実行する。 各チェーンは、変数の割り当てに関する確率分布を保持しており、これはQAOA回路の初期確率(ウォームスタート状態)として用いられる。 各反復において、チェーンは量子回路からサンプルを抽出し、古典的な事後処理を適用し、サンプルの出現状況に基づいてその分布を更新する。 反復処理を通じて、これにより、変分最適化ループを用いることなく、高品質な解の探索に焦点を絞ることができます。

チェーン数(num_parallel)、チェーンごとの総ショット予算(total_shots)、およびQAOAの反復回数(reps)は、解の品質と実行時間のバランスを調整するための主要な制御パラメータである。

制約付き量子オプティマイザーのワークフロー図

ベンチマーク

以下のベンチマーク結果から、Qiskitの「Constrained Quantum Optimizer」関数は、100をはるかに超える二値変数を持つ制約付き最適化問題に対して、高品質で実現可能な解を見出すことができることが示されています。 精度は、求まった目的関数値と既知の最適値との比率である。 実行時間は、関数の呼び出しから結果の返却までの実時間です。 QPU使用量は、課金対象となる量子コンピューティング時間です。

2つの問題が検討された。すなわち、「 最大独立集合 (MIS)」問題と、「最大 kk -カット」問題である。後者は、よく知られた「 MaxCut 」問題を2つ以上のカテゴリに拡張したものである。 Max- kk -Cutは、グラフ着色決定問題に相当する最適化問題でもあります(すべての辺が切断されたとき、そのグラフは kk -着色可能となります)。

問題点
変数
制約
量子ビット
正確性
実現可能性
合計実行時間(秒)
QPU使用時間(秒)
シュート総数
MIS es60fst02186280124100.0%はい940.2147.025.0k
MIS sloane_2dc_128128517374100.0%はい347.6106.012.5k
Max-3-Cut 空手部99339998.7%はい279.5166.025.0k
Max-4-Cut 空手部13233132100.0%はい258.3200.025.0k

ベンチマークの注意事項

  • 上記の結果は、Heron ibm_marrakesh r2 プロセッサ上で、デフォルトのオプションを設定し、を有効 use_session にした状態で得られたものです。 例えば sloane_2dc_128 、…が使用されました total_shots=12500 。
  • MISのインスタンスにおける量子ビット数の減少(変数数128および186に対して74および124)は、前処理における変数の固定を反映している。
  • MISの問題インスタンスは、 Quantum Optimization Benchmarking Libraryから採用されている。- Max- kk -Cut問題のインスタンスは、色数が5である「 Zachary Karate Club 」グラフである。

使用を開始する

このガイドでは、Constrained Quantum Optimizer の関数を読み込み、簡単な問題を解く方法を示すことで、その基本的な使い方を解説します。 より詳細なチュートリアルについては、「 Aqarios制約付き量子最適化ツールを使用した最大独立集合の探索」 をご覧ください。

IBM Quantum のAPIキーとインスタンス CRN を使用して認証を行い、カタログから関数を読み込んでください。

Note

以下のコードは、認証情報を保存済みであることを前提としています。 設定を行うには、「 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つの二値変数からなる以下の任意の最適化問題 xi∈{0,1}x_i \in \{0,1\} を、2つの制約条件の下で定式化してください:

min⁡x1x2+2x2x3−x3x4−2x4x5−2x1x3−4x2x5s.t.x1+x2+x3≤1x3−x4+x5=0 \min x_1 x_2 + 2 x_2 x_3 - x_3 x_4 - 2 x_4 x_5 - 2 x_1 x_3 - 4 x_2 x_5 \\ \text{s.t.}\quad x_1 + x_2 + x_3 \leq 1 \\ \quad x_3 - x_4 + x_5 = 0

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()

result

Output:

{'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 )

「最大- kk -Cut問題」とは、グラフの頂点を kk つのグループに分割し、端点が異なるグループに属する辺の数を最大化する問題である。 k=3k = 3 の場合、これは、異色辺の数を最大化する 3 色着色を見つけることと同等である。

形式的には、各ノード i∈Vi \in V を、二値変数 xi,cx_{i,c} (色 c∈{1,…,k}c \in \{1, \ldots, k\} )を持つ kk のグループのいずれかに割り当てます。各ノードに対するワンホット制約 ∑cxi,c=1\sum_c x_{i,c} = 1 により、一意な割り当てが保証されます。 この目的関数は、グループ間のエッジの数を最大化する:

min⁡∑(u,v)∈E∑cxu,c xv,cs.t.∑cxi,c=1∀i∈V\min \sum_{(u,v) \in E} \sum_c x_{u,c} \, x_{v,c}\\ \text{s.t.} \sum_{c} x_{i,c} = 1 \quad \forall i \in V

ワンホット制約は、最適化ツールがネイティブに処理する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
Output of the previous code cell

変更ログ

[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] までご連絡ください。


次のステップ

推奨事項

参照

  1. Bucher ら (2026)、 *反復ウォームスタートXYミキサーを用いた制約付き量子最適化 *10.1088/1367-2630/ae8ea2
このページは役に立ちましたか?
バグや誤字の報告、またはコンテンツの要求はGitHubで行ってください。