跳转至

手算检查 QUBO 到 Hamiltonian 的映射

把一个两变量二进制目标转换为 Pauli 算符,并逐一检查四个计算基态。请先完成图问题和Hamiltonian 与可观测量,在安装好的环境中从仓库根目录运行。

我们要最小化的目标为:

f(x0, x1) = 0.1 − x0 − 0.5 x1 + 1.25 x0 x1
x0, x1 ∈ {0, 1}

正的二次项使同时选择两个变量更贵。它是目标函数的一部分;通用 QUBO 不会另外将这种选择标为不满足约束。图问题转换为 MIS 时,才会附带相应的约束解释。

先确认正负号约定

经典变量转换使用 x = (1+s)/2,其中 s ∈ {−1,+1}。投影到 Pauli 算符时使用 s = −Z。两步合起来是 x = (I−Z)/2,因此计算基 0 对应 x=0,1 对应 x=1。

代入并展开可得:

H = −0.3375 I + 0.1875 Z0 − 0.0625 Z1 + 0.3125 Z0 Z1

常数项不会改变哪个状态使能量最小,但会影响报告中的能量值。这里的系数表示优化目标的数值,尚未指定如何换算成物理频率 rad/us 或硬件脉冲幅度。

"""把带类型的 QUBO 问题投影为 Pauli cost Hamiltonian。

投影结果保留变量顺序、offset、各项系数和来源标识,可直接作为 QAOA 或 VQE 的
cost operator。本例不运行优化器,也不包含硬件 embedding。
"""

from __future__ import annotations

import json

from cascaqit.algorithms import problem_to_pauli_hamiltonian
from cascaqit.problems import QUBOProblemIR, evaluate_qubo_bitstring


def main() -> None:
    """构建一个 QUBO、完成投影,并评估一个已知 bitstring。"""
    problem = QUBOProblemIR.from_terms(
        problem_id="lesson.optimization.qubo",
        variables=("x0", "x1"),
        linear_terms={"x0": -1.0, "x1": -0.5},
        quadratic_terms={("x0", "x1"): 1.25},
        offset=0.1,
    )
    hamiltonian = problem_to_pauli_hamiltonian(problem)

    payload = {
        "track": "optimization_researcher",
        "level": "foundation",
        "lesson": "qubo_hamiltonian",
        "facts": {
            "variables": list(problem.variables),
            "pauli_coefficients": {
                term.observable.name: term.coefficient for term in hamiltonian.terms
            },
            "basis_objectives": {
                bits: evaluate_qubo_bitstring(problem, bits)
                for bits in ("00", "01", "10", "11")
            },
            "term_count": len(hamiltonian.terms),
            "hamiltonian_offset": hamiltonian.constant,
            "candidate_10_value": evaluate_qubo_bitstring(problem, "10"),
            "source_hash_present": len(problem.stable_hash()) == 64,
        },
        "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/02_foundation_qubo_hamiltonian_zh.py
{
  "boundaries": {
    "cloud_execution": false,
    "credentials_loaded": false,
    "hardware_execution": false,
    "network_accessed": false
  },
  "facts": {
    "basis_objectives": {
      "00": 0.1,
      "01": -0.4,
      "10": -0.9,
      "11": -0.1499999999999999
    },
    "candidate_10_value": -0.9,
    "hamiltonian_offset": -0.3375,
    "pauli_coefficients": {
      "Z(x0)": 0.1875,
      "Z(x0)*Z(x1)": 0.3125,
      "Z(x1)": -0.0625
    },
    "source_hash_present": true,
    "term_count": 3,
    "variables": [
      "x0",
      "x1"
    ]
  },
  "lesson": "qubo_hamiltonian",
  "level": "foundation",
  "track": "optimization_researcher"
}

按 variables 的顺序读取比特串,第一个字符表示 x0。

比特串 二进制目标值 Hamiltonian 基态能量
00 0.1 0.1
01 −0.4 −0.4
10 −0.9 −0.9
11 −0.15 −0.15

最小值对应 10。脚本同时输出全部基态目标值和 Pauli 系数,可以在运行优化器之前检查映射。源码哈希用于标识所用问题,不能单独证明转换正确。本课不会执行优化、采样或硬件嵌入。

修改代价,再检查结果

  1. 只把常数偏移从 0.1 改为 0.6。表格、算符和最优比特串分别怎样变化?
  2. 移除二次项,哪个比特串会成为最优解?
  3. 用 Z0=-1、Z1=+1 计算 10 的能量,再反转两者符号。第二次实际算的是哪个比特串?

常数偏移使所有值和 Hamiltonian 常数项都增加 0.5,最优比特串仍是 10。去掉成对代价后,11 的值为 −1.4,成为最优解。原算符在 10 上的能量为 −0.9;反转符号实际计算了 01,得到 −0.4。位序或编码出错时,结果仍可能看起来合理,却已经在求另一个问题。

下一课运行 QAOA,观察优化器如何使用这个代价算符。

English version

SDK 1.0.8a · `6eff6362`