Qibo量子算法示例¶
这个notebook展示了几个基本的量子算法实现。
In [1]:
Copied!
import qibo
from qibo import models, gates
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi']
print(f"Qibo版本: {qibo.__version__}")
import qibo
from qibo import models, gates
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'SimSun', 'KaiTi']
print(f"Qibo版本: {qibo.__version__}")
Qibo版本: 0.2.20
1. 量子傅里叶变换 (QFT)¶
量子傅里叶变换是许多量子算法的基础,如Shor算法。
In [2]:
Copied!
def qft_rotations(circuit, n):
"""对n个量子比特应用QFT旋转"""
if n == 0:
return circuit
n -= 1
circuit.add(gates.H(n))
for qubit in range(n):
circuit.add(gates.CU1(qubit, n, np.pi/2**(n-qubit)))
return qft_rotations(circuit, n)
def swap_registers(circuit, n):
"""交换寄存器中的量子比特"""
for qubit in range(n//2):
circuit.add(gates.SWAP(qubit, n-qubit-1))
return circuit
def qft(circuit, n):
"""对n个量子比特应用QFT"""
qft_rotations(circuit, n)
swap_registers(circuit, n)
return circuit
# 创建一个4量子比特的QFT电路
n_qubits = 4
qft_circuit = models.Circuit(n_qubits)
# 初始化为|1010>
qft_circuit.add(gates.X(0))
qft_circuit.add(gates.X(2))
# 应用QFT
qft(qft_circuit, n_qubits)
# 打印电路
qft_circuit.draw()
# 执行电路
result = qft_circuit.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 绘制概率分布图
plt.figure(figsize=(12, 6))
plt.bar(range(len(probabilities)), probabilities)
plt.xlabel('状态索引')
plt.ylabel('概率')
plt.title('QFT应用于|1010>的概率分布')
plt.xticks(range(0, len(probabilities), 2))
plt.grid(axis='y', alpha=0.3)
plt.show()
def qft_rotations(circuit, n):
"""对n个量子比特应用QFT旋转"""
if n == 0:
return circuit
n -= 1
circuit.add(gates.H(n))
for qubit in range(n):
circuit.add(gates.CU1(qubit, n, np.pi/2**(n-qubit)))
return qft_rotations(circuit, n)
def swap_registers(circuit, n):
"""交换寄存器中的量子比特"""
for qubit in range(n//2):
circuit.add(gates.SWAP(qubit, n-qubit-1))
return circuit
def qft(circuit, n):
"""对n个量子比特应用QFT"""
qft_rotations(circuit, n)
swap_registers(circuit, n)
return circuit
# 创建一个4量子比特的QFT电路
n_qubits = 4
qft_circuit = models.Circuit(n_qubits)
# 初始化为|1010>
qft_circuit.add(gates.X(0))
qft_circuit.add(gates.X(2))
# 应用QFT
qft(qft_circuit, n_qubits)
# 打印电路
qft_circuit.draw()
# 执行电路
result = qft_circuit.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 绘制概率分布图
plt.figure(figsize=(12, 6))
plt.bar(range(len(probabilities)), probabilities)
plt.xlabel('状态索引')
plt.ylabel('概率')
plt.title('QFT应用于|1010>的概率分布')
plt.xticks(range(0, len(probabilities), 2))
plt.grid(axis='y', alpha=0.3)
plt.show()
[Qibo 0.2.20|INFO|2025-09-02 11:00:43]: Using numpy backend on /CPU:0
0: ─X─o──────────o───────o──H─x─── 1: ───|──o───────|──o──H─U1───|─x─ 2: ─X─|──|──o──H─U1─U1────────|─x─ 3: ─H─U1─U1─U1────────────────x───
2. Grover搜索算法¶
Grover算法是一种量子搜索算法,可以在无序数据库中以O(√N)的复杂度找到目标元素。
In [ ]:
Copied!
def grover_circuit(n_qubits, target_state):
"""创建Grover搜索算法电路
参数:
n_qubits: 量子比特数量
target_state: 目标状态的二进制表示
"""
# 创建电路
circuit = models.Circuit(n_qubits)
# 初始化为均匀叠加态
for i in range(n_qubits):
circuit.add(gates.H(i))
# 计算迭代次数 (π/4 * √N)
iterations = int(np.pi/4 * np.sqrt(2**n_qubits))
# Grover迭代
for _ in range(iterations):
# 标记目标状态(Oracle)
# 这里我们使用多控制Z门来标记目标状态
for i in range(n_qubits):
if target_state[i] == '0':
circuit.add(gates.X(i))
# 多控制Z门 (使用辅助比特实现)
if n_qubits > 2:
controls = list(range(n_qubits-1))
circuit.add(gates.MCZ(controls, n_qubits-1))
else:
circuit.add(gates.CZ(0, 1))
for i in range(n_qubits):
if target_state[i] == '0':
circuit.add(gates.X(i))
# 振幅放大
# 1. 对所有量子比特应用H门
for i in range(n_qubits):
circuit.add(gates.H(i))
# 2. 对|0>态应用相位反转
for i in range(n_qubits):
circuit.add(gates.X(i))
# 3. 应用多控制Z门
if n_qubits > 2:
controls = list(range(n_qubits-1))
circuit.add(gates.Z(controls, n_qubits-1))
else:
circuit.add(gates.CZ(0, 1))
# 4. 恢复
for i in range(n_qubits):
circuit.add(gates.X(i))
# 5. 再次应用H门
for i in range(n_qubits):
circuit.add(gates.H(i))
return circuit
# 创建一个3量子比特的Grover电路,搜索状态|101>
n_qubits = 3
target = '101'
grover = grover_circuit(n_qubits, target)
# 执行电路
result = grover.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 显示概率分布
for i, prob in enumerate(probabilities):
if prob > 0.01: # 只显示概率大于1%的状态
print(f"|{i:0{n_qubits}b}>: {prob:.4f}")
# 绘制概率分布图
plt.figure(figsize=(10, 6))
plt.bar([f"{i:0{n_qubits}b}" for i in range(2**n_qubits)], probabilities)
plt.xlabel('量子态')
plt.ylabel('概率')
plt.title(f'Grover搜索算法: 目标状态 |{target}>')
plt.xticks(rotation=45)
plt.grid(axis='y', alpha=0.3)
plt.show()
def grover_circuit(n_qubits, target_state):
"""创建Grover搜索算法电路
参数:
n_qubits: 量子比特数量
target_state: 目标状态的二进制表示
"""
# 创建电路
circuit = models.Circuit(n_qubits)
# 初始化为均匀叠加态
for i in range(n_qubits):
circuit.add(gates.H(i))
# 计算迭代次数 (π/4 * √N)
iterations = int(np.pi/4 * np.sqrt(2**n_qubits))
# Grover迭代
for _ in range(iterations):
# 标记目标状态(Oracle)
# 这里我们使用多控制Z门来标记目标状态
for i in range(n_qubits):
if target_state[i] == '0':
circuit.add(gates.X(i))
# 多控制Z门 (使用辅助比特实现)
if n_qubits > 2:
controls = list(range(n_qubits-1))
circuit.add(gates.MCZ(controls, n_qubits-1))
else:
circuit.add(gates.CZ(0, 1))
for i in range(n_qubits):
if target_state[i] == '0':
circuit.add(gates.X(i))
# 振幅放大
# 1. 对所有量子比特应用H门
for i in range(n_qubits):
circuit.add(gates.H(i))
# 2. 对|0>态应用相位反转
for i in range(n_qubits):
circuit.add(gates.X(i))
# 3. 应用多控制Z门
if n_qubits > 2:
controls = list(range(n_qubits-1))
circuit.add(gates.Z(controls, n_qubits-1))
else:
circuit.add(gates.CZ(0, 1))
# 4. 恢复
for i in range(n_qubits):
circuit.add(gates.X(i))
# 5. 再次应用H门
for i in range(n_qubits):
circuit.add(gates.H(i))
return circuit
# 创建一个3量子比特的Grover电路,搜索状态|101>
n_qubits = 3
target = '101'
grover = grover_circuit(n_qubits, target)
# 执行电路
result = grover.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 显示概率分布
for i, prob in enumerate(probabilities):
if prob > 0.01: # 只显示概率大于1%的状态
print(f"|{i:0{n_qubits}b}>: {prob:.4f}")
# 绘制概率分布图
plt.figure(figsize=(10, 6))
plt.bar([f"{i:0{n_qubits}b}" for i in range(2**n_qubits)], probabilities)
plt.xlabel('量子态')
plt.ylabel('概率')
plt.title(f'Grover搜索算法: 目标状态 |{target}>')
plt.xticks(rotation=45)
plt.grid(axis='y', alpha=0.3)
plt.show()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[3], line 66 64 n_qubits = 3 65 target = '101' ---> 66 grover = grover_circuit(n_qubits, target) 68 # 执行电路 69 result = grover.execute() Cell In[3], line 29, in grover_circuit(n_qubits, target_state) 27 if n_qubits > 2: 28 controls = list(range(n_qubits-1)) ---> 29 circuit.add(gates.MCZ(controls, n_qubits-1)) 30 else: 31 circuit.add(gates.CZ(0, 1)) AttributeError: module 'qibo.gates' has no attribute 'MCZ'
3. 量子相位估计¶
量子相位估计是Shor算法和量子化学模拟的关键组成部分。
In [ ]:
Copied!
def phase_estimation_circuit(precision, unitary_gate):
"""创建量子相位估计电路
参数:
precision: 估计精度(量子比特数)
unitary_gate: 要估计特征值的幺正门
"""
# 总量子比特数 = 精度 + 1个目标量子比特
n_qubits = precision + 1
# 创建电路
circuit = models.Circuit(n_qubits)
# 初始化目标量子比特为特征向量
# 这里我们使用|1>作为示例
circuit.add(gates.X(precision))
# 对估计寄存器应用H门
for i in range(precision):
circuit.add(gates.H(i))
# 应用受控幺正门
for i in range(precision):
# 应用2^i次幺正门
repetitions = 2 ** i
for _ in range(repetitions):
if unitary_gate == 'T':
circuit.add(gates.CT(i, precision))
elif unitary_gate == 'S':
circuit.add(gates.CS(i, precision))
# 应用逆QFT到估计寄存器
# 首先交换比特顺序
for i in range(precision // 2):
circuit.add(gates.SWAP(i, precision - i - 1))
# 然后应用逆QFT
for i in range(precision):
circuit.add(gates.H(i))
for j in range(i + 1, precision):
circuit.add(gates.CU1(j, i, -np.pi / float(2 ** (j - i))))
return circuit
# 创建一个相位估计电路,估计T门的相位
# T门的特征值是e^(i*pi/4),相位是1/8
precision = 3
pe_circuit = phase_estimation_circuit(precision, 'T')
# 执行电路
result = pe_circuit.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 只关注估计寄存器的结果
estimation_probs = np.zeros(2**precision)
for i in range(2**precision):
for j in range(2):
idx = i + j * (2**precision)
estimation_probs[i] += probabilities[idx]
# 显示概率分布
for i, prob in enumerate(estimation_probs):
if prob > 0.01: # 只显示概率大于1%的状态
phase = i / (2**precision)
print(f"|{i:0{precision}b}>: {prob:.4f} (相位 ≈ {phase:.4f})")
# 绘制概率分布图
plt.figure(figsize=(10, 6))
plt.bar([f"{i:0{precision}b}" for i in range(2**precision)], estimation_probs)
plt.xlabel('估计寄存器状态')
plt.ylabel('概率')
plt.title('量子相位估计: T门的相位 (理论值 = 1/8 = 0.125)')
plt.xticks(rotation=45)
plt.grid(axis='y', alpha=0.3)
plt.show()
def phase_estimation_circuit(precision, unitary_gate):
"""创建量子相位估计电路
参数:
precision: 估计精度(量子比特数)
unitary_gate: 要估计特征值的幺正门
"""
# 总量子比特数 = 精度 + 1个目标量子比特
n_qubits = precision + 1
# 创建电路
circuit = models.Circuit(n_qubits)
# 初始化目标量子比特为特征向量
# 这里我们使用|1>作为示例
circuit.add(gates.X(precision))
# 对估计寄存器应用H门
for i in range(precision):
circuit.add(gates.H(i))
# 应用受控幺正门
for i in range(precision):
# 应用2^i次幺正门
repetitions = 2 ** i
for _ in range(repetitions):
if unitary_gate == 'T':
circuit.add(gates.CT(i, precision))
elif unitary_gate == 'S':
circuit.add(gates.CS(i, precision))
# 应用逆QFT到估计寄存器
# 首先交换比特顺序
for i in range(precision // 2):
circuit.add(gates.SWAP(i, precision - i - 1))
# 然后应用逆QFT
for i in range(precision):
circuit.add(gates.H(i))
for j in range(i + 1, precision):
circuit.add(gates.CU1(j, i, -np.pi / float(2 ** (j - i))))
return circuit
# 创建一个相位估计电路,估计T门的相位
# T门的特征值是e^(i*pi/4),相位是1/8
precision = 3
pe_circuit = phase_estimation_circuit(precision, 'T')
# 执行电路
result = pe_circuit.execute()
# 计算测量结果的概率
probabilities = result.probabilities()
# 只关注估计寄存器的结果
estimation_probs = np.zeros(2**precision)
for i in range(2**precision):
for j in range(2):
idx = i + j * (2**precision)
estimation_probs[i] += probabilities[idx]
# 显示概率分布
for i, prob in enumerate(estimation_probs):
if prob > 0.01: # 只显示概率大于1%的状态
phase = i / (2**precision)
print(f"|{i:0{precision}b}>: {prob:.4f} (相位 ≈ {phase:.4f})")
# 绘制概率分布图
plt.figure(figsize=(10, 6))
plt.bar([f"{i:0{precision}b}" for i in range(2**precision)], estimation_probs)
plt.xlabel('估计寄存器状态')
plt.ylabel('概率')
plt.title('量子相位估计: T门的相位 (理论值 = 1/8 = 0.125)')
plt.xticks(rotation=45)
plt.grid(axis='y', alpha=0.3)
plt.show()