1. Cirq环境搭建与第一个量子电路

Cirq 是 Google 主导开发的开源量子计算框架,它的核心定位不是“通用量子算法库”,而是帮助开发者精确描述量子电路在具体硬件上的执行细节。与一些高度封装的框架不同,Cirq 把量子比特、门操作、时刻(Moment)、测量等概念都显式暴露出来,这让它非常适合学习量子电路的真实结构,也方便后续对接真实量子处理器。本章的目标很明确:完成环境安装,创建量子比特,搭建一个最简单的量子电路,在本地模拟器上运行,并读取测量结果。

安装 Cirq 与验证环境

Cirq 以 Python 包的形式发布,推荐使用 Python 3.9 及以上版本。为了避免与系统中其他 Python 项目产生依赖冲突,建议先创建独立虚拟环境,再安装 Cirq。以下命令在 Windows、macOS 和 Linux 上基本通用:

python -m venv cirq-env
# Windows
cirq-env\Scripts\activate
# macOS / Linux
source cirq-env/bin/activate

pip install --upgrade pip
pip install cirq

如果只是做电路模拟,安装 cirq 即可;若后续需要连接真实硬件或使用更完整的工具链,可以安装 cirq-core、cirq-google 等子包。安装完成后,用一段最小代码验证环境是否可用:

import cirq
print(cirq.__version__)
q = cirq.LineQubit(0)
print(cirq.Circuit(cirq.X(q), cirq.measure(q)))

如果终端能打印出版本号,并输出类似 0: ───X───M─── 的电路文本图,说明 Cirq 已经可以正常工作。这里的 0 是量子比特编号,X 是 Pauli-X 门,M 表示测量。文本电路图是 Cirq 非常实用的调试工具,它按“时刻”从左到右排列,每一列代表一个可以并行执行的时刻。

量子比特、门与时刻的基本关系

在 Cirq 中,量子比特用 LineQubit、GridQubit 或 NamedQubit 表示。LineQubit 适合一维链式结构,GridQubit 适合二维网格硬件拓扑,NamedQubit 则允许用字符串命名。对于入门示例,使用 LineQubit.range(2) 就能快速得到两个量子比特 q0 和 q1。

量子门是作用在量子比特上的操作。常见的单比特门包括 X、Y、Z、H,两比特门最典型的是 CNOT。Cirq 会把电路自动切分成若干“时刻”,同一时刻内的门必须作用在互不重叠的量子比特上。例如,先对 q0 施加 H 门,再以 q0 为控制、q1 为目标施加 CNOT,就构成了最经典的纠缠态制备电路。这个电路虽然只有两个门,却能把 |00⟩ 变成 (|00⟩+|11⟩)/√2,是理解量子并行与纠缠的最小实验。

Cirq 电路:H + CNOT + 测量 q0 先叠加,再作为控制位;q1 作为目标位,最终得到纠缠态 q0 q1 H M M 模拟器测量统计(示例) 00:约 50% 11:约 50% 01 / 10:接近 0 多次采样后统计,非单次结果

构建并运行第一个电路

下面给出一个完整可运行的示例。它创建两个量子比特,先对 q0 施加 H 门,再用 CNOT 把 q0 与 q1 纠缠起来,最后同时测量两个量子比特。测量结果会以位串形式返回,例如 00 或 11。

import cirq

q0, q1 = cirq.LineQubit.range(2)

circuit = cirq.Circuit(
    cirq.H(q0),
    cirq.CNOT(q0, q1),
    cirq.measure(q0, q1, key='result')
)

print("电路结构:")
print(circuit)

simulator = cirq.Simulator()
result = simulator.run(circuit, repetitions=1000)

print("测量统计:")
print(result.histogram(key='result'))

运行后,print(circuit) 会输出类似下面的文本电路图:

0: ───H───@───M('result')───
          │   │
1: ───────X───M─────────────

其中 @ 表示控制位,X 表示目标位,M 表示测量。测量统计通常会在 00 和 11 两个结果上各占约一半,01 和 10 几乎不出现。这正是纠缠态的典型特征:两个量子比特的测量结果高度相关,而不是各自独立随机。需要说明的是,这里给出的比例是理想模拟器下的理论期望,实际运行会因采样次数存在统计涨落。

如何读取与判断结果

Cirq 的 run() 返回的是 Result 对象,可以通过 histogram() 查看各测量结果的频次,也可以直接访问 measurements 获取原始位串数组。判断电路是否正确,关键看两点:第一,电路结构是否符合预期,即 H 门是否在 CNOT 之前、控制位与目标位是否接对;第二,测量统计是否与理论分布一致。对于上面的贝尔态电路,如果 00 与 11 的频次接近相等,且 01、10 接近零,就说明纠缠制备成功。

如果测量结果中 01 和 10 大量出现,优先检查 CNOT 的控制位和目标位是否写反,或者 H 门是否误加到了 q1 上。Cirq 的文本电路图能直观暴露这类接线错误。

常见问题与排查

初学者最容易遇到三类问题。第一类是安装问题,例如 pip install cirq 因网络或版本冲突失败,此时可尝试指定版本或使用国内镜像源。第二类是 API 使用问题,例如把 cirq.measure 写成 cirq.measurement,或者忘记给测量指定 key,导致后续无法按名称读取结果。第三类是概念问题,例如误以为 simulator.run() 返回的是单个确定结果,实际上它默认执行一次采样,只有设置 repetitions 后才能看到统计分布。

建议在第一个电路跑通后,做一个小练习:把 H 门去掉,只保留 CNOT 和测量,观察结果是否稳定为 00;再把 H 门加到 q1 上,观察统计是否发生变化。通过这种对比,可以快速建立对“叠加”“纠缠”“测量”三个概念的直观认识,也为后续学习参数化电路、噪声模拟和真实硬件运行打下基础。