Qiskit 与 Python 量子编程实战

IBM Qiskit 完全入门:安装配置、量子电路可视化、 IBM Quantum 真实量子机运行、量子纠缠实验、Deutsch-Jozsa 算法实现。从零开始编写并执行第一个量子程序。

导语:送你一个真实的量子计算机

IBM 在 2016 年向全球开放了 5 量子比特量子计算机的云端访问——任何人只要有网络,就可以向量子处理器提交任务。今天,IBM Quantum 平台提供最高 1000+ 量子比特的系统。

Qiskit 是 IBM 开发的 Python 框架,可以让你在熟悉的编程环境中构建量子电路、在本地模拟器中测试、然后发送到 IBM 的真实量子硬件上执行。

一句话总结:Qiskit 是进入真实量子计算世界的最便捷入口——用 Python 写量子程序,在真正的量子计算机上运行,零硬件投入。


1. 环境准备

1.1 安装 Qiskit

# 创建虚拟环境(推荐)
python -m venv qiskit-env
source qiskit-env/bin/activate  # Linux/macOS
# qiskit-env\Scripts\activate  # Windows

# 安装 Qiskit
pip install qiskit qiskit-ibm-runtime

# 验证安装
python -c "import qiskit; print(qiskit.__version__)"

1.2 获取 IBM Quantum 访问令牌

  1. 访问 https://quantum.ibm.com 注册账号
  2. 进入 API Token 页面
  3. 复制个人访问令牌
from qiskit_ibm_runtime import QiskitRuntimeService

# 保存令牌(首次)
QiskitRuntimeService.save_account(
    channel="ibm_quantum",
    token="YOUR_TOKEN_HERE",
    set_as_default=True,
)

# 后续直接使用
service = QiskitRuntimeService()
print("可用后端:", [b.name for b in service.backends()])
# 输出类似:['ibm_brisbane', 'ibm_sherbrooke', 'ibm_kyiv', ...]

一句话总结:Qiskit 的 Python 生态自然融入数据科学家的工作流——安装、认证、选择后端,三步即可向真实量子机提交任务。


2. 第一个量子程序

2.1 创建量子电路

from qiskit import QuantumCircuit
import matplotlib.pyplot as plt

# 创建一个 2 量子比特、2 经典比特的电路
qc = QuantumCircuit(2, 2)

# 第一步:在第一个量子比特上应用 H 门(创建叠加态)
qc.h(0)

# 第二步:应用 CNOT 门(以量子比特 0 为控制,量子比特 1 为目标)
# 这会将两个量子比特纠缠为贝尔态
qc.cx(0, 1)

# 第三步:测量两个量子比特,结果存入经典比特
qc.measure([0, 1], [0, 1])

# 可视化电路
print("量子电路:")
print(qc.draw(output='text'))

# 保存高清图片
qc.draw(output='mpl', style='iqp')
plt.savefig('bell_circuit.png', dpi=150)

电路图输出:

q_0: ──H──■──M───
          │   │
q_1: ─────┼───M───
          │   │
c: 2/════╩═══╩════
          0   1

2.2 本地模拟器运行

from qiskit_aer import AerSimulator
from qiskit.visualization import plot_histogram

# 使用 Aer 模拟器
simulator = AerSimulator()

# 编译电路(适配后端指令集)
from qiskit import transpile
compiled_circuit = transpile(qc, simulator)

# 运行 1000 次
job = simulator.run(compiled_circuit, shots=1000)
result = job.result()

# 获取统计结果
counts = result.get_counts()
print("测量结果:", counts)
# 预期输出:{'00': ~500, '11': ~500}

# 可视化
fig = plot_histogram(counts)
fig.savefig('bell_histogram.png')

2.3 在真实量子机上运行

from qiskit_ibm_runtime import QiskitRuntimeService, Sampler

service = QiskitRuntimeService()

# 选择一个可用的量子后端(根据量子位数量和队列长度选择)
backend = service.least_busy(operational=True, simulator=False)
print(f"使用后端: {backend.name}")

# 编译电路适配真实硬件
compiled = transpile(qc, backend)

# 使用 Sampler primitive 运行
sampler = Sampler(mode=backend)
job = sampler.run([compiled], shots=1024)

print(f"任务 ID: {job.job_id()}")
print("等待结果...")
result = job.result()

# 真实的量子计算有噪声,结果不会 100% 集中在 00/11
counts = result[0].data.c.get_counts()
print("量子机测量结果:", counts)
# 可能输出:{'00': 480, '11': 460, '01': 42, '10': 42}
# 误差来自量子噪声(退相干、门误差)

一句话总结:Qiskit 的工作流是"设计电路 → 本地模拟验证 → 编译适配 → 提交量子机"——模拟器免费快速,真实量子机能看到真实世界的噪声。


3. 量子门操作库

3.1 所有 Qiskit 标准门

from qiskit import QuantumCircuit

qc = QuantumCircuit(3)  # 3 个量子比特

# ===== 单量子比特门 =====
qc.x(0)       # Pauli-X(量子非门)
qc.y(0)       # Pauli-Y
qc.z(0)       # Pauli-Z(相位翻转)
qc.h(0)       # Hadamard(创建叠加)
qc.s(0)       # S 门(相位 π/2)
qc.t(0)       # T 门(相位 π/4)

# 通用旋转门(绕布洛赫球三个轴)
qc.rx(np.pi/4, 0)   # 绕 X 轴旋转 π/4
qc.ry(np.pi/3, 0)   # 绕 Y 轴旋转 π/3
qc.rz(np.pi/2, 0)   # 绕 Z 轴旋转 π/2

# U 门(最通用的单量子比特门)
# U(θ, φ, λ) = RZ(φ) * RY(θ) * RZ(λ)
qc.u(np.pi/2, 0, np.pi, 0)

