上一章: 泡利算子
下一章: 量子态
基本概念
变分量子算法
变分量子算法(Variational Quantum Algorithm, VQA)提供了一个通用的框架,可用于解决各种各样的问题。对于一个优化问题,由一个参数化量子线路产生的可观测状态的期望值来定义损失函数,然后使用经典优化器来优化参数。量子近似优化算法(Quantum Approximate Optimization Algorithm,QAOA)和变分量子本征求解器(Variational Quantum Eigensolver,VQE)是经典的应用案例。
一个QAOA示例
参数化量子线路
参数化量子线路的酉矩阵为 \( U\left ( \theta \right ) \)。其中, \( \theta \)是可变的参数, \( U\left ( \theta \right ) \)由 \( \theta \)的实际数值与参数化量子线路中各量子门的组成方式决定。(使用QPanda3准备参数化量子线路)
参数化量子态
参数化量子态由变分量子线路作用于初始态得到(使用QPanda3获取给定参数值后的参数化量子态): \(|\psi(\theta)\rangle=U(\theta)|0\rangle^{{ }^{\otimes n}} \)
变分量子算法中的哈密顿期望
- 量子态 \( \left | \psi \right \rangle \)和哈密顿算子 \( \ H \)对应的哈密顿期望定义为: \( \langle H\rangle=\langle\psi| H|\psi\rangle \)
- 参数化量子态 \(\left | \psi \left ( \theta \right ) \right \rangle \) 和哈密顿算子 \( H \)对应的哈密顿期望为: \( \left \langle H \right \rangle = \left \langle \psi\left ( \theta \right ) \right | H \left | \psi \left ( \theta \right ) \right \rangle \)
- 变分量子线路 \( U\left ( \theta \right ) \)和哈密顿算子 \( \ H \)对应的哈密顿期望为(使用QPanda3计算哈密顿期望值): \( \left \langle H \right \rangle = \left \langle 0 \right | ^{\otimes n}U^{\dagger }\left ( \theta \right ) HU\left ( \theta \right ) \left | 0 \right \rangle ^{\otimes n}\)
变分量子算法中的梯度计算
这里以向量形式描述梯度概念(并不限制梯度只能由向量表达):
梯度是目标函数 \( \left \langle H \right \rangle \) (这里是哈密顿期望)关于参数 \( \theta \)(这里以向量形式描述)的偏导数向量(m是参数的个数)(使用QPanda3计算梯度值): \( \nabla \left \langle H \right \rangle = \left ( \frac{\nabla \left \langle H\right \rangle }{\partial \theta_{1} },\frac{\nabla \left \langle H\right \rangle }{\partial \theta_{2} },\dots ,\frac{\nabla \left \langle H\right \rangle }{\partial \theta_{m} } \right ) \)
基本使用方法
VQCircuit的API文档
一般应用流程
准备参数化量子线路
步骤
顺序 | 步骤 | QPanda3接口 |
1 | 约定参数 \( \theta \)的形式 | set_Param接口 |
2 | 设计变分量子线路 \( U\left ( \theta \right ) \)的结构 | <<运算符和append接口 |
API文档
示例代码
def get_vqc1():
vqc = VQCircuit()
vqc.set_Param([2])
p0 = vqc.Param([0],'p0')
p1 = vqc.Param([1],'p1')
e = 3.14*p0*p1+p1+4
vqc << X(0)
vqc << RX(0,3.14)
vqc << RY(0,e)
return vqc
def get_vqc2():
vqc2 = VQCircuit()
vqc2.set_Param([3])
P0 = vqc2.Param([0],'P0')
P1 = vqc2.Param([1],'P1')
P2 = vqc2.Param([2],'P2')
cir = QCircuit()
cir << Y(0)
vqc2 << cir
vqc1= get_vqc1()
vqc2.append(vqc1,[(vqc1.Param([0]),vqc2.Param([0])),(vqc1.Param([1]),vqc2.Param([1]))])
return vqc2
vqc1 = get_vqc1()
print('vqc1:')
vqc1.display_ansatz()
print()
vqc2 = get_vqc2()
print('vqc2:')
vqc2.display_ansatz()
示例代码输出结果
vqc1:
X q[0]
RX q[0],(3.14000000)
RY q[0],(((3.14*p0*p1+p1)+4))
vqc2:
Y q[0]
X q[0]
RX q[0],(3.14000000)
RY q[0],(((3.14*P0*P1+P1)+4))
- 注解
-
获取给定参数值后的参数化量子态
目标
已准备好变分量子线路 \( U\left ( \theta \right ) \)和参数 \( \theta \)的实际数值 \( \theta val \),获取 \( \left | \psi\left ( \theta val \right ) \right \rangle \)
示例代码
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2])
vqc << RX(0,vqc.Param([0]))
vqc << RY(1,vqc.Param([1]))
return vqc
def get_param_val():
param_val = [5.14,6.14]
return param_val
def get_qstate(vqc,param_val):
cir = vqc(param_val).at([0])
qvm = CPUQVM()
qvm.run(QProg(cir),1)
stv = qvm.result().get_state_vector()
return stv
vqc = get_vqc()
param_val = get_param_val()
stv = get_qstate(vqc,param_val)
print('∣ψ(θval)⟩:',stv)
示例代码输出结果
∣ψ(θval)⟩: [(0.8388860014815892+0j), 0.5395864336991233j, (-0.06016089509492038+0j), -0.03869656040878351j]
计算哈密顿期望值
目标
已准备好变分量子线路 \( U\left ( \theta \right ) \)、参数 \( \theta \)的实际数值 \( \theta val \)和哈密顿算子 \( \ H \),计算哈密顿期望值 \( \left \langle H \right \rangle \)
API文档
示例代码
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2])
vqc << RX(0,vqc.Param([0]))
vqc << RY(1,vqc.Param([1]))
return vqc
def get_param_val():
param_val = [2.14,3.14]
return param_val
def get_hamiltonian():
paulis = [
('YY', [0, 1], (12.36525580995888 + 14.85172018664403j)),
('YX', [0, 1], (12.920260765526914 + 26.29613065236354j))
]
return Hamiltonian(paulis)
def get_hamiltonian_expectation(vqc,param_val,ham):
res = vqc(param_val).expval_hamiltonian(ham,[0],used_threads=4,backend='CPU')
return res
def get_hamiltonian_expectation2(vqc:VQCircuit,param_val,ham):
res = vqc.get_gradients_and_expectation(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF).expectation_val()
return res
vqc = get_vqc()
param_val = get_param_val()
ham = get_hamiltonian()
ham_expectation = get_hamiltonian_expectation(vqc,param_val,ham)
ham_expectation2 = get_hamiltonian_expectation2(vqc,param_val,ham)
print('ham_expectation:',ham_expectation)
print('ham_expectation2:',ham_expectation2)
示例代码输出结果
ham_expectation: -0.01733304686759475
ham_expectation2: -0.01733304686759475
计算梯度值
目标
已准备好变分量子线路 \( U\left ( \theta \right ) \)、参数 \( \theta \)的实际数值 \( \theta val \)和哈密顿算子 \( \ H \),计算梯度值
API文档
- 注解
- QPanda3目前支持求梯度的参数化量子门包括RX、RY、RZ、CRX、CRY、CRZ。
示例代码
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2])
vqc << RX(0,vqc.Param([0]))
vqc << RY(1,vqc.Param([1]))
return vqc
def get_param_val():
param_val = [2.14,3.14]
return param_val
def get_hamiltonian():
paulis = [
('YY', [0, 1], (12.36525580995888 + 14.85172018664403j)),
('YX', [0, 1], (12.920260765526914 + 26.29613065236354j))
]
return Hamiltonian(paulis)
def get_gradient(vqc,param_val,ham):
return vqc.get_gradients(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
def get_gradient2(vqc:VQCircuit,param_val,ham):
return vqc.get_gradients_and_expectation(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
vqc = get_vqc()
param_val = get_param_val()
ham = get_hamiltonian()
res1 = get_gradient(vqc,param_val,ham)
res2 = get_gradient2(vqc,param_val,ham)
print('res1:',res1)
print('res1 gradient:',res1.gradients())
print('res2:',res2)
print('res2 gradient:',res2.gradients())
示例代码输出结果
res1: {gradient(double):{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
res1 gradient: [0.011090474368968659, 23.39317090007428]
res2: (gradient and expectation){"expectation":-0.017333,"gradients":{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
res2 gradient: [0.011090474368968659, 23.39317090007428]
- 注解
-
其他使用方式
矩阵或张量形式的参数θ
对应于编程语言中的2维数组或者多维数组
API文档
示例代码
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2, 2, 2])
vqc << RX(0, vqc.Param([0, 0, 0], 'P000'))
vqc << RY(0, vqc.Param([0, 0, 1], 'P001'))
vqc << RZ(1, vqc.Param([0, 1, 0], 'P010'))
vqc << RY(1, vqc.Param([0, 1, 1], 'P011'))
vqc << RX(0, vqc.Param([1, 0, 0], 'P100'))
vqc << RY(0, vqc.Param([1, 0, 1], 'P101'))
vqc << RZ(1, vqc.Param([1, 1, 0], 'P110'))
vqc << RY(1, vqc.Param([1, 1, 1], 'P111'))
return vqc
def get_param_val():
param_val = [
[
[2.00, 3.01],
[4.10, 5.11]
],
[
[20.00, 30.01],
[40.10, 50.11]
]
]
return param_val
def get_hamiltonian():
paulis = [
('YY', [0, 1], (12.36525580995888 + 14.85172018664403j)),
('YX', [0, 1], (12.920260765526914 + 26.29613065236354j))
]
return Hamiltonian(paulis)
def get_cir(vqc,param_val):
return vqc(param_val).at([0])
def get_expectation_and_gradient(vqc:VQCircuit,param_val,ham):
return vqc.get_gradients_and_expectation(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
vqc = get_vqc()
param_val = get_param_val()
ham = get_hamiltonian()
res = get_expectation_and_gradient(vqc,param_val,ham)
print('vqc:')
vqc.display_ansatz()
print('\ncir ir:\n',get_cir(vqc,param_val).originir())
print('res:',res)
print('res gradient:',res.gradients())
print('res hamiltonian expectation:',res.expectation_val())
示例代码输出结果
UserWarning: VQCircuit.get_gradients_and_expectation : The input parameter A is not a one-dimensional array.
The elements of A will be processed in row-major order.
return vqc.get_gradients_and_expectation(params=param_val,observable=ham,diff_method=DiffMethod.ADJOINT_DIFF)
vqc:
RX q[0],(P000)
RY q[0],(P001)
RZ q[1],(P010)
RY q[1],(P011)
RX q[0],(P100)
RY q[0],(P101)
RZ q[1],(P110)
RY q[1],(P111)
cir ir:
QINIT 2
CREG 1
RX q[0],(2.00000000)
RY q[0],(3.01000000)
RZ q[1],(4.10000000)
RY q[1],(5.11000000)
RX q[0],(20.00000000)
RY q[0],(30.01000000)
RZ q[1],(40.10000000)
RY q[1],(50.11000000)
res: (gradient and expectation){"expectation":-0.162402,"gradients":{Parameter.at([0]):-0.963576,Parameter.at([1]):-2.8101,Parameter.at([2]):5.12893,Parameter.at([3]):-19.6122,Parameter.at([4]):0.143741,Parameter.at([5]):-6.85959,Parameter.at([6]):-15.2735,Parameter.at([7]):6.39117}}
res gradient: [-0.9635762918972298, -2.8101035948737088, 5.128933515832114, -19.612201408718036, 0.14374054299616468, -6.859590953208836, -15.273535159436635, 6.3911729646014805]
res hamiltonian expectation: -0.16240194962603027
- 注解
- 对于矩阵(2维数组)或者张量(多维数组),QPanda3按行序处理内部数据。如果[0,1,2,3,4,5]、[[0,1],[2,3],[4,5]]和[[0,1,2],[3,4,5]]作为 \( \theta \)的值,QPanda3将打印警告信息、使用相同的方式处理它们并获得相同的结果。警告信息旨在提醒用户保证数组各维度信息的合理性。
- 这里的变分量子线路的结构以 类 OriginIR的形式呈现
参数θ元素个数的确定
- 参数 \( \theta \)元素总数与使用set_Param设置的数据形式保持一致
- 向set_Param传入的向量的元素的乘积就是参数 \( \theta \)元素的总数
- QPanda3提供了接口mutable_parameter_total来获得参数 \( \theta \)元素的总数
API文档
示例代码
vqc = VQCircuit()
vqc.set_Param([3,4,5])
res = vqc.mutable_parameter_total()
print('res:',res)
示例代码输出结果
表达式求值
支持的运算:加、乘和标量数乘
示例代码
vqc = VQCircuit()
def prepare_theta():
vqc.set_Param([3])
a = vqc.Param([0],'a')
b = vqc.Param([1],'b')
c = vqc.Param([2],'c')
return a,b,c
def get_expression(a,b,c):
return 3.14*a*b+c+4.14
def update_param_vals():
param_val = [5,6,7]
vqc(param_val)
def get_expression_val():
d.calculate_expression_val()
return d.get_expression_val()
a,b,c = prepare_theta()
d = get_expression(a,b,c)
update_param_vals()
d_val = get_expression_val()
print('d:',d)
print('val of d:',d_val)
示例代码输出结果
d: ((3.14*a*b+c)+4.14)
val of d: 105.34
梯度计算与哈密顿期望计算的其它接口
序号 | 接口 | 说明 | API |
1 | def get_gradients(self, params: numpy.ndarray[numpy.float64], observable, diff_method: DiffMethod) | 提供参数向量 \( \theta \)的一组数值,计算一组参数值对应的梯度值和一个哈密顿期望值 | 文档 |
2 | def get_gradients(self, params: numpy.ndarray[numpy.float64], observable, param_group_total: int, diff_method: DiffMethod) | 提供参数向量 \( \theta \)的param_group_total组数值,计算param_group_total组参数值对应的param_group_total组梯度值 | 文档 |
3 | def get_gradients_and_expectation(self, params: numpy.ndarray[numpy.float64], observable, diff_method: DiffMethod) | 提供参数向量 \( \theta \)的一组数值,计算一组参数值对应的一组梯度值和一个哈密顿期望值 | 文档 |
4 | def get_gradients_and_expectation(self, params: numpy.ndarray[numpy.float64], observable, param_group_total: int, diff_method: DiffMethod) | 提供参数向量 \( \theta \)的param_group_total组数值,计算param_group_total组参数值对应的param_group_total组梯度值和param_group_total个哈密顿期望值 | 文档 |
示例代码
def get_vqc():
vqc = VQCircuit()
vqc.set_Param([2])
vqc << RX(0,vqc.Param([0]))
vqc << RY(1,vqc.Param([1]))
return vqc
def get_hamiltonian():
paulis = [
('YY', [0, 1], (12.36525580995888 + 14.85172018664403j)),
('YX', [0, 1], (12.920260765526914 + 26.29613065236354j))
]
return Hamiltonian(paulis)
def fun1(vqc,ham):
param_val = [2.14, 3.14]
pq3_res1 = vqc.get_gradients(param_val, ham, DiffMethod.ADJOINT_DIFF)
print('pq3_res1:',pq3_res1)
print('pq3_res1.gradients():', pq3_res1.gradients())
print()
def fun2(vqc,ham):
param_val = [2.14, 3.14,4.14,5.14]
pq3_res2 = vqc.get_gradients(param_val, ham,param_group_total=2,diff_method= DiffMethod.ADJOINT_DIFF)
print('pq3_res2:', pq3_res2)
print('pq3_res2.data():',pq3_res2.data())
print()
def fun3(vqc,ham):
param_val = [2.14, 3.14]
pq3_res3 = vqc.get_gradients_and_expectation(param_val,ham,diff_method=DiffMethod.ADJOINT_DIFF)
print('pq3_res3:',pq3_res3)
print('pq3_res3.data():',pq3_res3.data())
print('pq3_res3.gradients():', pq3_res3.gradients())
print('pq3_res3.expectation_val():', pq3_res3.expectation_val())
print()
def fun4(vqc,ham):
param_val = [2.14, 3.14,4.14, 5.14]
pq3_res4 = vqc.get_gradients_and_expectation(param_val, ham, param_group_total=2,diff_method=DiffMethod.ADJOINT_DIFF)
print('pq3_res4:', pq3_res4)
print('pq3_res4.data():', pq3_res4.data())
print()
vqc = get_vqc()
ham = get_hamiltonian()
fun1(vqc,ham)
fun2(vqc,ham)
fun3(vqc,ham)
fun4(vqc,ham)
示例代码输出结果
pq3_res1: {gradient(double):{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
pq3_res1.gradients(): [0.011090474368968659, 23.39317090007428]
pq3_res2: (gradient(double)):[{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932},{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}]
pq3_res2.data(): [[0.011090474368968659, 23.39317090007428], [0.011090474368968659, 23.39317090007428]]
pq3_res3: (gradient and expectation){"expectation":-0.017333,"gradients":{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}
pq3_res3.data(): (-0.01733304686759475, [0.011090474368968659, 23.39317090007428])
pq3_res3.gradients(): [0.011090474368968659, 23.39317090007428]
pq3_res3.expectation_val(): -0.01733304686759475
pq3_res4: ((gradient and expectation)):[{"expectation":-0.017333,"gradients":{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}},{"expectation":-0.017333,"gradients":{Parameter.at([0]):0.0110905,Parameter.at([1]):23.3932}}]
pq3_res4.data(): [(-0.01733304686759475, [0.011090474368968659, 23.39317090007428]), (-0.01733304686759475, [0.011090474368968659, 23.39317090007428])]
在VQA中应用
一个QAOA示例
此示例代码要解决的组合优化问题是最大切割问题[5]:给定一张图,图上有N个顶点,给每个顶点标注0/1,使得对边的切割最大(边的切割指的是,如果一条边的顶点标注不同就算切割)
示例代码
from pyqpanda3.core import H, RZ, T, RX, RY,CNOT,S,X,I,QCircuit, QProg, CPUQVM
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import matplotlib
matplotlib.use('TkAgg')
def generate_random_graph(n):
g = nx.random_regular_graph(4, n)
for u, v in g.edges:
g[u][v]['weight'] = np.random.uniform(-1, 1)
return g
def test_qaoa():
"""
<1>QAOA 的核心思想是通过在量子计算机上准备一个参数化的量子态,然后利用经典优化算法调整这些参数,使得量子态的测量结果能够以较高的概率对应于组合优化问题的近似最优解
<2>参数化量子态可以由参数化量子线路作用在初态上得到
<3> 此代码要解决的优化问题是:给定一张图,图上有N个顶点,给每个顶点标注0/1,使得对边的切割最大(边的切割指的是,如果一条边的顶点标注不同就算切割)
"""
def generate_ham(g):
ham_list = []
n = len(g.nodes)
for u, v in g.edges:
pauli_string = ['I'] * n
pauli_string[u] = 'Z'
pauli_string[v] = 'Z'
ham_list.append((''.join(pauli_string), list(range(n)), g.edges[u, v].get('weight', -1)))
return Hamiltonian(ham_list)
def generate_qaoa_circuit(g, layers):
n = len(g.nodes)
cir = VQCircuit()
cir.set_Param([layers, 2])
for i in range(n):
cir << H(i)
for layer in range(layers):
for edge in g.edges:
q0, q1 = edge
weight = g.edges[edge].get('weight', 1)
cir << CNOT(q0, q1) << RZ(q1, -2 * cir.Param([layer, 0]) * weight) << CNOT(q0, q1)
for q in g.nodes:
cir << RX(q, 2 * cir.Param([layer, 1]))
return cir
def optimize_params(vqc,ham):
x0 = np.random.random(vqc.mutable_parameter_total())
def get_expectation_and_grad(params, vqc, ham):
params = np.reshape(params, vqc.get_Param_dims())
exp_and_grad = vqc.get_gradients_and_expectation(params, ham, diff_method=DiffMethod.ADJOINT_DIFF)
return exp_and_grad.data()
from scipy.optimize import minimize
final_res = minimize(get_expectation_and_grad, x0, args=(vqc, ham), jac=True)
""" 代码说明
(1)scipy.optimize.minimize简介
①函数签名
scipy.optimize.minimize(fun, x0, args=(), method=None, jac=None, hess=None, hessp=None, bounds=None, constraints=(), tol=None, callback=None, options=None)
②参数说明
fun: 要最小化的目标函数。它应该接受一个数组作为输入,并返回一个标量值。
x0: 初始猜测值,是一个数组,表示优化变量的初始值。
args: 传递给目标函数和梯度函数的额外参数,以元组形式传递。
method: 优化算法的字符串标识符。默认是 'BFGS',但也可以选择其他算法,如 'Nelder-Mead'、'Powell'、'CG'、'Newton-CG'、'L-BFGS-B'、'TNC'、'COBYLA'、'SLSQP' 等。
jac: 目标函数的梯度。如果 jac 是一个布尔值且为 True,则假定 fun 返回的元组中包含梯度。如果 jac 是一个可调用对象,则它应该返回梯度。
③返回值
scipy.optimize.minimize
<1>函数的返回值是一个OptimizeResult 对象,它包含了优化过程的详细信息以及最终结果
<2>关键属性
1> 其属性x存储了优化后的参数值
2> success:一个布尔值,True 表示优化成功,False 表示优化失败
3> status:一个整数,表示优化器的终止状态。不同的优化算法可能有不同的状态码。0 通常表示成功,其他值可能表示不同的失败原因。
4> fun:优化后的目标函数值,即 fun(x) 的值。
5> message:一个字符串,描述优化器的终止消息。
6> nfev:目标函数的评估次数。
7> nit:优化器的迭代次数。
8> jac:优化结束时的梯度值(如果提供或计算了梯度)。
9> hess_inv: 优化结束时的 Hessian 矩阵的逆矩阵(如果提供或计算了 Hessian 矩阵)。
(2)final_res = minimize(get_expectation_and_grad, x0, args=(cir, ham), jac=True)
get_expectation_and_grad:该函数根据输入的参数(一维数组)计算得到哈密顿(相应的哈密顿量算子由args=(vqc,ham)中的ham指定)期望值(对应要返回的标量值)和梯度值(对应参数jac=True)
x0: 参数的初值,与get_expectation_and_grad要求的数组大小相同(由函数get_expectation_and_grad使用的变分量子线路(对应args=(vqc,ham)中的vqc)决定))
args=(vqc,ham):get_expectation_and_grad的入参分别为可变参数的数值、变分量子线路和哈密顿算子,vqc和ham分别对应变分量子线路和哈密顿算子
jac=True: 函数get_expectation_and_grad会返回梯度值
"""
return vqc(final_res.x.reshape((layers, 2))).at([0])
def measure_and_sample(cir):
prog = QProg()
prog <<cir
machine = CPUQVM()
machine.run(prog, shots=1000)
final_measure = machine.result().get_prob_dict()
return final_measure
def post_process(measure_res):
final_measure = sorted(measure_res.items(), key=lambda i: i[1], reverse=True)[:10]
labels = dict(zip(sorted(g.nodes), [i for i in final_measure[0][0][::-1]]))
nx.set_node_attributes(g, labels, 'label')
plt.figure(figsize=(8, 6))
pos = nx.spring_layout(g, seed=42)
nx.draw_networkx_nodes(g, pos, node_color='lightblue', node_size=500)
nx.draw_networkx_edges(g, pos, edge_color='gray', width=1.5)
node_labels = nx.get_node_attributes(g, 'label')
nx.draw_networkx_labels(g, pos, labels=node_labels, font_color='darkred', font_size=12)
edge_labels = {k: round(v, 3) for k, v in nx.get_edge_attributes(g, 'weight').items()}
nx.draw_networkx_edge_labels(g, pos, edge_labels=edge_labels, font_color='green')
plt.axis('off')
plt.show(block=True)
n = 8
layers = 3
g = generate_random_graph(n)
ham = generate_ham(g)
vqc = generate_qaoa_circuit(g, layers)
circuit = optimize_params(vqc, ham)
measure_res = measure_and_sample(circuit)
post_process(measure_res)
if __name__ == '__main__':
test_qaoa()
示例代码输出结果
qaoa
- 注解
- 上述代码中图的拓扑结构是随机生成的,因此代码运行的结果是不一样的。上述图片只用于展示程序运行的效果。
参考文献
[1] Cerezo M, Arrasmith A, Babbush R, et al. Variational quantum algorithms[J]. Nature Reviews Physics, 2021, 3(9): 625-644.
[2] Baydin A G, Pearlmutter B A, Radul A A, et al. Automatic differentiation in machine learning: a survey[J]. Journal of machine learning research, 2018, 18(153): 1-43.
[3] Jones T, Gacon J. Efficient calculation of gradients in classical simulations of variational quantum algorithms[J]. arXiv preprint arXiv:2009.02823, 2020.
[4] Luo X Z, Liu J G, Zhang P, et al. Yao. jl: Extensible, efficient framework for quantum algorithm design[J]. Quantum, 2020, 4: 341.
[5] Original Quantum. QAOA算法[EB/OL]. https://quantum-book-by-originq.readthedocs.io/en/latest/rst/4.5QAOA算法.html