B4: Less Than Oracle II

実行時間制限:3 秒

メモリ制限:512 MiB

配点:500点

Writer:admin

解説

以下、L=L1,...,Ln\ket{L} = \ket{L_1, ..., L_n} のように整数 LLii 番目のビットを LiL_i と表すこととします。

はじめに、オラクルの対象となる整数の集合 A={0, 1, ..., L1}A = \left\{0,\ 1,\ ...,\ L-1\right\} を次のように分解します。

A=i=1n(Ai={X(Xi<Li)((Xi+1=Li+1)...(Xn=Ln))})\begin{equation} A = \bigcup_{i=1}^n \left(A_i = \left\{\ket{X} \mid (X_i < L_i) \land ((X_{i+1} = L_{i+1}) \land ... \land (X_n = L_n)) \right\}\right) \end{equation}

すなわち、AAii 番目のビットが LL より小さく、i+1i+1 から nn 番目までのビットがすべて LL と等しいような集合 AiA_i のインデックス ii に関する和集合と言い換えることができます。なお、(Xi<Li)(X_i < L_i)(Xi=0Li=1)(X_i = 0 \land L_i = 1) と等価です。

例として L=5=101\ket{L} = \ket{5} = \ket{101} の場合を考えます。

  • i=1i=1 のとき、 A1={X(X1<1)((X2=0)(X3=1))}={001=4}A_1 = \left\{\ket{X} \mid (X_1 < 1) \land ((X_2 = 0) \land (X_3 = 1)) \right\} = \{\ket{001} = \ket{4}\}
  • i=2i=2 のとき、A2={X(X2<0)(X3=1)}={}A_2 = \left\{\ket{X} \mid (X_2 < 0) \land (X_3 = 1) \right\} = \{\}
  • i=3i=3 のとき、A3={X(X3<1)}={000=0,100=1,010=2,110=3}A_3 = \left\{\ket{X} \mid (X_3 < 1) \right\} = \{\ket{000} = \ket{0}, \ket{100} = \ket{1}, \ket{010} = \ket{2}, \ket{110} = \ket{3}\}

よって、A=A1A2A3={0,1,2,3,4}A = A_1 \cup A_2 \cup A_3 = \{\ket{0}, \ket{1}, \ket{2}, \ket{3}, \ket{4}\} と計算でき、無事 L=5L = 5 未満の状態を列挙できます。

このような分解を元に、インデックス ii それぞれの集合に対して ZZ ゲートを作用させることでオラクルを実現できます。

各インデックスにおいて 2 つの条件 Xi<LiX_i < L_i((Xi+1=Li+1)...(Xn=Ln))((X_{i+1} = L_{i+1}) \land ... \land (X_n = L_n)) は量子ゲートを用いて次のように表現できます。

  • Xi<LiX_i < L_i:
    1. Li=0L_i = 0 の場合には何もしない(ゲートを作用させずにスキップする)
  • ((Xi+1=Li+1)...(Xn=Ln))((X_{i+1} = L_{i+1}) \land ... \land (X_n = L_n)):
    1. i+1i+1 から nn ビット目までのインデックス jj に対して、Lj=0L_j = 0 ならば jj 番目の量子ビットに XX ゲートを作用させる。
    2. ii 番目の量子ビットに XX ゲートを作用させる。( Xi=0X_i = 0 の場合に 1-1 をかけるため)
    3. 複数制御 ZZ ゲートを i+1i+1 から nn ビット目までを制御ビット、ii ビット目を標的ビットとして作用させる。
      1. と 1. の逆操作を行う。

解答例

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

from qiskit import QuantumCircuit
from qiskit.circuit.library import ZGate
 
 
def solve(n: int, L: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
 
    for i in range(n):
        if not (L >> i) & 1:
            continue
        for j in range(i + 1, n):
            if not (L >> j) & 1:
                qc.x(j)
        qc.x(i)
        if i == n - 1:
            qc.z(i)
        else:
            qc.append(ZGate().control(n - i - 1), range(i, n))
        qc.x(i)
        for j in range(i + 1, n):
            if not (L >> j) & 1:
                qc.x(j)
 
    return qc

補足

  • 問題 B3 では、オラクルの対象となるすべての状態にそれぞれ対応した量子ゲートを作用させる実装が想定解法となっていますが、これは貪欲法であり非効率的です。量子アルゴリズムが古典アルゴリズムに対して計算量の観点で優位性を発揮するには、回路の深さの浅い効率的なオラクルを実装する必要があります。
  • より効率的なオラクルの実装法が文献 [1] にて提案されています。

References

  • [1] J. Sanchez-Rivero et al., “Automatic generation of an efficient less-than oracle for quantum amplitude amplification,” in 2023 IEEE/ACM 4th International Workshop on Quantum Software Engineering (Q-SE), May 2023, pp. 26–33. (https://arxiv.org/abs/2303.07120)