# ===== 双量子比特门 =====
qc.cx(0, 1)   # CNOT(受控非)
qc.cz(0, 1)   # CZ(受控 Z)
qc.swap(0, 1) # SWAP(交换)

# 受控旋转
qc.crx(np.pi/2, 0, 1)  # 控制位为 |1⟩ 时对目标做 RX

# ===== 三量子比特门 =====
qc.ccx(0, 1, 2)  # Toffoli(双控非)
qc.cswap(0, 1, 2)  # Fredkin(受控交换)

print(qc.draw())

3.2 自定义参数化电路

from qiskit.circuit import Parameter
import numpy as np

# 定义参数
theta = Parameter('θ')
phi = Parameter('φ')

# 构建参数化电路(常用于变分量子算法 VQE/QAOA)
qc = QuantumCircuit(2)
qc.rx(theta, 0)
qc.ry(phi, 1)
qc.cx(0, 1)

# 绑定参数值
bound_circuit = qc.assign_parameters({theta: np.pi/4, phi: np.pi/3})
print(bound_circuit.draw())

一句话总结:Qiskit 提供了完备的量子门操作库,从单比特旋转到多比特控制门,还支持参数化电路——这是变分量子算法(VQE、QAOA)实现的基础。


4. 实战:Deutsch-Jozsa 算法

Deutsch-Jozsa 算法是展示量子优势的"Hello World"——用一次查询判断函数是常数函数还是平衡函数,而经典计算机最坏需要 2^(n-1)+1 次查询。

from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
import numpy as np

# ===== 构建 Oracle =====
# Oracle 是一个黑盒函数,量子查询通过控制操作实现
# 这里构造一个"平衡函数"的 Oracle

def create_oracle(n, oracle_type='balanced'):
    """
    n: 输入比特数
    oracle_type: 'constant' 或 'balanced'
    """
    oracle = QuantumCircuit(n + 1)
    
    if oracle_type == 'balanced':
        # 平衡函数:一半输入输出 0,一半输出 1
        # 实现:对第一个输入做 CNOT
        oracle.cx(0, n)
    else:
        # 常数函数:所有输入输出相同
        # 常数 0:不做任何操作
        # 常数 1:翻转输出比特
        oracle.x(n)
    
    return oracle

# ===== 完整的 Deutsch-Jozsa 算法电路 =====
n = 3  # 3 个输入比特

dj_circuit = QuantumCircuit(n + 1, n)

# 步骤1:最后一个量子比特设为 |1⟩
dj_circuit.x(n)

# 步骤2:所有量子比特应用 H
dj_circuit.h(range(n + 1))

# 步骤3:插入 Oracle
oracle = create_oracle(n, 'balanced')
dj_circuit = dj_circuit.compose(oracle)

# 步骤4:前 n 个量子比特再应用 H
dj_circuit.h(range(n))

# 步骤5:测量前 n 个量子比特
dj_circuit.measure(range(n), range(n))

print(dj_circuit.draw())

# ===== 在模拟器中运行 =====
simulator = AerSimulator()
compiled = transpile(dj_circuit, simulator)
result = simulator.run(compiled, shots=1024).result()
counts = result.get_counts()

print("测量结果:", counts)
# 如果是平衡函数:结果不会是 |000⟩
# 如果是常数函数:结果一定是 |000⟩

# 判断逻辑
if '0' * n in counts and counts['0' * n] == 1024:
    print("函数是常数函数")
else:
    print("函数是平衡函数")

一句话总结:Deutsch-Jozsa 算法是理解量子并行和量子优势的教科书案例——经典计算需要指数级查询,量子计算只需要 1 次。


5. 噪声与错误缓解

真实量子计算机的噪声来源:

噪声类型描述缓解方法
T1 退相干量子比特与环境耦合,失去量子态选择相干时间长的量子比特
T2 退相位相对相位随机漂移动态解耦(Dynamical Decoupling)
门误差量子门操作不完美错误缓解算法
测量误差测量结果误判测量错误校准
串扰相邻量子比特间的不受控交互电路重排、隔离策略

5.1 错误缓解

from qiskit_ibm_runtime import Estimator
from qiskit.primitives import EstimatorPub
from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager

# 生成带错误缓解的 Estimator
estimator = Estimator(mode=backend, options={
    "resilience": {
        "measure_mitigation": True,  # 测量错误缓解
        "zne_mitigation": True,      # 零噪声外推
    }
})

一句话总结:当前量子计算机处于 NISQ(含噪声中等规模量子)时代——噪声是真实计算的核心挑战,Qiskit 提供了多种缓解策略来提高结果质量。


6. 总结

Qiskit 编程的核心工作流:

  1. 设计电路:QuantumCircuit(n_qubits, n_clbits)
  2. 添加门操作:h()、cx()、measure() 等
  3. 本地模拟:AerSimulator().run() 快速验证
  4. 编译适配:transpile() 将逻辑电路映射到物理硬件
  5. 提交执行:Sampler.run() 或 Estimator.run()
  6. 分析结果:统计测量结果,评估量子优势

Qiskit 的完整学习路径:

  • IBM Quantum Learning 平台:https://learning.quantum.ibm.com
  • Qiskit Runtime Primitives:Sampler(采样)和 Estimator(期望值估计)
  • Qiskit Patterns:量子计算的标准设计模式

延伸阅读:

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「quantum」更多文章

  1. 开放量子系统与退相干建模:密度矩阵、Kraus 与 Lindblad 方程
  2. 量子基准测试与性能指标:保真度、量子体积与 CLOPS
  3. 量子编译器与电路转译:从逻辑线路到硬件脉冲