解説
この問題も 問題B6 と同様に特定の計算基底状態の確率振幅を増幅する問題であり、グローバーのアルゴリズムの使用を想定しています。
ここで、Grover iteration を r 回行った後に増幅対象の計算基底状態を観測される確率 P(r) は次式で表されます。
P(r)=sin2((r+21)θ)
ただし、θ=2arcsin(1/2n)とします。
P(r)=1 を満たす実数 r のうち正で最小のもの rmin は、以下のように表せます。
rmin=2θπ−21
実際にはイテレーション回数は整数である必要がありますが、この問題の制約の範囲内では整数に丸めた rmin で操作後に ∣aL∣2≥0.9 を満たすことが確認できます。
また、 n=10 の場合は rmin∼25 であり、Grover iterationの回路は深さ 8 以内で実装できるため、量子回路の深さは 250 以下に抑えることができます。
(1)式の証明
量子状態 ∣ψ′⟩ を以下のように定義します。
∣ψ′⟩=2n−11(i=0∑2n−1∣i⟩−∣L⟩)
∣ψ⟩ は ∣L⟩ と ∣ψ′⟩ を用いて、以下のように表せます。
∣ψ⟩=2n1∣L⟩+2n2n−1∣ψ′⟩
そして、
sin2θ=2n1
を満たす θ を考えると、∣ψ⟩ は以下のように書き換えられます。
∣ψ⟩=sin2θ∣L⟩+cos2θ∣ψ′⟩
ここで、 r を非負整数とし、以下の量子状態にGrover iterationを行った後の量子状態を計算します。
sin((r+21)θ)∣L⟩+cos((r+21)θ)∣ψ′⟩
まず、∣ψ⟩, ∣ψ′⟩, ∣L⟩の内積では、
⟨ψ∣L⟩=⟨L∣ψ⟩=1/2n, ⟨ψ′∣ψ⟩=⟨ψ∣ψ′⟩=2n−1/2n, ⟨ψ′∣L⟩=⟨L∣ψ′⟩=0
が成立し、計算基底状態 ∣L⟩ のみの符号を反転させるオラクルを O とおいたとき、 O=I−2∣L⟩⟨L∣ と表せることから、オラクル O を(7)式の量子状態に作用させると、以下のようになります。
ただし、r+1/2 を r+21 とします。
O(sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩)=(I−2∣L⟩⟨L∣)(sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩)=sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩−2sin(r+21θ)∣L⟩⟨L∣L⟩−2cos(r+21θ)∣L⟩⟨L∣ψ′⟩=sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩−2sin(r+21θ)∣L⟩=−sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩
次に、演算子 2∣ψ⟩⟨ψ∣−I で表される操作を適用すると、以下のようになります。
(2∣ψ⟩⟨ψ∣−I)(−sin(r+21θ)∣L⟩+cos(r+21θ)∣ψ′⟩)=−2sin(r+21θ)∣ψ⟩⟨ψ∣L⟩+2cos(r+21θ)∣ψ⟩⟨ψ∣ψ′⟩+sin(r+21θ)∣L⟩−cos(r+21θ)∣ψ′⟩=−2n2sin(r+21θ)∣ψ⟩+2n22n−1cos(r+21θ)∣ψ⟩+sin(r+21θ)∣L⟩−cos(r+21θ)∣ψ′⟩=−2sin2θsin(r+21θ)∣ψ⟩+2cos2θcos(r+21θ)∣ψ⟩+sin(r+21θ)∣L⟩−cos(r+21θ)∣ψ′⟩=−2sin22θsin(r+21θ)∣L⟩−2sin2θcos2θsin(r+21θ)∣ψ′⟩+2sin2θcos2θcos(r+21θ)∣L⟩+2cos22θcos(r+21θ)∣ψ′⟩+sin(r+21θ)∣L⟩−cos(r+21θ)∣ψ′⟩=((1−2sin22θ)sin(r+21θ)+2sin2θcos2θcos(r+21θ))∣L⟩+((2cos2 2θ−1)cos(r+21θ)−2sin2θcos2θsin(r+21θ))∣ψ′⟩=(sin(r+21θ)cosθ+cos(r+21θ)sinθ)∣L⟩+(cos(r+21θ)cosθ−sin(r+21θ)sinθ)∣ψ′⟩=sin((r+21+1)θ)∣L⟩+cos((r+21+1)θ)∣ψ′⟩
よって、(6)式の∣ψ⟩ に対してGrover iterationを r 回行った後の量子状態は以下のようになることがわかります。
∣ψ⟩=sin((r+21)θ)∣L⟩+cos((r+21)θ)∣ψ′⟩
n=2 の場合の回路図は、以下の通りです。回路図内のReflect_B4
は、B4の回路を示しています。
なお、以上の考察は以下のように幾何学的に考えることができます。
図では、 Uψ=2∣ψ⟩⟨ψ∣−I とおいています。
∣ψ′⟩ と ∣L⟩ が張る 2 次元空間において、 O はベクトルを ∣ψ′⟩ に対して対称なベクトルへ移す変換であり、 Uψ はベクトルを ∣ψ⟩ に対して対称なベクトルへ移す変換です。
解答例
解答例は以下の通りです。
import math
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import ZGate
def compose_oracle(qc: QuantumCircuit, y: QuantumRegister, o: QuantumCircuit) -> QuantumCircuit:
qc.x(y)
qc.h(y)
qc.compose(o, inplace=True)
qc.h(y)
qc.x(y)
return qc
def reflect(n: int) -> QuantumCircuit:
qc = QuantumCircuit(n)
qc.x(range(n))
qc.append(ZGate().control(n - 1), range(n))
qc.x(range(n))
return qc
def solve(n: int, o: QuantumCircuit) -> QuantumCircuit:
x, y = QuantumRegister(n), QuantumRegister(1)
qc = QuantumCircuit(x, y)
theta = math.asin(1 / math.sqrt(2**n)) * 2
rotation_count = int(round(math.pi / 2 / theta - 1 / 2))
qc.h(range(n))
for _ in range(rotation_count):
compose_oracle(qc, y, o)
qc.h(range(n))
qc.compose(reflect(n), inplace=True)
qc.h(range(n))
return qc