<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Qiskit on kenji.blog</title><link>http://kenji.blog/tags/qiskit/</link><description>Recent content in Qiskit on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>ja</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 20:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/tags/qiskit/index.xml" rel="self" type="application/rss+xml"/><item><title>Qiskitを使った量子プログラミング超入門</title><link>http://kenji.blog/p/qiskit-quantum-programming-intro/</link><pubDate>Fri, 11 Sep 2026 20:00:00 +0900</pubDate><guid>http://kenji.blog/p/qiskit-quantum-programming-intro/</guid><description>&lt;img src="http://kenji.blog/p/qiskit-quantum-programming-intro/img/eyecatch.jpg" alt="Featured image of post Qiskitを使った量子プログラミング超入門" />&lt;h2 id="1-はじめに">1. はじめに
&lt;/h2>&lt;p>現代のコンピュータ（古典コンピュータ）は、私たちの生活を劇的に変化させ、高度な計算能力によって社会のあらゆる側面を支えています。しかし、一部の特定の問題（例えば、巨大な数の素因数分解、複雑な分子構造のシミュレーション、最適化問題など）においては、現在の最先端のスーパーコンピュータであっても、宇宙の年齢より長い時間が必要になることが知られています。&lt;/p>
&lt;p>こうした「古典コンピュータの限界」を打ち破る可能性を秘めているのが**量子コンピュータ（Quantum Computer）**です。量子力学の不思議な性質（重ね合わせや量子もつれ）を計算資源として活用することで、特定の問題を劇的に高速化できると考えられています。&lt;/p>
&lt;p>本記事では、IBMがオープンソースで提供している量子コンピューティングのフレームワークである**Qiskit（キスキット）**を用いて、量子プログラミングの世界へ第一歩を踏み出します。物理や数学の基礎から丁寧に解説し、実際にPythonでコードを書き、シミュレータ上で量子回路を動かすまでのプロセスを網羅した、非常に詳細な入門ガイドです。&lt;/p>
&lt;hr>
&lt;h2 id="2-量子計算を支える物理と数学の基礎">2. 量子計算を支える物理と数学の基礎
&lt;/h2>&lt;p>量子プログラミングを理解するためには、まず量子力学の基本的な概念を理解する必要があります。ここでは、量子ビット、重ね合わせ、量子もつれという3つの重要な柱について解説します。&lt;/p>
&lt;h3 id="21-古典ビットと量子ビットqubit">2.1 古典ビットと量子ビット（Qubit）
&lt;/h3>&lt;p>古典コンピュータの情報単位は「ビット（Bit）」です。ビットは常に &lt;code>0&lt;/code> か &lt;code>1&lt;/code> のどちらか一つの状態をとります。&lt;/p>
&lt;p>一方、量子コンピュータの情報の最小単位は**量子ビット（Qubit: Quantum bit）**と呼ばれます。量子ビットは、&lt;code>0&lt;/code> と &lt;code>1&lt;/code> の状態をとることができるだけでなく、&lt;strong>その両方の状態を同時に保持する&lt;/strong>ことが可能です。&lt;/p>
&lt;p>数学的には、量子ビットの状態 $|\psi\rangle$ は、基底状態 $|0\rangle$ と $|1\rangle$ の線形結合（重ね合わせ）として表現されます。&lt;/p>
$$
|\psi\rangle = \alpha|0\rangle + \beta|1\rangle
$$
&lt;p>ここで、$\alpha$ と $\beta$ は複素数であり、それぞれ状態 $|0\rangle$ と $|1\rangle$ を観測する確率振幅を表します。量子力学の基本原理に基づき、確率の合計は1にならなければならないため、以下の規格化条件を満たします。&lt;/p>
$$
|\alpha|^2 + |\beta|^2 = 1
$$
&lt;p>つまり、この量子ビットを「測定（観測）」したとき、$|0\rangle$ が得られる確率は $|\alpha|^2$、$|1\rangle$ が得られる確率は $|\beta|^2$ となります。測定前は確率的にしか状態が決まっていないという点が、古典ビットとの決定的な違いです。&lt;/p>
&lt;div class="mermaid">graph LR
A["古典ビット (Classical Bit)"] --> B["確定した状態: 0 または 1"]
C["量子ビット (Qubit)"] --> D["重ね合わせ: 0 と 1 の両方"]
D --> E["測定によって確率的に状態が確定"]&lt;/div>
&lt;h3 id="22-重ね合わせsuperposition">2.2 重ね合わせ（Superposition）
&lt;/h3>&lt;p>先ほど述べたように、$|0\rangle$ と $|1\rangle$ の状態が混ざり合っている状態を**重ね合わせ（Superposition）**と呼びます。&lt;/p>
&lt;p>例えば、1つの量子ビットが完全に均等な重ね合わせ状態にある場合、$\alpha = \frac{1}{\sqrt{2}}$、$\beta = \frac{1}{\sqrt{2}}$ となります。&lt;/p>
$$
|\psi\rangle = \frac{1}{\sqrt{2}}|0\rangle + \frac{1}{\sqrt{2}}|1\rangle
$$
&lt;p>この状態を測定すると、$|0\rangle$ と $|1\rangle$ がそれぞれ50%の確率で観測されます。
もし2つの量子ビットがあれば、$|00\rangle, |01\rangle, |10\rangle, |11\rangle$ の4つの状態の重ね合わせを作ることができます。$n$個の量子ビットがあれば、$2^n$ 個の状態を同時に表現できることになり、これが量子コンピュータの並列処理能力の源泉の一つとなっています。&lt;/p>
&lt;h3 id="23-量子もつれentanglement">2.3 量子もつれ（Entanglement）
&lt;/h3>&lt;p>量子計算において最も強力かつ不思議な性質が**量子もつれ（Entanglement）**です。アインシュタインが「不気味な遠隔作用」と呼んだこの現象は、2つ以上の量子ビットが互いに強く結びつき、一方の量子ビットの状態が決定されると、物理的にどれだけ離れていても、もう一方の量子ビットの状態が瞬時に決定されるという性質です。&lt;/p>
&lt;p>最も有名な量子もつれ状態である「ベル状態（Bell State）」の一つ、$\Phi^+$ 状態は次のように表されます。&lt;/p>
$$
|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}
$$
&lt;p>この状態では、$|01\rangle$ や $|10\rangle$ という状態は存在しません。したがって、1つ目の量子ビットを測定して $|0\rangle$ だった場合、2つ目の量子ビットを測定するまでもなく、確実に $|0\rangle$ であることが確定します。逆に、1つ目が $|1\rangle$ なら、2つ目も必ず $|1\rangle$ となります。&lt;/p>
&lt;hr>
&lt;h2 id="3-量子論理ゲートquantum-logic-gates">3. 量子論理ゲート（Quantum Logic Gates）
&lt;/h2>&lt;p>古典コンピュータがAND、OR、NOTなどの論理ゲートを用いて計算を行うように、量子コンピュータも&lt;strong>量子ゲート&lt;/strong>を用いて量子ビットの状態を操作します。量子状態はベクトルであるため、量子ゲートはそのベクトルに作用する「ユニタリ行列」として表現されます。&lt;/p>
&lt;h3 id="31-パウリゲートpauli-x-y-z">3.1 パウリゲート（Pauli-X, Y, Z）
&lt;/h3>&lt;p>パウリゲートは、1量子ビットに対する基本的な操作です。&lt;/p>
&lt;p>&lt;strong>・Pauli-X ゲート (NOTゲート)&lt;/strong>
古典のNOTゲートに相当します。$|0\rangle$ を $|1\rangle$ に、$|1\rangle$ を $|0\rangle$ に反転させます。（ブロッホ球においてX軸周りの180度回転）&lt;/p>
$$
X = \begin{pmatrix} 0 &amp; 1 \\ 1 &amp; 0 \end{pmatrix}
$$
&lt;p>&lt;strong>・Pauli-Y ゲート&lt;/strong>
Y軸周りの180度回転を行います。位相とビットの両方を反転させる効果があります。&lt;/p>
$$
Y = \begin{pmatrix} 0 &amp; -i \\ i &amp; 0 \end{pmatrix}
$$
&lt;p>&lt;strong>・Pauli-Z ゲート (位相反転ゲート)&lt;/strong>
$|0\rangle$ の状態はそのままに、$|1\rangle$ の状態の位相を反転（$-1$ を掛ける）させます。（Z軸周りの180度回転）&lt;/p>
$$
Z = \begin{pmatrix} 1 &amp; 0 \\ 0 &amp; -1 \end{pmatrix}
$$
&lt;h3 id="32-アダマールゲートhadamard-gate">3.2 アダマールゲート（Hadamard Gate）
&lt;/h3>&lt;p>アダマールゲート（Hゲート）は、確定した状態（$|0\rangle$ や $|1\rangle$）を重ね合わせ状態に変換する、非常に重要なゲートです。&lt;/p>
$$
H = \frac{1}{\sqrt{2}}
\begin{pmatrix}
1 &amp; 1 \\
1 &amp; -1
\end{pmatrix}
$$
&lt;p>$|0\rangle$ にHゲートを適用すると、均等な重ね合わせ状態である $|+\rangle$ になります。&lt;/p>
$$
H|0\rangle = \frac{1}{\sqrt{2}}|0\rangle + \frac{1}{\sqrt{2}}|1\rangle = |+\rangle
$$
&lt;h3 id="33-位相ゲートphase-gates">3.3 位相ゲート（Phase Gates）
&lt;/h3>&lt;p>位相ゲートは、Zゲートを一般化したもので、$|1\rangle$ 状態の位相を指定した角度 $\theta$ だけ回転させます。&lt;/p>
$$
P(\theta) = \begin{pmatrix} 1 &amp; 0 \\ 0 &amp; e^{i\theta} \end{pmatrix}
$$
&lt;p>代表的なものとして、Sゲート（$\theta = \pi/2$）や Tゲート（$\theta = \pi/4$）があります。&lt;/p>
&lt;h3 id="34-cnotゲートcontrolled-not-gate">3.4 CNOTゲート（Controlled-NOT Gate）
&lt;/h3>&lt;p>CNOTゲート（CXゲート）は、2つの量子ビット間で操作を行うゲートで、量子もつれを生成するために不可欠です。「制御（Control）ビット」と「標的（Target）ビット」から構成されます。&lt;/p>
&lt;p>制御ビットが $|1\rangle$ の場合のみ、標的ビットにXゲート（NOT操作）を適用し、制御ビットが $|0\rangle$ の場合は何もしません。&lt;/p>
$$
CNOT = \begin{pmatrix}
1 &amp; 0 &amp; 0 &amp; 0 \\
0 &amp; 1 &amp; 0 &amp; 0 \\
0 &amp; 0 &amp; 0 &amp; 1 \\
0 &amp; 0 &amp; 1 &amp; 0
\end{pmatrix}
$$
&lt;hr>
&lt;h2 id="4-qiskitの基本と環境構築">4. Qiskitの基本と環境構築
&lt;/h2>&lt;p>ここからは、実際にPythonとQiskitを使用して量子プログラムを書いていきます。&lt;/p>
&lt;h3 id="41-qiskitとは">4.1 Qiskitとは？
&lt;/h3>&lt;p>&lt;strong>Qiskit&lt;/strong>は、IBM Quantumが開発したオープンソースの量子コンピューティング向けソフトウェア開発キット（SDK）です。Pythonを用いて直感的に量子回路を構築し、ローカルのシミュレータや、クラウド経由で実際のIBMの量子コンピュータ実機で実行することができます。&lt;/p>
&lt;h3 id="42-インストール方法">4.2 インストール方法
&lt;/h3>&lt;p>Qiskitを利用するためには、Python環境が必要です。以下のコマンドでQiskitと関連パッケージ（シミュレータや描画用ライブラリ）をインストールします。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install qiskit qiskit-aer qiskit-ibm-runtime matplotlib pylatexenc
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h3 id="43-プログラミングの基本フロー">4.3 プログラミングの基本フロー
&lt;/h3>&lt;p>Qiskitを使った量子プログラミングは、主に以下のステップで進行します。&lt;/p>
&lt;div class="mermaid">graph TD
A["1. 回路の構築 (Build)"] --> B["2. コンパイル/トランスパイル (Compile)"]
B --> C["3. 実行 (Execute)"]
C --> D["4. 結果の解析と可視化 (Analyze)"]&lt;/div>
&lt;ol>
&lt;li>&lt;strong>回路の構築&lt;/strong>: &lt;code>QuantumCircuit&lt;/code> オブジェクトを作成し、ゲートを追加していく。&lt;/li>
&lt;li>&lt;strong>コンパイル&lt;/strong>: 実行するバックエンド（実機やシミュレータ）に合わせて回路を最適化。&lt;/li>
&lt;li>&lt;strong>実行&lt;/strong>: バックエンドにジョブを送信し、結果を取得。&lt;/li>
&lt;li>&lt;strong>解析&lt;/strong>: 測定結果のヒストグラムなどをプロット。&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h2 id="5-実践ベル状態量子もつれを作る回路の構築">5. 実践：ベル状態（量子もつれ）を作る回路の構築
&lt;/h2>&lt;p>理論で学んだ「量子もつれ（ベル状態）」を、実際にQiskitで作成してみましょう。目標とする状態は $|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$ です。&lt;/p>
&lt;h3 id="51-回路の設計">5.1 回路の設計
&lt;/h3>&lt;p>ベル状態を作るには、以下の手順を踏みます。&lt;/p>
&lt;ol>
&lt;li>2つの量子ビットを用意する（初期状態はどちらも $|0\rangle$）。&lt;/li>
&lt;li>1つ目の量子ビットにアダマールゲート（H）を適用し、重ね合わせ状態にする。&lt;/li>
&lt;li>1つ目の量子ビットを「制御ビット」、2つ目の量子ビットを「標的ビット」として、CNOTゲートを適用する。&lt;/li>
&lt;li>結果を読み取るために測定（Measure）を行う。&lt;/li>
&lt;/ol>
&lt;h3 id="52-pythonqiskit-コード実装">5.2 Python/Qiskit コード実装
&lt;/h3>&lt;p>それでは、実際のコードを見てみましょう。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">transpile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit_aer&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Aer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit.visualization&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">plot_histogram&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">matplotlib.pyplot&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">plt&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. 回路の初期化&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2つの量子ビットと、2つの古典ビットを持つ量子回路を作成&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. Hゲートの適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 量子ビット 0 (q0) にアダマールゲートを適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. CNOTゲートの適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># q0 を制御ビット、q1 を標的ビットとして CNOT を適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cx&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 4. 測定&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 量子ビット 0 と 1 を測定し、古典ビット 0 と 1 にそれぞれ書き込む&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">measure&lt;/span>&lt;span class="p">([&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 回路図を描画 (matplotlibを使用)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># qc.draw(&amp;#39;mpl&amp;#39;)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">draw&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>このコードを実行すると、コンソール上にアスキーアートで以下のような量子回路図が表示されます。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"> ┌───┐ ┌─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">q_0: ┤ H ├──■──┤M├───
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └───┘┌─┴─┐└╥┘┌─┐
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">q_1: ─────┤ X ├─╫─┤M├
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> └───┘ ║ └╥┘
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">c: 2/═══════════╩══╩═
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 0 1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;code>H&lt;/code> がアダマールゲート、&lt;code>■&lt;/code> と &lt;code>X&lt;/code> の組み合わせがCNOTゲート、&lt;code>M&lt;/code> が測定を表しています。&lt;/p>
&lt;h3 id="53-シミュレータでの実行と結果の解釈">5.3 シミュレータでの実行と結果の解釈
&lt;/h3>&lt;p>次に、この回路をIBMの高性能シミュレータ &lt;code>Aer&lt;/code> で実行し、結果を確認します。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Aerシミュレータのバックエンドを取得&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">simulator&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Aer&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_backend&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;qasm_simulator&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># シミュレータ向けに回路をトランスパイル（最適化）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">compiled_circuit&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">transpile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">simulator&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 回路を実行（ここでは1000回ショットを実行）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">job&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">simulator&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">compiled_circuit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">shots&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1000&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 結果を取得&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">job&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 状態の観測回数（カウント）を取得&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">counts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_counts&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">compiled_circuit&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">測定結果:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># ヒストグラムのプロット&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># plot_histogram(counts)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># plt.show()&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>結果の解釈&lt;/strong>&lt;/p>
&lt;p>コンソールの出力は以下のようになるはずです。
&lt;code>測定結果: {'00': 495, '11': 505}&lt;/code>
（※確率はランダムなため、実行ごとに数値はわずかに変動します）&lt;/p>
&lt;p>理想的なシミュレーション環境では、測定結果は &lt;code>00&lt;/code> と &lt;code>11&lt;/code> がおよそ50%ずつ観測され、&lt;code>01&lt;/code> や &lt;code>10&lt;/code> は一切観測されません。
これはまさに、私たちが作成したベル状態 $|\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$ の理論的予測と完全に一致しています。1つ目の量子ビットが0であれば2つ目も必ず0、1であれば必ず1になるという「量子もつれ」が正確にシミュレートされています。&lt;/p>
&lt;p>なお、実機の量子コンピュータ（IBM Quantum Hardware）で実行した場合、ノイズ（量子デコヒーレンスやゲートエラー）の影響により、わずかに &lt;code>01&lt;/code> や &lt;code>10&lt;/code> が観測されることがあります。このノイズをいかに減らすか（量子誤り訂正）が、現在の量子コンピュータ開発における最大の課題の一つです。&lt;/p>
&lt;hr>
&lt;h2 id="6-より高度なアルゴリズムへのスケールアップ">6. より高度なアルゴリズムへのスケールアップ
&lt;/h2>&lt;p>ベル状態の作成は量子プログラミングの「Hello World」とも言えます。ここからさらに発展させることで、古典コンピュータを凌駕する強力なアルゴリズムを構築できます。&lt;/p>
&lt;h3 id="61-ドイチェジョサのアルゴリズムdeutsch-jozsa-algorithm">6.1 ドイチェ・ジョサのアルゴリズム（Deutsch-Jozsa Algorithm）
&lt;/h3>&lt;p>与えられた関数 $f(x)$ が「定数関数（入力に関わらず常に0または常に1を出力する）」か「均衡関数（半分の入力に対して0、残りの半分に対して1を出力する）」のどちらであるかを判定する問題です。
古典コンピュータでは最悪の場合 $2^{n-1} + 1$ 回の関数の評価が必要ですが、ドイチェ・ジョサのアルゴリズムを使えば、量子の並列性を利用して&lt;strong>たった1回の評価&lt;/strong>で判定することができます。これは、重ね合わせ状態を入力し、干渉（Interference）を利用して不要な状態を打ち消し、欲しい答えを増幅させるという量子アルゴリズムの基本パターンを示しています。&lt;/p>
&lt;h3 id="62-グローバーのアルゴリズムgrovers-algorithm">6.2 グローバーのアルゴリズム（Grover&amp;rsquo;s Algorithm）
&lt;/h3>&lt;p>ソートされていない $N$ 個のデータベースから特定のデータを探し出す検索問題において、古典アルゴリズムが平均 $N/2$ 回の計算を要するのに対し、グローバーのアルゴリズムは $\sqrt{N}$ 回で目的のデータを見つけ出すことができます。
このアルゴリズムは、「オラクル（Oracle）」と呼ばれるブラックボックスを用いて目的の解の位相を反転させ、さらに「振幅増幅（Amplitude Amplification）」を行うことで、目的の解が観測される確率を劇的に高めます。&lt;/p>
&lt;div class="mermaid">graph TD
A["初期化 (すべての状態の重ね合わせ)"] --> B["オラクル (正解の位相を反転)"]
B --> C["拡散演算子 (平均値周りの反転による振幅増幅)"]
C --> D{"十分な確率に達したか？"}
D -- "No" --> B
D -- "Yes" --> E["測定"]&lt;/div>
&lt;hr>
&lt;h2 id="7-まとめとこれからの学習">7. まとめとこれからの学習
&lt;/h2>&lt;p>この記事では、量子コンピューティングの根本的な概念である重ね合わせや量子もつれから始まり、Qiskitを用いた量子論理ゲートの操作、そして実際にベル状態を構築・シミュレーションして結果を解釈するまでを詳細に解説しました。&lt;/p>
&lt;p>QiskitはPythonという親しみやすい言語で記述できるため、数学的・物理的な壁を越えて、アルゴリズムの構築に集中させてくれる強力なツールです。量子コンピュータは現在、ノイズを伴う中規模量子デバイス（NISQ: Noisy Intermediate-Scale Quantum）の時代にありますが、機械学習（Quantum Machine Learning）、化学シミュレーション（Quantum Chemistry）、暗号解読など、数多くの分野での応用研究が世界中で急速に進められています。&lt;/p>
&lt;p>ぜひ、この機会にQiskitを使って様々な量子回路を自作し、実機のIBM Quantumプロセッサで動かしてみてください。未来のコンピューティング・パラダイムをその手で体験できるはずです。&lt;/p>
&lt;h3 id="参考資料">参考資料
&lt;/h3>&lt;ul>
&lt;li>&lt;a class="link" href="https://qiskit.org/documentation/" target="_blank" rel="noopener"
>Qiskit公式ドキュメント&lt;/a>&lt;/li>
&lt;li>&lt;a class="link" href="https://qiskit.org/textbook/ja/preface.html" target="_blank" rel="noopener"
>Qiskit Textbook&lt;/a> - より深く数学的背景やアルゴリズムを学びたい方におすすめの公式テキスト&lt;/li>
&lt;li>IBM Quantum Learning&lt;/li>
&lt;/ul>
&lt;p>量子の世界へようこそ！&lt;/p></description></item><item><title>ショアのアルゴリズムをPythonでシミュレーションしてみた</title><link>http://kenji.blog/p/shors-algorithm-simulation-python/</link><pubDate>Fri, 11 Sep 2026 08:00:00 +0900</pubDate><guid>http://kenji.blog/p/shors-algorithm-simulation-python/</guid><description>&lt;img src="http://kenji.blog/p/shors-algorithm-simulation-python/img/eyecatch.jpg" alt="Featured image of post ショアのアルゴリズムをPythonでシミュレーションしてみた" />&lt;h1 id="1-はじめに量子コンピュータがもたらす暗号の危機">1. はじめに：量子コンピュータがもたらす暗号の危機
&lt;/h1>&lt;p>現代のインターネット社会におけるセキュリティの大部分は、&lt;strong>公開鍵暗号方式&lt;/strong>（特にRSA暗号）に依存しています。私たちがオンラインショッピングでクレジットカード情報を送信する際や、機密性の高いデータをやり取りする際、その通信内容はRSA暗号によって強固に守られています。&lt;/p>
&lt;p>RSA暗号の安全性の根拠は、「&lt;strong>巨大な整数の素因数分解は、古典コンピュータ（私たちが普段使っているPCやスーパーコンピュータ）では極めて困難である&lt;/strong>」という数学的な事実に依存しています。しかし、1994年にピーター・ショア（Peter Shor）が発表した「&lt;strong>ショアのアルゴリズム（Shor&amp;rsquo;s Algorithm）&lt;/strong>」は、この前提を根底から覆すものでした。ショアのアルゴリズムを大規模な量子コンピュータ上で実行すれば、古典コンピュータでは宇宙の年齢以上の時間を要する素因数分解を、わずか数分から数時間で解くことができると数学的に証明されたのです。&lt;/p>
&lt;p>本記事では、このショアのアルゴリズムがいかにして素因数分解を高速に行うのか、その数学的な仕組みから、Pythonと量子計算フレームワークである&lt;strong>Qiskit&lt;/strong>を用いた具体的なシミュレーション実装までを、徹底的に詳細に解説していきます。&lt;/p>
&lt;hr>
&lt;h1 id="2-計算量の劇的な変化指数関数から多項式時間へ">2. 計算量の劇的な変化：指数関数から多項式時間へ
&lt;/h1>&lt;p>なぜ素因数分解が難しいのでしょうか？古典コンピュータにおける最良の素因数分解アルゴリズムとして知られる「一般数体ふるい法（General Number Field Sieve, GNFS）」を用いたとしても、その計算量は準指数関数的になります。&lt;/p>
&lt;p>桁数 $N$ の合成数を素因数分解するのにかかる時間計算量は、古典的な手法では以下のようになります。&lt;/p>
$$ O\left(\exp\left( c (\log N)^{1/3} (\log \log N)^{2/3} \right)\right) $$
&lt;p>このため、鍵長を長くする（例えば2048ビットや4096ビットにする）だけで、古典コンピュータでの解読には数千年、数万年といった現実的ではない時間がかかるようになります。&lt;/p>
&lt;p>しかし、量子コンピュータ上で&lt;strong>ショアのアルゴリズム&lt;/strong>を用いると、計算量は入力のビット数 $\log N$ に対して多項式時間へと劇的に削減されます。&lt;/p>
$$ O((\log N)^3) $$
&lt;p>これは、ビット数を2倍にした場合、古典コンピュータでは計算時間が天文学的に増大するのに対し、量子コンピュータでは計算時間がせいぜい8倍程度にしか増えないことを意味します。この**指数関数時間から多項式時間への計算量クラスの削減（BQPクラスへの包含）**こそが、ショアのアルゴリズムの真の凄みです。&lt;/p>
&lt;div class="mermaid">graph TD
A["入力サイズ(ビット数) Nの増加"] --> B{"アルゴリズムの選択"}
B -->|古典: 一般数体ふるい法| C["準指数関数的増加 O(exp(...))"]
B -->|量子: ショアのアルゴリズム| D["多項式時間 O((log N)^3)"]
C --> E["数千年〜数十億年 (解読不能)"]
D --> F["数分〜数時間 (現実的な時間で解読)"]&lt;/div>
&lt;hr>
&lt;h1 id="3-アルゴリズムの全体像と数学的背景">3. アルゴリズムの全体像と数学的背景
&lt;/h1>&lt;p>ショアのアルゴリズムは、実はすべてを量子コンピュータで行うわけではありません。古典コンピュータによる前処理・後処理と、量子コンピュータによる核心部分（周期発見アルゴリズム）の連携によって成り立っています。&lt;/p>
&lt;p>アルゴリズムの全体的な流れは以下のようになります。&lt;/p>
&lt;div class="mermaid">graph TD
A["入力: 素因数分解したい合成数 N"] --> B["a &lt; N なる乱数 a を選ぶ"]
B --> C{"gcd(a, N) > 1 ?"}
C -- "Yes" --> D["自明な因数 gcd(a, N) を出力して終了"]
C -- "No" --> E["量子アルゴリズムで f(x) = a^x mod N の周期 r を見つける"]
E --> F{"r が偶数 かつ a^(r/2) ≢ -1 mod N ?"}
F -- "No" --> B
F -- "Yes" --> G["因数 p = gcd(a^(r/2) - 1, N), q = gcd(a^(r/2) + 1, N) を計算"]
G --> H["出力: p, q"]&lt;/div>
&lt;h2 id="素因数分解から周期発見問題への帰着">素因数分解から周期発見問題への帰着
&lt;/h2>&lt;p>ショアの天才的なひらめきは、「&lt;strong>素因数分解問題&lt;/strong>」を「&lt;strong>周期発見問題（Order Finding Problem）&lt;/strong>」に変換したことにあります。&lt;/p>
&lt;p>整数 $N$（素因数分解したい数）と、互いに素な整数 $a$（$1 &lt; a &lt; N$）を考えます。次のようなモジュラー指数関数を定義します。&lt;/p>
$$ f(x) = a^x \bmod N $$
&lt;p>この関数は、ある周期 $r$ を持ちます。つまり、任意の $x$ に対して $f(x+r) = f(x)$ が成り立ちます。特に $x=0$ のとき、&lt;/p>
$$ a^r \equiv 1 \pmod N $$
&lt;p>となる最小の正の整数 $r$ を「$a$ の $N$ を法とする位数（Order）」と呼びます。この周期 $r$ を見つけることができれば、次のようにして素因数を導き出すことができます。&lt;/p>
&lt;p>式を変形すると、
&lt;/p>
$$ a^r - 1 \equiv 0 \pmod N $$
&lt;p>
もし $r$ が偶数であれば、平方差の公式を用いて因数分解できます。
&lt;/p>
$$ (a^{r/2} - 1)(a^{r/2} + 1) \equiv 0 \pmod N $$
&lt;p>これは、$N$ が $(a^{r/2} - 1)$ または $(a^{r/2} + 1)$ のいずれかと公約数を持つことを意味します（ただし $a^{r/2} \not\equiv -1 \pmod N$ という条件を満たす必要があります）。したがって、ユークリッドの互除法を用いて、&lt;/p>
$$ p = \gcd(a^{r/2} - 1, N) $$
$$ q = \gcd(a^{r/2} + 1, N) $$
&lt;p>を計算すれば、$N$ の非自明な素因数 $p, q$ を見つけることができるのです。この計算（最大公約数の計算や乱数の生成）は、古典コンピュータで非常に高速に行えます。問題は、&lt;strong>周期 $r$ をどのようにして高速に見つけるか&lt;/strong>という点に絞られます。古典コンピュータでは、この周期 $r$ を見つけること自体が指数関数的な時間を要してしまいます。ここで量子コンピュータの出番となります。&lt;/p>
&lt;hr>
&lt;h1 id="4-量子アルゴリズム部分周期発見の仕組み">4. 量子アルゴリズム部分：周期発見の仕組み
&lt;/h1>&lt;p>量子コンピュータを用いて周期 $r$ を見つけるためのサブルーチンは、以下の4つのステップで構成されます。&lt;/p>
&lt;div class="mermaid">graph LR
subgraph "量子状態の推移"
S1["|0⟩|0⟩ (初期化)"] --> S2["Hゲート: 重ね合わせ Σ|x⟩|0⟩"]
S2 --> S3["オラクル U: Σ|x⟩|a^x mod N⟩"]
S3 --> S4["QFT: 干渉による周期抽出"]
S4 --> S5["測定: 近似値 y の取得"]
end&lt;/div>
&lt;h2 id="ステップ1量子レジスタの初期化と重ね合わせ">ステップ1：量子レジスタの初期化と重ね合わせ
&lt;/h2>&lt;p>まず、2つの量子レジスタを用意します。第1レジスタは状態を入力するためのもので、第2レジスタは関数の計算結果を格納するためのものです。
初期状態は全て $|0\rangle$ です。&lt;/p>
$$ |\psi_0\rangle = |0\rangle_1 |0\rangle_2 $$
&lt;p>第1レジスタのすべての量子ビットにアダマールゲート（Hadamard Gate）を適用し、考え得るすべての入力 $x$ （$0$ から $Q-1$ まで、$Q=2^n$）の等確率な重ね合わせ状態を作り出します。&lt;/p>
$$ |\psi_1\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle_1 |0\rangle_2 $$
&lt;p>これにより、量子コンピュータは一度の演算で $Q$ 個すべての入力に対する状態を同時に保持することになります。これが&lt;strong>量子並列性&lt;/strong>の強力な源泉です。&lt;/p>
&lt;h2 id="ステップ2オラクル関数モジュラーべき乗の適用">ステップ2：オラクル関数（モジュラーべき乗）の適用
&lt;/h2>&lt;p>次に、量子演算回路 $U_f$ を用いて、関数 $f(x) = a^x \bmod N$ を計算し、その結果を第2レジスタに格納します。&lt;/p>
$$ |\psi_2\rangle = \frac{1}{\sqrt{Q}} \sum_{x=0}^{Q-1} |x\rangle_1 |a^x \bmod N\rangle_2 $$
&lt;p>この時点で、第1レジスタと第2レジスタは**量子もつれ（エンタングルメント）**の状態にあります。もし（仮に）第2レジスタを観測して特定の値 $k = a^{x_0} \bmod N$ を得たとすると、第1レジスタの状態は、その値 $k$ を与えるような $x$ の重ね合わせ状態に崩壊します。関数の周期が $r$ であるため、残る状態は $x_0, x_0+r, x_0+2r, \dots$ という $r$ 飛ばしの値になります。&lt;/p>
$$ |\psi_3\rangle = \sqrt{\frac{r}{Q}} \sum_{j=0}^{M-1} |x_0 + j r\rangle_1 |k\rangle_2 $$
&lt;p>しかし、私たちは $x_0$ を知りたいわけではなく、周期 $r$ 自体を知りたいのです。この状態から $r$ を直接観測することは不可能です。そこで、量子フーリエ変換を用います。&lt;/p>
&lt;h2 id="ステップ3量子フーリエ変換qftによる位相干渉">ステップ3：量子フーリエ変換（QFT）による位相干渉
&lt;/h2>&lt;p>第1レジスタに対して**量子フーリエ変換（Quantum Fourier Transform, QFT）**を適用します。QFTは古典的な離散フーリエ変換の量子版であり、状態ベクトルの振幅を変換します。基底状態 $|x\rangle$ に対するQFTの作用は以下のように定義されます。&lt;/p>
$$ QFT |x\rangle = \frac{1}{\sqrt{Q}} \sum_{y=0}^{Q-1} \omega^{xy} |y\rangle $$
&lt;p>ここで、$\omega = e^{2\pi i / Q}$ です。&lt;/p>
&lt;p>QFTを適用すると、状態の振幅が干渉を起こします。数学的な詳細は省きますが、周期 $r$ を持つ状態に対してQFTを適用すると、波が**建設的干渉（Constructive Interference）&lt;strong>を起こすのは、$y$ が $Q/r$ の整数倍に極めて近い値のときだけになります。それ以外の状態は&lt;/strong>破壊的干渉（Destructive Interference）**により確率振幅が相殺され、ゼロに近づきます。&lt;/p>
&lt;h2 id="ステップ4測定と連分数展開">ステップ4：測定と連分数展開
&lt;/h2>&lt;p>最後に第1レジスタを測定します。測定によって得られる値 $y$ は、高い確率で以下の条件を満たします。&lt;/p>
$$ y \approx c \frac{Q}{r} \implies \frac{y}{Q} \approx \frac{c}{r} $$
&lt;p>（$c$ は $0 \le c &lt; r$ の未知の整数です）&lt;/p>
&lt;p>得られた有理数 $y/Q$ に対して古典アルゴリズムである**連分数展開（Continued Fraction Expansion）**を適用することで、近似分数 $c/r$ を計算し、分母から周期 $r$ を抽出します。&lt;/p>
&lt;hr>
&lt;h1 id="5-pythonとqiskitを用いたシミュレーション実装">5. PythonとQiskitを用いたシミュレーション実装
&lt;/h1>&lt;p>理論だけでは実感が湧かないため、実際にPythonとIBMの量子計算フレームワークである&lt;strong>Qiskit&lt;/strong>を用いて、ショアのアルゴリズムをシミュレーションしてみましょう。&lt;/p>
&lt;p>ここでは、最も古典的で有名な例である &lt;strong>「$N=15$ を $a=7$ を用いて素因数分解する」&lt;/strong> というシナリオを実装します。&lt;/p>
&lt;h2 id="実行環境の準備">実行環境の準備
&lt;/h2>&lt;p>あらかじめQiskitをインストールしておいてください。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install qiskit qiskit-aer numpy
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="python実装コードの全体像">Python実装コードの全体像
&lt;/h2>&lt;p>以下のコードは、$N=15, a=7$ に特化したショアのアルゴリズムの実装例です。汎用的なモジュラーべき乗回路を組むのは現在のシミュレータでは計算コストが高すぎるため、特定の $a=7$ の場合のゲート動作をハードコーディングしています。&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt"> 10
&lt;/span>&lt;span class="lnt"> 11
&lt;/span>&lt;span class="lnt"> 12
&lt;/span>&lt;span class="lnt"> 13
&lt;/span>&lt;span class="lnt"> 14
&lt;/span>&lt;span class="lnt"> 15
&lt;/span>&lt;span class="lnt"> 16
&lt;/span>&lt;span class="lnt"> 17
&lt;/span>&lt;span class="lnt"> 18
&lt;/span>&lt;span class="lnt"> 19
&lt;/span>&lt;span class="lnt"> 20
&lt;/span>&lt;span class="lnt"> 21
&lt;/span>&lt;span class="lnt"> 22
&lt;/span>&lt;span class="lnt"> 23
&lt;/span>&lt;span class="lnt"> 24
&lt;/span>&lt;span class="lnt"> 25
&lt;/span>&lt;span class="lnt"> 26
&lt;/span>&lt;span class="lnt"> 27
&lt;/span>&lt;span class="lnt"> 28
&lt;/span>&lt;span class="lnt"> 29
&lt;/span>&lt;span class="lnt"> 30
&lt;/span>&lt;span class="lnt"> 31
&lt;/span>&lt;span class="lnt"> 32
&lt;/span>&lt;span class="lnt"> 33
&lt;/span>&lt;span class="lnt"> 34
&lt;/span>&lt;span class="lnt"> 35
&lt;/span>&lt;span class="lnt"> 36
&lt;/span>&lt;span class="lnt"> 37
&lt;/span>&lt;span class="lnt"> 38
&lt;/span>&lt;span class="lnt"> 39
&lt;/span>&lt;span class="lnt"> 40
&lt;/span>&lt;span class="lnt"> 41
&lt;/span>&lt;span class="lnt"> 42
&lt;/span>&lt;span class="lnt"> 43
&lt;/span>&lt;span class="lnt"> 44
&lt;/span>&lt;span class="lnt"> 45
&lt;/span>&lt;span class="lnt"> 46
&lt;/span>&lt;span class="lnt"> 47
&lt;/span>&lt;span class="lnt"> 48
&lt;/span>&lt;span class="lnt"> 49
&lt;/span>&lt;span class="lnt"> 50
&lt;/span>&lt;span class="lnt"> 51
&lt;/span>&lt;span class="lnt"> 52
&lt;/span>&lt;span class="lnt"> 53
&lt;/span>&lt;span class="lnt"> 54
&lt;/span>&lt;span class="lnt"> 55
&lt;/span>&lt;span class="lnt"> 56
&lt;/span>&lt;span class="lnt"> 57
&lt;/span>&lt;span class="lnt"> 58
&lt;/span>&lt;span class="lnt"> 59
&lt;/span>&lt;span class="lnt"> 60
&lt;/span>&lt;span class="lnt"> 61
&lt;/span>&lt;span class="lnt"> 62
&lt;/span>&lt;span class="lnt"> 63
&lt;/span>&lt;span class="lnt"> 64
&lt;/span>&lt;span class="lnt"> 65
&lt;/span>&lt;span class="lnt"> 66
&lt;/span>&lt;span class="lnt"> 67
&lt;/span>&lt;span class="lnt"> 68
&lt;/span>&lt;span class="lnt"> 69
&lt;/span>&lt;span class="lnt"> 70
&lt;/span>&lt;span class="lnt"> 71
&lt;/span>&lt;span class="lnt"> 72
&lt;/span>&lt;span class="lnt"> 73
&lt;/span>&lt;span class="lnt"> 74
&lt;/span>&lt;span class="lnt"> 75
&lt;/span>&lt;span class="lnt"> 76
&lt;/span>&lt;span class="lnt"> 77
&lt;/span>&lt;span class="lnt"> 78
&lt;/span>&lt;span class="lnt"> 79
&lt;/span>&lt;span class="lnt"> 80
&lt;/span>&lt;span class="lnt"> 81
&lt;/span>&lt;span class="lnt"> 82
&lt;/span>&lt;span class="lnt"> 83
&lt;/span>&lt;span class="lnt"> 84
&lt;/span>&lt;span class="lnt"> 85
&lt;/span>&lt;span class="lnt"> 86
&lt;/span>&lt;span class="lnt"> 87
&lt;/span>&lt;span class="lnt"> 88
&lt;/span>&lt;span class="lnt"> 89
&lt;/span>&lt;span class="lnt"> 90
&lt;/span>&lt;span class="lnt"> 91
&lt;/span>&lt;span class="lnt"> 92
&lt;/span>&lt;span class="lnt"> 93
&lt;/span>&lt;span class="lnt"> 94
&lt;/span>&lt;span class="lnt"> 95
&lt;/span>&lt;span class="lnt"> 96
&lt;/span>&lt;span class="lnt"> 97
&lt;/span>&lt;span class="lnt"> 98
&lt;/span>&lt;span class="lnt"> 99
&lt;/span>&lt;span class="lnt">100
&lt;/span>&lt;span class="lnt">101
&lt;/span>&lt;span class="lnt">102
&lt;/span>&lt;span class="lnt">103
&lt;/span>&lt;span class="lnt">104
&lt;/span>&lt;span class="lnt">105
&lt;/span>&lt;span class="lnt">106
&lt;/span>&lt;span class="lnt">107
&lt;/span>&lt;span class="lnt">108
&lt;/span>&lt;span class="lnt">109
&lt;/span>&lt;span class="lnt">110
&lt;/span>&lt;span class="lnt">111
&lt;/span>&lt;span class="lnt">112
&lt;/span>&lt;span class="lnt">113
&lt;/span>&lt;span class="lnt">114
&lt;/span>&lt;span class="lnt">115
&lt;/span>&lt;span class="lnt">116
&lt;/span>&lt;span class="lnt">117
&lt;/span>&lt;span class="lnt">118
&lt;/span>&lt;span class="lnt">119
&lt;/span>&lt;span class="lnt">120
&lt;/span>&lt;span class="lnt">121
&lt;/span>&lt;span class="lnt">122
&lt;/span>&lt;span class="lnt">123
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">numpy&lt;/span> &lt;span class="k">as&lt;/span> &lt;span class="nn">np&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit_aer&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AerSimulator&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit.visualization&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">plot_histogram&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">fractions&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Fraction&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">math&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 1. 逆量子フーリエ変換 (QFT†) を構築する関数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">qft_dagger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;n量子ビットの逆量子フーリエ変換回路を生成する&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 順序を反転するためのSWAPゲート&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">qubit&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qubit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">qubit&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 制御位相ゲートとHゲートの適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">j&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">m&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">cp&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">np&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">pi&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="nb">float&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">m&lt;/span>&lt;span class="p">)),&lt;/span> &lt;span class="n">m&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">j&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s2">&amp;#34;QFT_dagger&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">qc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 2. 7^x mod 15 の制御モジュラーべき乗演算を構築する関数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">c_amod15&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">power&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s2">&amp;#34;&amp;#34;&amp;#34;特定のaとべき乗に対する制御Uゲートを生成する(N=15専用)&amp;#34;&amp;#34;&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">_&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">power&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># a=7の場合の 7^x mod 15 のハードコーディング論理&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">13&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">8&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">11&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">3&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">swap&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">0&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">a&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">7&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">11&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="mi">13&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">to_gate&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">name&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">^&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">power&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> mod 15&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">c_U&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">U&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">control&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">c_U&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 3. メインの量子回路構成&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">shor_circuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># n_count: 制御レジスタのビット数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ターゲットレジスタは 0〜15 を表現するため 4ビット&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">QuantumCircuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">4&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 第1レジスタ（制御レジスタ）の初期化（重ね合わせの生成）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">h&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 第2レジスタ（ターゲットレジスタ）を |1&amp;gt; (0001) に初期化&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">x&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 制御モジュラーべき乗演算（オラクル）の適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">q&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 2^q 乗の演算を適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c_amod15&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">[&lt;/span>&lt;span class="n">q&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="n">i&lt;/span>&lt;span class="o">+&lt;/span>&lt;span class="n">n_count&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">i&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">4&lt;/span>&lt;span class="p">)])&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 第1レジスタに逆量子フーリエ変換を適用&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qft_dagger&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 第1レジスタを測定&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">measure&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">),&lt;/span> &lt;span class="nb">range&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">qc&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># --- 実行セクション ---&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">if&lt;/span> &lt;span class="vm">__name__&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="s2">&amp;#34;__main__&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">N&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">a&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">7&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">n_count&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="mi">8&lt;/span> &lt;span class="c1"># 制御レジスタに8量子ビットを使用 (Q=256)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;探索設定: N=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, a=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">, 制御量子ビット数=&lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 回路の生成&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">qc&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">shor_circuit&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># シミュレータでの実行&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sim&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AerSimulator&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 最新のQiskitではtranspileを推奨&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">from&lt;/span> &lt;span class="nn">qiskit&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">transpile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">compiled_circuit&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">transpile&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">qc&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">sim&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">job&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">sim&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">compiled_circuit&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">shots&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="mi">1024&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">result&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">job&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">result&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">counts&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">result&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">get_counts&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">測定結果(ビット列: 観測回数):&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">bitstring&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">count&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">items&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">bitstring&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">count&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">回&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 古典的後処理: 連分数展開による周期rの特定&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s2">--- 周期の計算と素因数分解 ---&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phases&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">output&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="n">counts&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ビット列を10進数に変換&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">decimal&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nb">int&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">output&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 位相 = 測定値 / 2^n_count&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phase&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">decimal&lt;/span> &lt;span class="o">/&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="n">n_count&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">phases&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 連分数展開によって近似分数を取得。分母の上限は N=15&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">frac&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Fraction&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">limit_denominator&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">15&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">r&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">frac&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">denominator&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34;観測値: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">decimal&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">3d&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | 位相: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">phase&lt;/span>&lt;span class="si">:&lt;/span>&lt;span class="s2">.4f&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | 連分数: &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">frac&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> | 推定周期 r = &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 周期 r が偶数かつ有効な結果をもたらすか確認&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">r&lt;/span> &lt;span class="o">%&lt;/span> &lt;span class="mi">2&lt;/span> &lt;span class="o">==&lt;/span> &lt;span class="mi">0&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">guess1&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">guess2&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">math&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">gcd&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">a&lt;/span>&lt;span class="o">**&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">r&lt;/span>&lt;span class="o">//&lt;/span>&lt;span class="mi">2&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="o">+&lt;/span> &lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">guess1&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">]&lt;/span> &lt;span class="ow">or&lt;/span> &lt;span class="n">guess2&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">N&lt;/span>&lt;span class="p">]:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; 成功！ &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">N&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> の素因数は &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">guess1&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> と &lt;/span>&lt;span class="si">{&lt;/span>&lt;span class="n">guess2&lt;/span>&lt;span class="si">}&lt;/span>&lt;span class="s2"> です。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; 自明な因数のみ。やり直し。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">else&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="sa">f&lt;/span>&lt;span class="s2">&amp;#34; =&amp;gt; 周期が奇数のため失敗。&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="コードの解説と実行結果の解析">コードの解説と実行結果の解析
&lt;/h2>&lt;p>上記のコードを実行すると、制御レジスタの測定結果として、高い確率で特定のピーク（観測値）が得られます。&lt;code>n_count=8&lt;/code>（$Q=256$）の場合、理想的な量子コンピュータ（またはシミュレータ）であれば、観測値として &lt;code>0&lt;/code>, &lt;code>64&lt;/code>, &lt;code>128&lt;/code>, &lt;code>192&lt;/code> のような数値が圧倒的な確率で出現します。&lt;/p>
&lt;p>これらを $Q=256$ で割ると、位相 $y/Q$ はそれぞれ $0.0$, $0.25$, $0.5$, $0.75$ となります。
この位相を連分数展開すると：&lt;/p>
&lt;ul>
&lt;li>$0.25 \to 1/4$ （推定周期 $r=4$）&lt;/li>
&lt;li>$0.50 \to 1/2$ （推定周期 $r=2$）&lt;/li>
&lt;li>$0.75 \to 3/4$ （推定周期 $r=4$）&lt;/li>
&lt;/ul>
&lt;p>ここで得られた周期 $r=4$ を用いて、素因数を計算します。
$a=7, r=4$ なので、
$p = \gcd(7^2 - 1, 15) = \gcd(48, 15) = 3$
$q = \gcd(7^2 + 1, 15) = \gcd(50, 15) = 5$&lt;/p>
&lt;p>見事に、$15 = 3 \times 5$ の素因数分解に成功しました。&lt;/p>
&lt;blockquote>
&lt;p>[!TIP]
測定値として $y=128$（位相 $0.5$）が得られた場合、分母は $2$ となり、真の周期 $r=4$ ではなくその約数を得てしまいます。このような場合は、アルゴリズムを複数回実行するか、得られた $r$ の倍数を調べることで真の周期にたどり着くことができます。&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h1 id="6-実用化に向けた課題と-nisq-時代の限界">6. 実用化に向けた課題と NISQ 時代の限界
&lt;/h1>&lt;p>シミュレータ上で $N=15$ を素因数分解することは簡単にできましたが、実社会で使われているRSA-2048（617桁の10進数）を素因数分解するには、現実の量子コンピュータにはまだ数多くの壁が存在します。&lt;/p>
&lt;p>現在私たちが生きている時代は、&lt;strong>NISQ（Noisy Intermediate-Scale Quantum：ノイズあり中規模量子）時代&lt;/strong>と呼ばれています。量子ビットは外部環境のノイズに対して極めて脆弱であり、計算途中で「デコヒーレンス」を起こして状態が壊れてしまいます。&lt;/p>
&lt;p>ショアのアルゴリズムのような深い（ゲート数が多い）回路を正確に実行するためには、ノイズを訂正する**量子誤り訂正（Quantum Error Correction）**が不可欠です。一つのノイズのない「論理量子ビット」を作り出すために、数千個の「物理量子ビット」を表面符号（Surface Code）などでエンコードする必要があります。&lt;/p>
&lt;p>2048ビットのRSA暗号を破るためには、数千個の完璧な論理量子ビットが必要であり、それを実現するには&lt;strong>数百万から数千万個の物理量子ビット&lt;/strong>を搭載したフォールトトレラント（誤り耐性）量子コンピュータが必要になると見積もられています。現在の最先端の量子プロセッサでも数百〜数千物理量子ビット程度であるため、直ちに世界中の暗号が破られるわけではありません。&lt;/p>
&lt;blockquote>
&lt;p>[!WARNING]
しかし、「Store Now, Decrypt Later（今保存して、後で解読する）」という脅威モデルが存在します。攻撃者は現在暗号化されている機密通信を暗号データのまま大量に保存しておき、10〜20年後に強力な量子コンピュータが完成した瞬間に全てを解読するという戦略をとる可能性があります。&lt;/p>
&lt;/blockquote>
&lt;hr>
&lt;h1 id="7-耐量子計算機暗号pqcへの移行">7. 耐量子計算機暗号（PQC）への移行
&lt;/h1>&lt;p>このような「Q-Day（量子コンピュータが暗号を破る日）」の到来に備え、アメリカ国立標準技術研究所（NIST）を筆頭に、世界中の暗号学者が**耐量子計算機暗号（Post-Quantum Cryptography, PQC）**の策定を進めています。&lt;/p>
&lt;p>PQCは、ショアのアルゴリズムを用いても（あるいはグローバーのアルゴリズムを用いても）効率的に解くことができないと数学的に考えられている新しい数学的問題（格子問題、多変数多項式問題、ハッシュ関数ベースなど）を基盤としています。すでに「CRYSTALS-Kyber」や「CRYSTALS-Dilithium」といったアルゴリズムが標準規格として選定され、AppleのiMessageや各種ウェブブラウザの通信プロトコルへの導入が徐々に始まっています。&lt;/p>
&lt;p>ITインフラを管理するエンジニアにとって、既存のRSAや楕円曲線暗号からPQCへの「クリプト・アジリティ（暗号の俊敏性：素早く暗号方式を切り替えられる設計）」をシステムに組み込むことが、今後の大きなミッションとなるでしょう。&lt;/p>
&lt;hr>
&lt;h1 id="8-おわりに">8. おわりに
&lt;/h1>&lt;p>本記事では、ショアのアルゴリズムの理論的な数学的背景から始まり、量子フーリエ変換を用いた周期抽出のメカニズム、そしてPythonとQiskitを用いた具体的なシミュレーションコードまで、1万文字規模のボリュームで徹底的に解説を行いました。&lt;/p>
&lt;p>量子力学というミクロな世界の物理法則が、マクロな情報科学の根幹である計算量理論や暗号理論を根本から覆してしまうという事実は、科学の歴史において最もエキサイティングなパラダイムシフトの一つです。現在進行形で発展し続ける量子コンピューティング技術と、それに立ち向かう新しい暗号技術の攻防戦から、今後も目が離せません。&lt;/p>
&lt;p>ぜひ、今回紹介したPythonコードをご自身の環境で実行し、量子状態の重ね合わせと干渉が生み出す「計算の魔法」を体感してみてください。&lt;/p>
&lt;hr>
&lt;p>&lt;strong>参考文献&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Shor, P. W. (1994). &amp;ldquo;Algorithms for quantum computation: discrete logarithms and factoring&amp;rdquo;. Proceedings 35th Annual Symposium on Foundations of Computer Science.&lt;/li>
&lt;li>Nielsen, M. A., &amp;amp; Chuang, I. L. (2010). &amp;ldquo;Quantum Computation and Quantum Information&amp;rdquo;. Cambridge University Press.&lt;/li>
&lt;li>Qiskit Documentation: &lt;a class="link" href="https://qiskit.org/documentation/" target="_blank" rel="noopener"
>https://qiskit.org/documentation/&lt;/a>&lt;/li>
&lt;/ul></description></item></channel></rss>