Optimization Solver: Q-CTRL Fire OpalによるQiskit Function
APIリファレンスを参照してください
Qiskit Functionsは、IBM Quantum® Premium Plan、Flex Plan、およびOn-Prem(IBM Quantum Platform API経由)Planのユーザーのみが利用できる実験的な機能です。プレビューリリースの状態にあり、変更される可能性があります。
パッケージのバージョン
このページのコードは以下の要件を使用して開発されました。 これらのバージョン以降の使用を推奨します。
qiskit-ibm-runtime~=0.46.1
sympy~=1.14.0
概要
Fire Opal Optimization Solverを使用すると、量子の専門知識を必要とせずに、量子ハードウェア上でユーティリティスケールの最適化問題を解くことができます。高レベルの問題定義を入力するだけで、Solverが残りの処理を行います。ワークフロー全体はノイズを考慮した設計になっており、内部的にFire OpalのPerformance Managementを活用しています。Solverは、最大規模のIBM® QPU上でもフルデバイススケールで、古典的に困難な問題に対して一貫して正確な解を提供します。
Solverは柔軟性があり、目的関数または任意のグラフとして定義された組み合わせ最適化問題を解くために使用できます。問題をデバイストポロジーにマッピングする必要はありません。制約をペナルティ項として定式化できる場合、制約なしの問題と制約付きの問題の両方を解くことができます。このガイドに含まれる例では、異なるSolver入力タイプを使用して、制約なしおよび制約付きのユーティリティスケール最適化問題を解く方法を示しています。最初の例は156ノード、3-Regularグラフで定義されたMax-Cut問題に関するものであり、2番目の例はコスト関数で定義された50ノードのMinimum Vertex Cover問題に取り組んでいます。
Optimization Solverへのアクセスを取得するには、Q-CTRLにお問い合わせください。
機能の説明
Solverは、ハードウェアレベルでのエラー抑制から効率的な問題マッピングおよびクローズドループの古典的最適化まで、アルゴリズム全体を完全に最適化および自動化します。Solverのパイプラインは裏側で各ステージのエラーを削減し、意味のあるスケールアップに必要な強化されたパフォーマンスを実現しています。基礎となるワークフローはQuantum Approximate Optimization Algorithm(QAOA)から着想を得ており、ハイブリッド量子古典アルゴリズムです。Optimization Solverワークフロー全体の詳細な概要については、公開されている論文を参照してください。
Optimization Solverで一般的な問題を解くには:
- 問題を目的関数、グラフ、または
SparsePauliOpスピンチェーンとして定義します。 - Qiskit Functions Catalogを通じて機能に接続します。
- Solverで問題を実行し、結果を取得します。
受け付ける問題形式
- 目的関数の多項式表現。理想的にはPythonで既存のSymPy Polyオブジェクトを使用して作成し、sympy.sreprを使用して文字列にフォーマットします。
- 特定の問題タイプのグラフ表現。グラフはPythonのnetworkxライブラリを使用して作成する必要があります。その後、networkx関数
[nx.readwrite.json_graph.adjacency_data](http://nx.readwrite.json_graph.adjacency_data.)を使用して文字列に変換します。 - 特定の問題のスピンチェーン表現。スピンチェーンは
SparsePauliOpオブジェクトとして表現する必要があります。詳細についてはドキュメントを参照してください。
この機能が現在サポートしていないバックエンドを使用したい場合は、Q-CTRLにお問い合わせしてサポートを追加してください。
ベンチマーク
公開されているベンチマーク結果は、Solverが120量子ビットを超える問題を正常に解き、量子アニーリングやトラップイオンデバイスで以前に公開された結果をも上回ることを示しています。以下のベンチマーク指標は、いくつかの例に基づいた問題タイプの精度とスケーリングの大まかな目安を提供します。実際の指標は、目的関数の項数(密度)とその局所性、変数の数、多項式の次数などのさまざまな問題の特性によって異なる場合があります。
「量子ビット数」は厳密な制限ではなく、非常に一貫した解の精度が期待できる大まかな閾値を表しています。これらの制限を超えた大きな問題サイズも正常に解かれており、これらの制限を超えてテストすることをお勧めします。
任意の量子ビット接続性はすべての問題タイプでサポートされています。
| 問題タイプ | 量子ビット数 | 例 | 精度 | 合計時間 (s) | Runtime使用量 (s) | イテレーション数 |
|---|---|---|---|---|---|---|
| 疎に連結された二次問題 | 156 | 3-regular Max-Cut | 100% | 1764 | 293 | 16 |
| 高次バイナリ最適化 | 156 | Ising spin-glass model | 100% | 1461 | 272 | 16 |
| 密に連結された二次問題 | 50 | 完全連結Max-Cut | 100% | 1758 | 268 | 12 |
| ペナルティ項を持つ制約付き問題 | 50 | エッジ密度8%の重み付きMinimum Vertex Cover | 100% | 1074 | 215 | 10 |
はじめに
まず、IBM Quantum APIキーを使用して認証します。次に、以下のようにQiskit Functionを選択します。(このスニペットは、すでにアカウントをローカル環境に保存していることを前提としています。)
# Added by doQumentation — required packages for this notebook
!pip install -q networkx numpy qiskit-ibm-catalog qiskit-ibm-runtime sympy
from qiskit_ibm_catalog import QiskitFunctionsCatalog
catalog = QiskitFunctionsCatalog(channel="ibm_quantum_platform")
# Access Function
solver = catalog.load("q-ctrl/optimization-solver")
例:制約なし最適化
最大カット(Max-Cut)問題を実行します。以下の例は156ノード、3-regularの非重み付きグラフMax-Cut問題におけるSolverの能力を示していますが、重み付きグラフ問題も解くことができます。
qiskit-ibm-catalogに加え、この例を実行するにはnetworkxとnumpyパッケージも使用します。IPythonカーネルを使用してノートブックでこの例を実行する場合は、次のセルのコメントを解除してこれらのパッケージをインストールできます。
# %pip install networkx numpy
1. 問題を定義する
グラフ問題を定義し、problem_type='maxcut'を指定することでMax-Cut問題を実行できます。
import networkx as nx
import numpy as np
# Generate a random graph with 156 nodes
maxcut_graph = nx.random_regular_graph(d=3, n=156, seed=8)
# Optionally, visualize the graph
nx.draw_networkx(
maxcut_graph, nx.kamada_kawai_layout(maxcut_graph), node_size=100
)
Solverは問題定義の入力として文字列を受け付けます。
# Convert graph to string
problem_as_str = nx.readwrite.json_graph.adjacency_data(maxcut_graph)
2. 問題を実行する
グラフベースの入力方法を使用する場合は、問題タイプを指定してください。
# This cell is hidden from users
from qiskit_ibm_runtime import QiskitRuntimeService
service = QiskitRuntimeService()
backend_name = service.least_busy(n_qubits=156).name
# Solve the problem
maxcut_job = solver.run(
problem=problem_as_str,
problem_type="maxcut",
backend_name=backend_name, # E.g. "ibm_fez"
)
Qiskit Functionワークロードのステータスを確認するか、以下のように結果を返します:
# Get job status
print(maxcut_job.status())
QUEUED
3. 結果を取得する
結果辞書から最適なカット値を取得します。
variables_to_bitstring_index_mapサブ辞書が含まれており、順序を確認するのに役立ちます。# Poll for results
maxcut_result = maxcut_job.result()
# Take the absolute value of the solution since the cost function is minimized
qctrl_maxcut = abs(maxcut_result["solution_bitstring_cost"])
# Print the optimal cut value found by the Optimization Solver
print(f"Optimal cut value: {qctrl_maxcut}")
Optimal cut value: 210.0
グラフが密に連結されていない場合、PuLPなどのオープンソースソルバーを使用して問題を古典的に解くことで結果の精度を検証できます。高密度の問題では、解を検証するために高度な古典的ソルバーが必要になる場合があります。
例:制約付き最適化
上記のMax-Cut例は、一般的な二次制約なしバイナリ最適化問題です。Q-CTRLのOptimization Solverは、制約付き最適化を含むさまざまな問題タイプに使用できます。制約をペナルティ項としてモデル化した多項式として表された問題定義を入力することで、任意の問題タイプを解くことができます。
以下の例では、制約付き最適化問題であるminimum vertex cover(MVC)のコスト関数を構築する方法を示します。
qiskit-ibm-catalogおよびqiskitパッケージに加えて、この例を実行するにはnumpy、networkx、およびsympyパッケージも使用します。IPythonカーネルを使用してノートブックでこの例を実行する場合は、次のセルのコメントを解除してこれらのパッケージをインストールできます。
# %pip install numpy networkx sympy
1. 問題を定義する
ランダムに重み付けされたノードを持つグラフを生成して、ランダムなMVC問題を定義します。
import networkx as nx
from sympy import symbols, Poly, srepr
# To change the weights, change the seed to any integer.
rng_seed = 18
_rng = np.random.default_rng(rng_seed)
node_count = 50
edge_probability = 0.08
mvc_graph = nx.erdos_renyi_graph(
node_count, edge_probability, seed=rng_seed, directed=False
)
# add node weights
for i in mvc_graph.nodes:
mvc_graph.add_node(i, weight=_rng.random())
# Optionally, visualize the graph
nx.draw_networkx(mvc_graph, nx.kamada_kawai_layout(mvc_graph), node_size=200)
重み付きMVCの標準的な最適化モデルは以下のように定式化できます。まず、エッジがサブセット内の頂点に接続されていない場合、ペナルティを追加する必要があります。したがって、頂点がカバー(つまりサブセット)に含まれる場合は、そうでない場合はとします。次に、目標はサブセット内の頂点の総数を最小化することであり、以下の関数で表すことができます:
# Construct the cost function.
variables = symbols([f"n[{i}]" for i in range(node_count)])
cost_function = Poly(0, variables)
for i in mvc_graph.nodes():
weight = mvc_graph.nodes[i].get("weight", 0)
cost_function += variables[i] * weight
グラフ内のすべてのエッジは、カバーから少なくとも1つのエンドポイントを含む必要があり、以下の不等式として表すことができます:
エッジがカバーの頂点に接続されていないすべての場合は、ペナルティを科す必要があります。これは、が正のペナルティ定数であるの形式のペナルティを追加することでコスト関数に表すことができます。したがって、重み付きMVCの制約付き不等式に対する制約なしの代替案は次のとおりです:
# Add penalty term.
penalty_constant = 2
for i, j in mvc_graph.edges():
cost_function += penalty_constant * (
1 - variables[i] - variables[j] + variables[i] * variables[j]
)
2. 問題を実行する
# Solve the problem
mvc_job = solver.run(
problem=srepr(cost_function),
backend_name=backend_name, # E.g. "ibm_fez"
)
Qiskit Functionワークロードのステータスを確認するか、以下のように結果を返します:
print(mvc_job.status())
QUEUED
3. 結果を取得する
解を取得して結果を分析します。この問題には重み付きノードがあるため、解は単にカバーされるノードの最小数ではありません。代わりに、解のコストは頂点カバーに含まれる頂点の重みの合計を表しています。これは、選択された頂点を使用してグラフのすべてのエッジをカバーするための総「コスト」または「重み」を表します。
mvc_result = mvc_job.result()
qctrl_cost = mvc_result["solution_bitstring_cost"]
# Print results
print(f"Solution cost: {qctrl_cost}")
Solution cost: 10.248198273708624
サポートを受ける
ご質問や問題がある場合は、Q-CTRLにお問い合わせください。
Changelog
- 2026-02-11: We now have support for
ibm_miami
次のステップ
- Q-CTRL Optimization Solverへのアクセスをリクエストします。
- このQiskit FunctionのAPIリファレンスをご覧ください。
- Q-CTRLのOptimization Solverで高次バイナリ最適化問題を解くチュートリアルに挑戦します。
- Sachdeva, N., et al. (2024). Quantum optimization using a 127-qubit gate-model IBM quantum computer can outperform quantum annealers for nontrivial binary optimization problems. arXiv preprint arXiv:2406.01743.を参照してください。
- Loco, D., et al. (2026). Practical protein-pocket hydration-site prediction for drug discovery on a quantum computer. arXiv preprint arXiv:2512.08390.を参照してください。
- Mazdaケーススタディを参照してください。
- Network Railケーススタディを参照してください。
- Australian Armyケーススタディを参照してください。
- Transport for New South Walesケーススタディを参照してください。