B3: Less Than Oracle I

実行時間制限:3 秒

メモリ制限:512 MiB

配点:300点

Writer:admin

解説

計算基底状態 0, 1, ... L1\ket{0},\ \ket{1},\ ...\ \ket{L-1} それぞれの複素振幅 aia_i1-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}2n1=1...1\ket{2^n - 1} = \ket{1...1} に変換する。
  2. n1n - 1 ビットを制御ビット、残りの 11 ビットを標的ビットとする複数制御 ZZ ゲート1を作用させます。このとき、ZZ ゲートは重ね合わせ状態の中の計算基底状態 l\ket{l} にのみ作用します。
    1. の逆操作を行い、2n1\ket{2^n - 1}l\ket{l} に戻す。

よって、この操作を計算基底状態 0, 1, ... L1\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 メソッドを使って実装できます。使い方は解答例を参照してください。