Demo 2:Grover 4-qubit

第 3 章 量子算法基础 · 本章演示 · 代码演示总索引

可视化:2×2 子图 —— 迭代 0/1/2/4 测量概率演化

对应教程:第 3 章 量子算法基础 中相关小节 · 依赖安装:pip install "unified-quantum[visualization,simulation]"

实现要点

完整源码

demos/ch03-algo-basics/02_grover_4qubit.py
  1"""
  2ch03 演示 2:Grover 4-qubit 标记 |0011⟩,迭代 0/1/2/4 次测量概率演化
  3
  4对应教程:chenzhaoyun.com/quantum-tutorial/ch03-algo-basics/grover.html
  5依赖:pip install unified-quantum[visualization]
  6运行:python demos/ch03-algo-basics/02_grover_4qubit.py
  7"""
  8from uniqc import (
  9    Circuit,
 10    grover_diffusion,
 11    grover_oracle,
 12    submit_task,
 13    wait_for_result,
 14)
 15import matplotlib
 16matplotlib.use("Agg")
 17import matplotlib.pyplot as plt
 18import numpy as np
 19from pathlib import Path
 20
 21OUT = Path(__file__).parent
 22N_QUBITS = 4
 23MARKED = 3  # = |0011>,即"|11>" 在 4-bit 表示下的等价态
 24ITERATIONS = (0, 1, 2, 4)
 25SHOTS = 2000
 26
 27
 28def run_grover(iterations: int):
 29    """构造均匀初态 |s> = H^n|0>,迭代 Grover 算子若干次,返回测量计数。"""
 30    oracle = grover_oracle(marked_state=MARKED, n_qubits=N_QUBITS)
 31    diff = grover_diffusion(n_qubits=N_QUBITS)
 32    c = Circuit()
 33    # 1) 均匀叠加初态
 34    for q in range(N_QUBITS):
 35        c.h(q)
 36    # 2) 迭代 Grover = Oracle + Diffusion
 37    for _ in range(iterations):
 38        c.add_circuit(oracle)
 39        c.add_circuit(diff)
 40    # 3) 测量每个输入比特
 41    for q in range(N_QUBITS):
 42        c.measure(q)
 43    result = wait_for_result(
 44        submit_task(circuit=c, backend="dummy:local:simulator", shots=SHOTS)
 45    )
 46    # uniqc 的 grover_oracle(marked_state, n_qubits) 会为内部 TOFFOLI
 47    # 多塞 3 个 ancilla(qubits 4,5,6);counts key 的高位就是它们。只保留
 48    # 输入寄存器的低 N_QUBITS 位即可。
 49    input_counts = {}
 50    for bs, cnt in result.counts.items():
 51        input_counts[bs[-N_QUBITS:]] = input_counts.get(bs[-N_QUBITS:], 0) + cnt
 52    return input_counts
 53
 54
 55# === 1. 跑 0/1/2/4 次迭代 ===
 56counts_by_iter = {k: run_grover(k) for k in ITERATIONS}
 57
 58labels = [f"{i:0{N_QUBITS}b}" for i in range(2 ** N_QUBITS)]
 59probs_by_iter = {}
 60for it, counts in counts_by_iter.items():
 61    total = sum(counts.values())
 62    probs_by_iter[it] = np.array([counts.get(lbl, 0) / total for lbl in labels])
 63
 64# === 2. matplotlib 可视化(2x2 子图,对应 4 个迭代深度) ===
 65fig, axes = plt.subplots(2, 2, figsize=(13, 8.5), sharey=True)
 66axes = axes.flatten()
 67
 68for ax, it in zip(axes, ITERATIONS):
 69    probs = probs_by_iter[it]
 70    color = np.where(np.arange(len(probs)) == MARKED, "#d62728", "#1f77b4")
 71    ax.bar(np.arange(len(probs)), probs * 100, color=color, edgecolor="black")
 72    ax.set_xticks(np.arange(len(probs)))
 73    ax.set_xticklabels(labels, rotation=90, fontsize=8)
 74    ax.set_xlabel("Basis state")
 75    ax.set_ylabel("Probability (%)")
 76    p_marked = probs[MARKED]
 77    ax.set_title(
 78        f"Iteration {it}  —  P(|{MARKED:0{N_QUBITS}b}>) = {p_marked:.3f}",
 79        fontsize=11,
 80    )
 81    ax.set_ylim(0, 70)
 82    ax.grid(axis="y", alpha=0.3)
 83
 84fig.suptitle(
 85    f"Grover on {N_QUBITS} qubits marking |{MARKED:0{N_QUBITS}b}> "
 86    f"({SHOTS} shots per iteration, dummy:local:simulator)",
 87    fontsize=12,
 88    y=0.995,
 89)
 90plt.tight_layout()
 91plt.savefig(OUT / "02_grover_4qubit.png", dpi=120, bbox_inches="tight")
 92plt.close()
 93
 94# === 3. stdout 关键统计 ===
 95print("ch03-algo-basics demo 2: Grover 4-qubit amplification")
 96print(f"  marked state: |{MARKED:0{N_QUBITS}b}>  (= int {MARKED})")
 97print(f"  N = 2^{N_QUBITS} = {2**N_QUBITS}; optimal iterations ≈ "
 98      f"{np.pi/4 * np.sqrt(2**N_QUBITS):.2f}")
 99print(f"  P(marked) per iteration:")
100for it in ITERATIONS:
101    p = probs_by_iter[it][MARKED]
102    print(f"    iter {it}: {p:.3f}")
103print(f"  saved: {OUT / '02_grover_4qubit.png'}")

运行结果

Demo 2:Grover 4-qubit

运行方式

# 仓库根目录执行;输出 PNG 到 demos/ch03-algo-basics/02_grover_4qubit.png,关键统计到 stdout
.venv/bin/python3 demos/ch03-algo-basics/02_grover_4qubit.py

← 本章演示 · ↑ 代码演示总索引 · ⌂ 教程门户