Nobisuke
Dekisugi
RAG
Privacy policy
2024/08/13 07:21
量子コンピューティングの分野では、効率的で効果的な量子アルゴリズムを改良するための新しい技術が次々と開発されています。最近、2-Step QAOA(量子近似最適化アルゴリズム)というテクニックを公開しました。この手法は、XYミキサーに適した量子状態を簡単に作り出すための新しいアプローチを提供します。
Two-Step QAOA: Enhancing Quantum Optimization by Decomposing One-Hot Constraints in QUBO Formulations
Yuichiro Minato
The Quantum Approximate Optimization Algorithm (QAOA) has shown promise in solving combinatorial optimization problems by leveraging quantum computational power. We propose a simple approach, the Two-Step QAOA, which aims to improve the effectiveness of QAOA by decomposing problems with one-hot encoding QUBO (Quadratic Unconstrained Binary Optimization) formulations. By identifying and separating the problem into two stages, we transform soft constraints into hard constraints, simplifying the generation of initial conditions and enabling more efficient optimization. The method is particularly beneficial for tackling complex societal problems that often involve intricate constraint structures.
2-Step QAOAは、異なる2種類のQAOAを連続して実行することで、XYミキサーに対応した量子状態を作り出す技術です。XYミキサーは、特定の量子アルゴリズムにおいて重要な役割を果たす要素ですが、その効果的な動作には特定の形式の量子状態が必要とされます。通常、この状態はディッケ状態(Dicke state)である必要があります。
ディッケ状態とは、一定数の量子ビットが「1」の状態にあり、残りが「0」の状態にある量子状態のことを指します。XYミキサーが効果的に機能するためには、このディッケ状態を特定の形式で準備する必要がありますが、これは非常に複雑でリソースを要するプロセスです。
従来、この状態を作り出すには精密かつ複雑な手順が必要でした。しかし、2-Step QAOAはこの課題に対する有望な解決策を提供します。
2-Step QAOAでは、最初のQAOAで制約条件を利用して量子状態を作成し、二回目のQAOAではその制約条件を外し、最初のQAOAで作成した量子状態を使って計算を開始します。QAOAは量子断熱計算に基づいており、最初のQAOAで求めた最小基底状態を利用してスタートし、別の解きたい問題の最小基底状態に到達するようにXYミキサーを使用して計算を進めます。
このアプローチにより、計算のステップがわかりやすくなると同時に、量子状態の作成プロセスが簡素化され、さらなる最適化の余地が残されます。
2-Step QAOAの主な利点は、XYミキサーをより使いやすくする点にあります。初期状態の準備の複雑さが軽減されることで、XYミキサーを必要とするアルゴリズムの実装がより容易になります。
さらに、この手法は最適化の新たな可能性を開き、より効率的な量子計算を実現します。ステップバイステップのプロセスであるため、理解しやすく、量子アルゴリズムの探究や実験に取り組む人々にとって貴重なツールとなるでしょう。
こちらのアルゴリズムの作成は通常のIBMのQiskitなどのツールなどを使って簡単に行うことができます。特に特殊なツールは必要なく、今までのツールを流用して作成することができます。
今回はシンプルに3つの量子ビットを準備し、そのうち一つだけを選ぶ問題を設定します。
最初はQUBOと呼ばれる定式化を準備し、そのうちイジングと呼ばれる量子回路で解けるように設定を直します。
QUBOでの変数を
量子ビットには重みが設定されており、q1を選ぶように、q1だけに重み10を設定してみます。制約条件とコストと呼ばれるものが必要になります。
こちらの記事を参考にして多少詳細を変えてます。
Qiskit で遊んでみる (20) — Qiskit Optimization での QAOA
3つの量子ビットから1つを選ぶための制約条件(後でqに変換します。)
q1を選ぶ条件
早速計算してみます。まずは初期状態を作ります。最初は、2-StepQAOAから、初期状態をHを使った重ね合わせ状態に、ミキサーをXを選び、制約条件式を使ってQAOAを実行します。
Qiskitで実行してみます。
from qiskit import QuantumCircuit, transpile
from qiskit.primitives import Sampler
from qiskit_algorithms.optimizers import COBYLA
from qiskit.quantum_info import SparsePauliOp
from qiskit_algorithms.minimum_eigensolvers import QAOA
ツールを読み込んで、初期状態を準備します。
initial_state_circuit = QuantumCircuit(3)
initial_state_circuit.h(0)
initial_state_circuit.h(1)
initial_state_circuit.h(2)
initial_state_circuit.barrier()
display(initial_state_circuit.draw('mpl'))
次に早速制約条件をQAOAに直します。今回は手作業でやってみました。sympyで式を入れます。
量子ビットqと言いましたが、ハミルトニアンのzに読み替えてみます。
また面倒なのですが、QUBOでの01バイナリの値を最終的に量子ビットの値と合わせたい場合には、少し操作が必要です。
x=0をz=-1, x=1をz=1に対応させてしまうと、z=-1の時の量子ビットの値は1になってしまい、z=+1の時は量子ビットの値は0になります。
変換を工夫して、-z = 2x - 1を代入にしてあります。
import sympy as sp
# 変数の定義
x0, x1, x2, z0, z1, z2 = sp.symbols('x0 x1 x2 z0 z1 z2')
# 式の定義
expression = (x0 + x1 + x2 - 1)**2
# 展開
expanded_expression = sp.expand(expression)
print(expanded_expression)
# x^2をxに置換
substituted_expression = expanded_expression.subs({x0**2: x0, x1**2: x1, x2**2: x2})
print(substituted_expression)
# -z = 2x - 1を代入
final_expression = substituted_expression.subs({x0: (-z0 + 1)/2, x1: (-z1 + 1)/2, x2: (-z2 + 1)/2})
# 再度展開
expanded_final_expression = sp.expand(final_expression)
# 分数を小数に変換
decimal_expression = sp.N(expanded_final_expression)
# 結果の表示
print(decimal_expression)
結果として、
0.5*z0*z1 + 0.5*z0*z2 - 0.5*z0 + 0.5*z1*z2 - 0.5*z1 - 0.5*z2 + 1.0
が得られました。これを手作業でQAOAに実装します。最後の定数の1.0は除外します。
sampler = Sampler()
optimizer = COBYLA()
step = 1
# コストハミルトニアンの定義
cost = SparsePauliOp(["ZZI", "ZIZ", "IZZ", "ZII", "IZI", "IIZ"], [0.5, 0.5, 0.5, -0.5, -0.5, -0.5])
qaoa = QAOA(
sampler,
optimizer,
reps=step,
initial_state=initial_state_circuit,
)
result = qaoa.compute_minimum_eigenvalue(cost)
print(result)
display(result.optimal_circuit.draw('mpl'))
結果は、
{ 'aux_operators_evaluated': None,
'best_measurement': { 'bitstring': '001',
'probability': 0.1361159839185406,
'state': 1,
'value': (-1+0j)},
'cost_function_evals': 125,
'eigenstate': {0: 0.028108483960627, 1: 0.111539508728194, 2: 0.111539508728194, 3: 0.186950878581939, 4: 0.111539508728194, 5: 0.186950878581939, 6: 0.186950878581939, 7: 0.076420354108974},
'eigenvalue': -0.10535746385765882,
'optimal_circuit': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7f34b9faab60>,
'optimal_parameters': { ParameterVectorElement(β[0]): 4.53294686272706,
ParameterVectorElement(γ[0]): 2.6926550359765855},
'optimal_point': array([4.53294686, 2.69265504]),
'optimal_value': -0.10535746385765882,
'optimizer_evals': None,
'optimizer_result': <qiskit_algorithms.optimizers.optimizer.OptimizerResult object at 0x7f34b99d5de0>,
'optimizer_time': 2.2393693923950195}
と、なりました。
ここでちょっと回路を確認してみます。
色々仕様が変わってて苦労しましたが、assign_parametersを使うことで得られた回路と角度を設定してQAOAを実行できます。
状態ベクトルで実行してみます。
from qiskit_aer import AerSimulator
bound_circuit = result.optimal_circuit.assign_parameters(result.optimal_parameters)
sim = AerSimulator()
t_qc = transpile(bound_circuit, backend=sim)
counts = sim.run(t_qc).result().get_counts()
print(counts)
結果として、
{'101': 67, '111': 12, '011': 62, '110': 59, '000': 68, '010': 237, '100': 248, '001': 271}
ある程度できました。完全なdicke状態ではないですが、繰り返し回数をがんばればいける気もします。
次に、この作成した状態を初期状態としてもう一回QAOAを連続して実行します。
コストハミルトニアンは
ミキサーハミルトニアンは今回はXYを利用します。
その前にちょっとQiskitで操作をする必要が。
先ほど出力された量子回路は測定を含んでいます。今回はカイロを再利用しますが、測定を外したいので、ゲートをコピーして新しい回路を準備します。
# 測定を取り除く新しい回路を作成
new_circuit = QuantumCircuit(bound_circuit.num_qubits)
# 測定以外の命令を新しい回路に追加
for instr, qargs, cargs in bound_circuit.data:
if instr.name != "measure":
new_circuit.append(instr, qargs, cargs)
# 元の回路に置き換える
bound_circuit = new_circuit
display(new_circuit.draw('mpl'))
できたら早速計算します。
XYミキサーを準備します。それぞれ量子ビットに全結合でかけます。コストは真ん中の量子ビット1にだけかければオッケ。
mixer = SparsePauliOp(["XXI", "YYI", "XIX", "YIY", "IXX", "IYY"], [1/2, 1/2, 1/2, 1/2, 1/2, 1/2])
cost2 = SparsePauliOp(["IZI"], [10])
qaoa = QAOA(
sampler,
optimizer,
reps=step,
initial_state=new_circuit,
mixer=mixer,
)
result2 = qaoa.compute_minimum_eigenvalue(cost2)
print(result2)
結果は、
{ 'aux_operators_evaluated': None,
'best_measurement': { 'bitstring': '010',
'probability': 0.6757586580378196,
'state': 2,
'value': (-10+0j)},
'cost_function_evals': 176,
'eigenstate': {0: 0.082178953352383, 1: 0.001601155937579, 2: 0.658789569931377, 3: 0.092518227299222, 4: 0.059313662657643, 5: 0.02451717463238, 6: 0.06924094024338, 7: 0.011840315946037},
'eigenvalue': -6.647781068400323,
'optimal_circuit': <qiskit.circuit.quantumcircuit.QuantumCircuit object at 0x7f34a3544670>,
'optimal_parameters': { ParameterVectorElement(β[0]): 5.7265622989569795,
ParameterVectorElement(γ[0]): -4.6198069088868525},
'optimal_point': array([ 5.7265623 , -4.61980691]),
'optimal_value': -6.647781068400323,
'optimizer_evals': None,
'optimizer_result': <qiskit_algorithms.optimizers.optimizer.OptimizerResult object at 0x7f34a1d31090>,
'optimizer_time': 6.24747109413147}
いい感じで010が出ました。状態ベクトルも再度実行してみます。
bound_circuit2 = result2.optimal_circuit.assign_parameters(result2.optimal_parameters)
t_qc2 = transpile(bound_circuit2, backend=sim)
counts2 = sim.run(t_qc2).result().get_counts()
print(counts2)
display(bound_circuit2.draw('mpl'))
{'101': 23, '001': 2, '100': 64, '110': 71, '011': 80, '111': 15, '000': 83, '010': 686}
大成功ですね。
2-Step QAOAの導入は、量子コンピューティングの分野において大きな前進を示しています。XYミキサーに対応した量子状態の作成を簡素化することで、この技術は高度な量子アルゴリズムをより実用的かつアクセスしやすいものにする可能性を秘めています。量子コンピューティングが進化し続ける中で、2-Step QAOAのような革新が、このエキサイティングな分野の未来を形作る重要な役割を果たしていくことでしょう。
本ブログでは、2-Step QAOAの可能性について簡単に紹介しました。この手法の技術的な側面や応用についてさらに詳しく知りたい方は、ぜひこの分野の最新の研究や開発を探索してみてください。
© 2024, blueqat Inc. All rights reserved