从目标求值到最终采样,读懂一次 QAOA¶
对图问题中的三节点路径运行一层 QAOA。先阅读 QUBO 映射,使用安装好的环境。本例的求值预算很小,用于观察流程,不用于展示收敛表现。
按 (a,b,c) 读取比特,最小化的代价为 f(x) = −(xa + xb + xc) + 2(xa xb + xb xc)。独立集 101 的值为 −2。三个节点全选得到 −3 + 2×2 = 1,同时违反约束。过低的罚系数可能使无效集合更有利,因此图接口会要求合适的罚系数。
层数、求值次数和采样次数各指什么¶
QAOA 从等幅叠加态开始,交替施加由 γ 控制的代价演化和由 β 控制的 X 混合操作。一层有两个参数,initial_parameters=(0.2, -0.3) 依次提供 γ 和 β。一层不等于求值一次:优化器会尝试多组参数。
"""针对小型 MIS 问题运行完整的本地 QAOA 流程。
程序完成问题投影、ansatz 构造、Backend objective evaluation、SciPy 优化、最终
采样和候选解码,并给出有界的经典比较。该比较只适用于当前小问题,不证明全局最优。
"""
from __future__ import annotations
import json
from cascaqit import QAOA, GraphProblemIR, LocalBackend, OptimizerConfig
def main() -> None:
"""使用固定输入优化并采样一个三节点路径图。"""
graph = GraphProblemIR.from_edges(
problem_id="lesson.optimization.qaoa",
positions={"a": (0.0, 0.0), "b": (5.0, 0.0), "c": (10.0, 0.0)},
edges=(("a", "b"), ("b", "c")),
)
result = QAOA(graph, layers=1, mis_penalty=2.0).run(
backend=LocalBackend(seed=501),
optimizer=OptimizerConfig(
method="COBYLA", max_iterations=8, max_evaluations=5, seed=501
),
initial_parameters=(0.2, -0.3),
final_shots=64,
)
candidate = result.best_observed_candidate
baseline = result.baseline
assert candidate is not None and baseline is not None
assert result.final_result is not None
payload = {
"track": "optimization_researcher",
"level": "applied",
"lesson": "qaoa_workflow",
"facts": {
"objective_estimator": result.metadata["objective_estimator"],
"objective_total_shots": result.metadata["objective_total_shots"],
"workflow_total_shots": result.metadata["workflow_total_shots"],
"backend_executions": result.metadata["workflow_backend_execution_count"],
"final_counts": result.final_result.counts,
"final_probabilities": result.final_result.probabilities,
"candidate_count": candidate.count,
"best_energy": round(result.best_evaluation.energy, 10),
"candidate_value": candidate.objective_value,
"termination_reason": result.termination.reason,
"evaluations": len(result.evaluations),
"counts_total": sum(result.final_result.counts.values()),
"candidate_bitstring": candidate.bitstring,
"candidate_feasible": candidate.feasible,
"baseline_value": baseline.objective_value,
"optimality_claim": candidate.optimality_claim,
},
"boundaries": {
"hardware_execution": False,
"cloud_execution": False,
"network_accessed": False,
"credentials_loaded": False,
},
}
print(json.dumps(payload, sort_keys=True))
if __name__ == "__main__":
main()
python3 examples/user/tracks/optimization_researcher/03_applied_qaoa_workflow_zh.py
配置最多允许五次目标求值,之后在选定参数处单独执行 64 次最终采样。max_iterations=8 不会覆盖 max_evaluations=5。查看停止原因,才能知道实际由哪个条件结束优化。
{
"boundaries": {
"cloud_execution": false,
"credentials_loaded": false,
"hardware_execution": false,
"network_accessed": false
},
"facts": {
"backend_executions": 6,
"baseline_value": -2.0,
"best_energy": -1.0259301196,
"candidate_bitstring": "101",
"candidate_count": 14,
"candidate_feasible": true,
"candidate_value": -2.0,
"counts_total": 64,
"evaluations": 5,
"final_counts": {
"001": 9,
"010": 21,
"011": 4,
"100": 3,
"101": 14,
"110": 2,
"111": 11
},
"final_probabilities": {
"000": 0.006485865446572203,
"001": 0.13794438752156066,
"010": 0.31275386143691747,
"011": 0.04281588559494963,
"100": 0.13794438752156063,
"101": 0.2521757366567452,
"110": 0.042815885594949664,
"111": 0.06706399022674457
},
"objective_estimator": "exact_state",
"objective_total_shots": 0,
"optimality_claim": "not_claimed",
"termination_reason": "max_evaluations",
"workflow_total_shots": 64
},
"lesson": "qaoa_workflow",
"level": "applied",
"track": "optimization_researcher"
}
求值方式为 exact_state,且 objective_total_shots 为零,表示优化器直接读取模拟状态的期望值。final_shots=64 影响单独的最终采样,不影响这些期望值的精度。每次状态演化仍然消耗 CPU。
best_energy 是对所有可能比特串的期望值。candidate_bitstring 是最终计数中实际出现过、代价最低的比特串,不一定是出现次数最多的那个。candidate_feasible 检查图约束。经典基准穷举这个小问题,找到值为 −2 的 101。
即使最佳期望值还高于 −2、停止原因为 max_evaluations,最终采样仍可能碰到最优候选。得到一次好样本,并不说明分布已经集中到最优解,也不说明优化器收敛。SDK 在候选的最优性字段上保留 not_claimed。
改变预算并解释影响¶
- 保持优化配置不变,只把
final_shots提高到 1024,哪些输出可能变化? - 改为两层,却仍提供两个初始参数。解释输入错误,再尝试四元素向量。
- 从计数计算
101的频率,以及所有可行集合的总频率。它们与期望能量有什么区别?
增加最终采样会改变采样成本和计数,本例精确求值的优化计算不变。两层需要四个参数,同时要调整 COBYLA 预算:最低求值次数为 参数数目 + 2,四个参数不能继续只给五次。可行串为 000、001、010、100、101,只有 101 最优。可行率、最优解频率和平均代价回答的是不同问题。