B3: Less Than Oracle I

実行時間制限:3 秒

メモリ制限:512 MiB

配点:300点

Writer:admin

解説

計算基底状態 ∣0⟩, ∣1⟩, ... ∣L−1⟩\ket{0},\ \ket{1},\ ...\ \ket{L-1} それぞれの複素振幅 aia_i に −1-1 をかけていくことを考えます。

−1-1 をかける操作自体は ZZ ゲート を利用できます。ZZ ゲートは計算基底状態 ∣0⟩\ket{0} はそのままに、計算基底状態 ∣1⟩\ket{1} を −∣1⟩-\ket{1} に変換するような量子ゲートです。

では、重ね合わせ状態の中の特定の計算基底状態 ∣l⟩\ket{l} にのみ ZZ ゲートを作用させるにはどうすればよいでしょうか?

これは次のように実現できます。

  1. ∣l⟩=∣l1l2l3...ln⟩\ket{l} = \ket{l_1 l_2 l_3 ... l_n} のうち、li=0l_i = 0 であるようなインデックス ii に対して、XX ゲートを作用させます。こうして、∣l⟩\ket{l} を ∣2n−1⟩=∣1...1⟩\ket{2^n - 1} = \ket{1...1} に変換します。
  2. n−1n - 1 ビットを制御ビット、残りの 11 ビットを標的ビットとする複数制御 ZZ ゲート1を作用させます。このとき、ZZ ゲートは重ね合わせ状態の中の計算基底状態 ∣l⟩\ket{l} にのみ作用します。
    1. の逆操作を行い、∣2n−1⟩\ket{2^n - 1} を ∣l⟩\ket{l} に戻します。

よって、この操作を計算基底状態 ∣0⟩, ∣1⟩, ... ∣L−1⟩\ket{0},\ \ket{1},\ ...\ \ket{L-1} それぞれに対して行うことで、この問題を解くことができます。

解答例

解答例は以下の通りです。

from qiskit import QuantumCircuit
from qiskit.circuit.library import ZGate
 
 
def solve(n: int, L: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
 
    for l in range(L):
        for i in range(n):
            # check if i-th bit of l is 0 or 1
            if not ((l >> i) & 1):
                qc.x(i)
        if n == 1:
            qc.z(0)
        else:
            # apply multiple controlled Z gate
            qc.append(ZGate().control(n - 1), range(n))
        for i in range(n):
            if not ((l >> i) & 1):
                qc.x(i)
    return qc

Footnotes

  1. Qiskit では複数制御ゲートを各ゲートクラスのもつ control メソッドを使って実装できます。使い方は解答例を参照してください。 ↩