解説
問題 A2 にて実装したスワップゲートの意味を考えましょう。
解法1
はじめに、2 2 2 量子ビットのスワップについて考えます。
1 1 1 番目の量子ビットと 2 2 2 番目の量子ビットをスワップする操作は、制御 X X X ゲートを用いることで実現でき、状態遷移は以下のようになります。
{ ∣ 00 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) → C X ( 0 , 1 ) ∣ 00 ⟩ ∣ 10 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) → C X ( 0 , 1 ) ∣ 01 ⟩ ∣ 01 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) → C X ( 0 , 1 ) ∣ 10 ⟩ ∣ 11 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) → C X ( 0 , 1 ) ∣ 11 ⟩ \begin{equation}
\begin{cases}
\ket {00} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \xrightarrow{CX(0, 1)} \ket{00} \\
\ket {10} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \xrightarrow{CX(0, 1)} \ket{01} \\
\ket {01} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \xrightarrow{CX(0, 1)} \ket{10} \\
\ket {11} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \xrightarrow{CX(0, 1)} \ket{11}
\end{cases}
\end{equation} ⎩ ⎨ ⎧ ∣ 00 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) CX ( 0 , 1 ) ∣ 00 ⟩ ∣ 10 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) CX ( 0 , 1 ) ∣ 01 ⟩ ∣ 01 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) CX ( 0 , 1 ) ∣ 10 ⟩ ∣ 11 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) CX ( 0 , 1 ) ∣ 11 ⟩
ここで、2 2 2 番目の量子ビットが 0 0 0 である時、すなわち ∣ 00 ⟩ , ∣ 10 ⟩ \ket{00}, \ket{10} ∣ 00 ⟩ , ∣ 10 ⟩ となる時の状態遷移に注目します。
{ ∣ 00 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) ∣ 00 ⟩ → C X ( 0 , 1 ) ∣ 00 ⟩ ∣ 10 ⟩ → C X ( 0 , 1 ) → C X ( 1 , 0 ) ∣ 01 ⟩ → C X ( 0 , 1 ) ∣ 01 ⟩ \begin{equation}
\begin{cases}
\ket {00} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \ket{00} \xrightarrow{CX(0, 1)} \ket{00} \\
\ket {10} \xrightarrow{CX(0, 1)} \xrightarrow{CX(1, 0)} \ket{01} \xrightarrow{CX(0, 1)} \ket{01}
\end{cases}
\end{equation} { ∣ 00 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) ∣ 00 ⟩ CX ( 0 , 1 ) ∣ 00 ⟩ ∣ 10 ⟩ CX ( 0 , 1 ) CX ( 1 , 0 ) ∣ 01 ⟩ CX ( 0 , 1 ) ∣ 01 ⟩
上記の ( 2 ) (2) ( 2 ) 式のように、はじめの「1 1 1 番目の量子ビットを制御ビット、2 2 2 番目の量子ビットを標的ビットとする制御 X X X ゲート」と、次の「2 2 2 番目の量子ビットを制御ビット、1 1 1 番目の量子ビットを標的ビットとする制御 X X X ゲート」によって 2 2 2 量子ビットのスワップが実現されていることがわかります。
これを上手く利用することで、この問題を解くことができます。
まず、x n − 1 = 0 x_{n-1} = 0 x n − 1 = 0 であることから x n − 2 , x n − 1 x_{n-2}, x_{n-1} x n − 2 , x n − 1 は 2 2 2 ステップで交換でき、以下の状態遷移が成り立ちます。
∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 2 x n − 1 ⟩ → C X ( n − 2 , n − 1 ) → C X ( n − 1 , n − 2 ) ∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 1 x n − 2 ⟩ \begin{equation}
\ket{x_0x_1 \cdots x_{n-4} x_{n-3} x_{n-2} x_{n-1}} \xrightarrow{CX(n-2,n-1)} \xrightarrow{CX(n-1,n-2)} \ket{x_0x_1 \cdots x_{n-4} x_{n-3} x_{n-1} x_{n-2}}
\end{equation} ∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 2 x n − 1 ⟩ CX ( n − 2 , n − 1 ) CX ( n − 1 , n − 2 ) ∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 1 x n − 2 ⟩
同様に、x n − 1 = 0 x_{n-1} = 0 x n − 1 = 0 であることから x n − 3 , x n − 1 x_{n-3}, x_{n-1} x n − 3 , x n − 1 は 2 2 2 ステップで交換でき、以下の状態遷移が成り立ちます。
∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 1 x n − 2 ⟩ → C X ( n − 3 , n − 2 ) → C X ( n − 2 , n − 3 ) ∣ x 0 x 1 ⋯ x n − 4 x n − 1 x n − 3 x n − 2 ⟩ \begin{equation}
\ket{x_0x_1 \cdots x_{n-4} x_{n-3} x_{n-1} x_{n-2}} \xrightarrow{CX(n-3,n-2)} \xrightarrow{CX(n-2,n-3)} \ket{x_0x_1 \cdots x_{n-4} x_{n-1} x_{n-3} x_{n-2}}
\end{equation} ∣ x 0 x 1 ⋯ x n − 4 x n − 3 x n − 1 x n − 2 ⟩ CX ( n − 3 , n − 2 ) CX ( n − 2 , n − 3 ) ∣ x 0 x 1 ⋯ x n − 4 x n − 1 x n − 3 x n − 2 ⟩
同様の操作を全部で n − 1 n-1 n − 1 回行うことで、目的の量子状態 ∣ x n − 1 x 0 x 1 ⋯ x n − 2 ⟩ \ket{x_{n-1} x_0 x_1 \cdots x_{n-2}} ∣ x n − 1 x 0 x 1 ⋯ x n − 2 ⟩ を深さ 2 ( n − 1 ) 2(n-1) 2 ( n − 1 ) で生成することができます。
n = 3 n = 3 n = 3 の場合の回路図は、以下の通りです。
解法2
A2 の解説で述べたように、3ステップで 2 2 2 変数 x , y x, y x , y をスワップする古典アルゴリズムとして、XOR swap が知られています。
特に y = 0 y=0 y = 0 のとき 3 3 3 ステップ目の「y y y を x + y ( m o d 2 ) x + y \pmod 2 x + y ( mod 2 ) で置き換える操作」を省略できるため、「y y y を x + y ( m o d 2 ) x + y \pmod 2 x + y ( mod 2 ) で置き換える操作」と「 x x x を x + y ( m o d 2 ) x + y \pmod 2 x + y ( mod 2 ) で置き換える操作」の 2 2 2 ステップでXOR swapを実現することができます。
これを利用することで、以下解法で解くこともできます。
まず、制御 X X X ゲートを用いて y y y を x + y ( m o d 2 ) x + y \pmod 2 x + y ( mod 2 ) で置き換える操作を 1 , 2 , … , n − 1 1, 2, \ldots, n-1 1 , 2 , … , n − 1 ビット目に対して行います。
for i in reversed ( range (n - 1 )):
qc.cx(i, i + 1 )
次に、制御 X X X ゲートを用いて x x x を x + y ( m o d 2 ) x + y \pmod 2 x + y ( mod 2 ) で置き換える操作を 1 , 2 , … , n − 1 1, 2, \ldots, n-1 1 , 2 , … , n − 1 ビット目に対して行います。
for i in reversed ( range (n - 1 )):
qc.cx(i + 1 , i)
これによって解法1と同様に、目的の量子状態 ∣ x n − 1 x 0 x 1 ⋯ x n − 2 ⟩ \ket{x_{n-1} x_0 x_1 \cdots x_{n-2}} ∣ x n − 1 x 0 x 1 ⋯ x n − 2 ⟩ を深さ 2 ( n − 1 ) 2(n-1) 2 ( n − 1 ) で生成することができます。
n = 3 n = 3 n = 3 の場合の回路図は、以下の通りです。
解答例
解答例は以下の通りです。
解法1
from qiskit import QuantumCircuit
def solve ( n : int ) -> QuantumCircuit:
qc = QuantumCircuit(n)
for i in reversed ( range (n - 1 )):
qc.cx(i, i + 1 )
qc.cx(i + 1 , i)
return qc
解法2
from qiskit import QuantumCircuit
def solve ( n : int ) -> QuantumCircuit:
qc = QuantumCircuit(n)
for i in reversed ( range (n - 1 )):
qc.cx(i, i + 1 )
for i in reversed ( range (n - 1 )):
qc.cx(i + 1 , i)
return qc