在Qiskit中从已完成的真实量子计算机作业获取QAOA优化结果属性
解决Qiskit QAOA真实设备运行后无法获取优化结果(res.x/fun)的问题
问题原因
- 真实量子设备的作业是异步远程执行的,运行速度远慢于模拟器,若优化过程中脚本中断(比如超时、连接断开),
minimize函数无法正常完成迭代,导致res变量未被定义。 job.result()仅返回量子计算的原始结果,而res.x、res.fun是经典优化器(COBYLA)的输出,这些数据不会自动存储在量子作业中——因为优化迭代的逻辑是在本地经典环境执行的,量子作业仅负责每一轮的采样计算。
解决方案
1. 提前保存优化过程状态(避免丢失res)
在运行minimize时,通过回调函数实时保存每一轮迭代的参数和对应的cost值,同时持久化到本地文件,防止脚本中断导致数据丢失。
示例代码:
import json from scipy.optimize import minimize # 存储优化过程的列表 optimization_history = [] def qaoa_callback(xk): # 计算当前参数对应的cost值 current_cost = cost_func(xk, ansatz, hamiltonian, estimator) # 记录参数和cost optimization_history.append({ "params": xk.tolist(), "cost": current_cost }) # 保存到本地文件 with open("qaoa_optimization_history.json", "w") as f: json.dump(optimization_history, f) # 运行优化时添加回调参数 res = minimize( cost_func, x0, args=(ansatz, hamiltonian, estimator), method="COBYLA", callback=qaoa_callback )
之后即使脚本中断,也可以从qaoa_optimization_history.json文件中读取所有迭代数据,找到最优参数。
2. 从已完成的作业中恢复优化数据
如果已经出现res未定义的情况,需要从已提交的量子作业中反向推导优化结果,前提是你在提交作业时给作业添加了元数据(保存对应迭代的参数)。
步骤1:提交作业时添加元数据
修改你的cost_func,在提交量子作业时,将当前迭代的参数存入作业元数据:
def cost_func(params, ansatz, hamiltonian, estimator): bound_ansatz = ansatz.bind_parameters(params) # 提交作业并添加元数据,保存当前参数 job = estimator.run(bound_ansatz, hamiltonian, shots=1024) job.update_metadata({"qaoa_params": params.tolist()}) # 获取计算结果并返回cost result = job.result() return result.values[0]
步骤2:筛选并提取作业数据
通过IBM Provider获取所有已完成的QAOA相关作业,提取元数据中的参数和计算得到的cost:
from qiskit_ibm_provider import IBMProvider provider = IBMProvider() # 获取账号下最近的作业,按创建时间倒序 all_jobs = provider.jobs(limit=100, sort_by='creation_date', descending=True) # 筛选QAOA相关作业(可根据你给作业的命名调整筛选条件) qaoa_jobs = [job for job in all_jobs if job.status().name == 'DONE' and "qaoa" in job.name()] # 收集参数和对应的cost值 optimization_data = [] for job in qaoa_jobs: metadata = job.metadata() params = metadata.get("qaoa_params") if params is None: continue # 跳过未保存参数的作业 result = job.result() cost = result.values[0] optimization_data.append({ "params": params, "cost": cost })
步骤3:找到最优结果
从收集到的数据中筛选出cost最小的条目,对应的参数就是res.x,cost值就是res.fun:
if optimization_data: # 按cost从小到大排序,取第一个 optimization_data.sort(key=lambda item: item["cost"]) best_result = optimization_data[0] best_x = best_result["params"] best_fun = best_result["cost"] print(f"最优参数: {best_x}") print(f"最小cost值: {best_fun}") else: print("未找到包含QAOA参数的已完成作业")
3. 避免脚本中断的建议
- 运行真实设备的优化任务时,使用后台进程执行(如Linux的
nohup命令),避免终端断开导致脚本终止。 - 优化过程中增加日志输出,实时监控迭代进度和作业状态。
内容的提问来源于stack exchange,提问作者Jane G
相关产品推荐
相关产品推荐

