量子启发式算法结合自动调参工具

下载Notebook下载样例代码在Gitee上查看源文件

量子启发式算法

量子启发式算法是一类基于量子力学原理的计算方法衍生或启发的经典力学方法,旨在利用量子力学的独特性质(叠加态、量子纠缠和量子并行性)来改进传统算法的性能。比较有名的是Ewin tang受HHL启发提出的算法,但目前没有实用场景。为了便于区分,我们把受量子退火或者模拟量子Ising机,称为量子退火启发式算法。研究这类算法的意义在于不断探索经典算法的上界;其次可以对现实问题进行建模,使其能够被量子算法或者量子启发式算法进行求解,并且后续可以用QPU来代替启发式算法进行加速。

常见的量子启发式算法包括:

  • ASB(Adiabatic Simulated bifurcation/绝热模拟分叉算法)

  • BSB(Ballistic Simulated bifurcation/弹道模拟分叉算法)

  • DSB(Discrete Simulated bifurcation/离散模拟分叉算法)

  • SimCIM(Simulated Coherent Ising Machine/模拟相干伊辛机算法)

  • LQA(Local Quantum Annealing/局部量子退火算法)

MindQuantum是基于昇思MindSpore开源深度学习平台开发的新一代通用量子计算框架,聚焦于NISQ阶段的算法实现与落地。结合HiQ高性能量子计算模拟器和昇思MindSpore并行自动微分能力,提供极简的开发模式和极致的性能体验。

MindQuantum已经集成量子启发式算法模块,并提供CPU、GPU、NUP/昇腾版本,适配多种硬件设备,并提供极致性能。

BSB/绝热模拟分叉算法为例,介绍量子启发式算法中参数定义:

  • J (Union[numpy.array, scipy.sparse.spmatrix]) - 耦合矩阵,维度为(N*N);与求解的图、ising或qubo问题相关。

  • h (numpy.array) - 外场强度,维度为(N,)。

  • x (numpy.array) - 自旋初始化配置,维度为(N*batch_size)。会在优化过程中被修改。如果不提供(None),将被初始化为在 [-0.01, 0.01] 范围内均匀分布的随机值。默认值:None。

  • n_iter (int) - 迭代步数。默认值: 1000。

  • batch_size (int) - 样本个数。默认值: 1。

  • dt (float) - 迭代步长。默认值: 1。

  • xi (float) - 频率维数,正的常数。默认值: None。

  • backend (str) - 计算后端和精度:’cpu-float32’、’gpu-float16’或’gpu-int8’,默认值: ‘cpu-float32’,适配CPU/GPU不同的硬件设备。

可优化参数:

  • n_iter迭代步数表示迭代计算的步数,根据具体问题来设置,迭代步数越大,越容易收敛,求解效果越好,但是计算时间越长,可调参数。

  • batch_size样本个数,MindQuantum.qaia模块通过矩阵升维,提供并行化能力,样本个数越大,解的规模越大,计算时间越长,可调参数。

  • dt迭代步长,控制每次动力学演化的步长距离,迭代步长直接影响到算法收敛的速度和稳定性;如果dt太大,可能会导致算法发散或不稳定;如果dt太小,则算法收敛速度会较慢,可调参数。

  • xi频率维数,用于调整算法在频率空间上的特性,可调参数。

综合考虑算法的稳定性、收敛速度、问题特性以及算法背景等因素,选择合适的参数(n_iter、batch_size、dt、xi)。

通常选取一组较好的参数组合需要大规模运行实验,耗费大量时间和人力,自动化调参工具便应运而生。

自动调参工具Optuna和Hyperopt

目前业界使用最广泛的python调参工具是Optuna和Hyperopt,可以使用网格搜索等方法自动化得到目标函数的最佳结果。

Optuna

Optuna 是一个开源超参数优化框架,由Preferred Networks开发,适合机器学习和深度学习,并逐步适配LLM大模型。相比传统的网格搜索Grid Search,Optuna使用贝叶斯优化等算法,能够更高效地找到最优参数组合

主要特点

  • 大规模搜索空间,支持多种参数类型(连续、离散、分类)

  • 先进高效的参数搜索算法

  • 提供可视化和并行优化能力

  • 支持对接PyTorch和TensorFlow等深度学习框架

常用API

  • Trial: 目标函数的单次调用

  • Study: 一次优化过程,包含一系列的 trials.

  • Parameter: 待优化的参数

Optuna官网:https://optuna.org/

安装命令,通过pip安装,支持Python 3.8或更高版本

pip install optuna
[1]:
# 代码样例

import optuna


# 定义需要优化的函数objective,最小化 (x-2)^2
def objective(trial):
    # 定义超参数x,数据类型为浮点数,范围是-10~10
    x = trial.suggest_float("x", -10, 10)
    return (x - 2) ** 2


# 创建study对象并调用30次
study = optuna.create_study()
study.optimize(objective, n_trials=30)


# 打印输出最佳参数
print("Best parameters:", study.best_params)
[I 2025-06-16 10:21:16,981] A new study created in memory with name: no-name-bb7d4a88-3012-401d-b020-06f0b7e63c1a
[I 2025-06-16 10:21:16,986] Trial 0 finished with value: 1.2332747669303585 and parameters: {'x': 0.8894709517845296}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,988] Trial 1 finished with value: 20.69100702532007 and parameters: {'x': 6.548736860417414}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,989] Trial 2 finished with value: 46.24728562544997 and parameters: {'x': 8.80053568665366}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,993] Trial 3 finished with value: 5.213333943630706 and parameters: {'x': -0.2832726389178113}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,995] Trial 4 finished with value: 85.54920023745696 and parameters: {'x': -7.249281065977882}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,995] Trial 5 finished with value: 10.244278172158554 and parameters: {'x': 5.200668394594878}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,997] Trial 6 finished with value: 31.17835152655691 and parameters: {'x': 7.5837578320121395}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,998] Trial 7 finished with value: 6.291002799247192 and parameters: {'x': -0.5081871539514733}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:16,999] Trial 8 finished with value: 21.702051777680936 and parameters: {'x': 6.658546101272471}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:17,000] Trial 9 finished with value: 60.059339007965605 and parameters: {'x': -5.7497960623467765}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:17,015] Trial 10 finished with value: 33.600981819914715 and parameters: {'x': -3.796635387870684}. Best is trial 0 with value: 1.2332747669303585.
[I 2025-06-16 10:21:17,025] Trial 11 finished with value: 0.8505643479802889 and parameters: {'x': 1.0777395443909086}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,033] Trial 12 finished with value: 0.9492117372189054 and parameters: {'x': 2.9742749802899104}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,039] Trial 13 finished with value: 1.088651567539649 and parameters: {'x': 3.0433846690169686}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,044] Trial 14 finished with value: 1.2990109251546207 and parameters: {'x': 3.139741604555445}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,055] Trial 15 finished with value: 25.721224363705996 and parameters: {'x': -3.0716096422837986}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,062] Trial 16 finished with value: 1.421723384219888 and parameters: {'x': 3.192360425467018}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,067] Trial 17 finished with value: 131.1684799164624 and parameters: {'x': -9.452880856643118}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,078] Trial 18 finished with value: 16.982720180776216 and parameters: {'x': -2.1210096069745115}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,087] Trial 19 finished with value: 63.354308243994815 and parameters: {'x': 9.959541961946982}. Best is trial 11 with value: 0.8505643479802889.
[I 2025-06-16 10:21:17,095] Trial 20 finished with value: 0.6002035355880134 and parameters: {'x': 1.2252719602415223}. Best is trial 20 with value: 0.6002035355880134.
[I 2025-06-16 10:21:17,103] Trial 21 finished with value: 0.160193332718854 and parameters: {'x': 1.599758407060368}. Best is trial 21 with value: 0.160193332718854.
[I 2025-06-16 10:21:17,113] Trial 22 finished with value: 0.14097107919717228 and parameters: {'x': 1.6245388446228128}. Best is trial 22 with value: 0.14097107919717228.
[I 2025-06-16 10:21:17,120] Trial 23 finished with value: 13.31927509952413 and parameters: {'x': -1.6495582060742817}. Best is trial 22 with value: 0.14097107919717228.
[I 2025-06-16 10:21:17,131] Trial 24 finished with value: 9.565104190348324 and parameters: {'x': 5.092750263171652}. Best is trial 22 with value: 0.14097107919717228.
[I 2025-06-16 10:21:17,137] Trial 25 finished with value: 0.440523307624899 and parameters: {'x': 1.3362807011809141}. Best is trial 22 with value: 0.14097107919717228.
[I 2025-06-16 10:21:17,146] Trial 26 finished with value: 0.0027116800107364622 and parameters: {'x': 1.9479262061038716}. Best is trial 26 with value: 0.0027116800107364622.
[I 2025-06-16 10:21:17,153] Trial 27 finished with value: 6.359825958163664 and parameters: {'x': 4.521869536309058}. Best is trial 26 with value: 0.0027116800107364622.
[I 2025-06-16 10:21:17,162] Trial 28 finished with value: 10.430425338027106 and parameters: {'x': -1.2296169026723751}. Best is trial 26 with value: 0.0027116800107364622.
[I 2025-06-16 10:21:17,168] Trial 29 finished with value: 0.006421219245358646 and parameters: {'x': 2.0801325105394723}. Best is trial 26 with value: 0.0027116800107364622.
Best parameters: {'x': 1.9479262061038716}

Hyperopt

Hyperopt是一个用于超参数优化的框架,由James Bergstra开发的分布式优化库,基于贝叶斯优化(Tree-structured Parzen Estimator,TPE)算法,能够高效搜索算法的最佳参数组合。

主要特点:

  • 提供多种优化算法,随机搜索、Parzen估计器树TPE、自适应TPE等

  • 支持Spark和MongoDB分布式计算

Hyperopt官网:https://hyperopt.github.io/hyperopt/

安装命令

pip install hyperopt
[2]:
# 代码样例
from hyperopt import fmin, tpe, hp, Trials


# 定义目标函数,最小化(x-2)^2
def objective(params):
    x = params["x"]
    return (x - 2) ** 2


# 定义搜索空间,超参数x,数据类型浮点数,是范围是-10~10
space = {"x": hp.uniform("x", -10, 10)}

# 优化30次
trials = Trials()
best = fmin(fn=objective, space=space, algo=tpe.suggest, max_evals=30, trials=trials)

print("Best parameters:", best)
100%|██████████| 30/30 [00:00<00:00, 895.79trial/s, best loss: 0.05078371223984796]
Best parameters: {'x': 1.7746475821300158}

Optuna对比Hyperopt

Optuna和Hyperopt两个自动调参框架都支持主流的贝叶斯优化等参数搜索算法。其中Optuna提供可视化功能,原生支持并行多进程,属于后起之秀;Hyperopt并行化对接MongoDB数据库,适合中小规模的参数搜索任务。

综上所述,我们使用量子启发式算法结合Optuna调参框架,求解图最大割问题。

最佳实践

我们结合量子启发式算法和调参框架Optuna,面向GSet图计算最大割MAXCUT,找到最优参数组合。

工作流:

  • 数据准备,此处以GSet图为例。

  • 数据处理,将图转化为MindQuantum.qaia启发式算法中稀疏化矩阵的格式。

  • 构造目标函数,定义参数搜索空间和优化项。我们以启发式算法求解最大割问题作为目标函数,选取迭代步数、频率维数、迭代步长作为超参数,并确认数据类型和范围,将每次计算出来的最大割值作为优化项。

  • Optuna设置优化方向(最大化)和优化次数,运行得到最佳参数组合和最大割值。

[4]:
# 导入需要的Python模块
import optuna
from mindquantum.algorithm.qaia import BSB
import numpy as np
import pandas as pd
from scipy.sparse import coo_matrix
[ ]:
# 数据准备
# 下载数据,无向图数据集来源于GSet
import requests

graph_file = "https://web.stanford.edu/~yyye/yyye/Gset/G22"

# 使用requests库中的get方法发送HTTP请求,将url的响应结果存入变量,再以二进制写入模式打开文件写入本地
response = requests.get(graph_file)
open("G22", "wb").write(response.content)


# 如果上述-下载图集的代码执行,报错TimeoutError,说明是网络问题
# 可以手动点击网址 https://web.stanford.edu/~yyye/yyye/Gset/G22,下载数据,保存在本地,与该教程同级目录
[5]:
# 数据处理
def read_gset(filename, negate=True):
    # 读取图表
    graph = pd.read_csv(filename, sep=" ")
    # 节点的数量
    n_v = int(graph.columns[0])
    # 边的数量
    n_e = int(graph.columns[1])

    # 如果节点和边不匹配,会抛出错误
    assert n_e == graph.shape[0], "The number of edges is not matched"

    # 将读取的数据转换为一个COO矩阵(Coordinate List Format),并返回一个稀疏矩阵
    G = coo_matrix(
        (
            np.concatenate([graph.iloc[:, -1], graph.iloc[:, -1]]),
            (
                np.concatenate([graph.iloc[:, 0] - 1, graph.iloc[:, 1] - 1]),
                np.concatenate([graph.iloc[:, 1] - 1, graph.iloc[:, 0] - 1]),
            ),
        ),
        shape=(n_v, n_v),
    )
    if negate:
        G = -G

    return G


G = read_gset("./G22")
[7]:
# 优化目标函数
# 将待优化的算法构造成目标函数,此处以模拟分岔BSB为例,定义输入的参数n_iter\xi\dt,返回值cut作为优化项
def objective(trial):
    # 定义参数搜索空间,迭代步数,整数类型,可选值[200, 500, 1000, 1500, 2000]
    n_iter = trial.suggest_categorical("n_iter", [200, 500, 1000, 1500, 2000])
    # 设置频率维数,浮点数,范围是0.1~2
    xi = trial.suggest_float("xi", 0.1, 2)
    # 设置迭代步长,浮点数,范围是0~2
    dt = trial.suggest_float("dt", 0, 2)

    # 使用BSB算法计算图的最大割值
    bsb = BSB(J=G, batch_size=100, n_iter=n_iter, xi=xi, dt=dt)
    bsb.update()
    cut_value = bsb.calc_cut()

    max_cut = max(cut_value)
    return max_cut


# 设置优化方向为最大化
study = optuna.create_study(direction="maximize")
# 优化30次
study.optimize(objective, n_trials=30)

# 打印出Optuna调参后得到的最近参数和结果
print("Best parameters:", study.best_params)
print("Best cut:", study.best_value)
[I 2025-06-10 14:45:49,389] A new study created in memory with name: no-name-e39b169b-e700-46cf-b7de-0a06029b5fc2
[I 2025-06-10 14:45:57,224] Trial 0 finished with value: 13150.0 and parameters: {'n_iter': 2000, 'xi': 0.9854202577397366, 'dt': 0.5477249406048266}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:05,089] Trial 1 finished with value: 13131.0 and parameters: {'n_iter': 2000, 'xi': 1.0144441314725534, 'dt': 0.14700420950824844}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:07,024] Trial 2 finished with value: 0.0 and parameters: {'n_iter': 500, 'xi': 1.0630337466081248, 'dt': 0.8816243325250461}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:10,916] Trial 3 finished with value: 13098.0 and parameters: {'n_iter': 1000, 'xi': 1.8987245320688324, 'dt': 0.48426104373507317}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:11,696] Trial 4 finished with value: 0.0 and parameters: {'n_iter': 200, 'xi': 0.5409946559755382, 'dt': 1.8674038859144357}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:17,508] Trial 5 finished with value: 13131.0 and parameters: {'n_iter': 1500, 'xi': 1.85980870314362, 'dt': 0.4736079017307153}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:18,312] Trial 6 finished with value: 13149.0 and parameters: {'n_iter': 200, 'xi': 0.8832047795920951, 'dt': 0.2944176599505819}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:26,011] Trial 7 finished with value: 0.0 and parameters: {'n_iter': 2000, 'xi': 1.415239274236914, 'dt': 1.2270769369519832}. Best is trial 0 with value: 13150.0.
[I 2025-06-10 14:46:33,920] Trial 8 finished with value: 13209.0 and parameters: {'n_iter': 2000, 'xi': 0.6685516703951494, 'dt': 0.38186215999423023}. Best is trial 8 with value: 13209.0.
[I 2025-06-10 14:46:34,700] Trial 9 finished with value: 0.0 and parameters: {'n_iter': 200, 'xi': 1.0212129276196251, 'dt': 1.1399747781193834}. Best is trial 8 with value: 13209.0.
[I 2025-06-10 14:46:36,649] Trial 10 finished with value: 0.0 and parameters: {'n_iter': 500, 'xi': 0.2674806227804169, 'dt': 1.5826105377506663}. Best is trial 8 with value: 13209.0.
[I 2025-06-10 14:46:44,426] Trial 11 finished with value: 13187.0 and parameters: {'n_iter': 2000, 'xi': 0.6201525299807226, 'dt': 0.7386461621543139}. Best is trial 8 with value: 13209.0.
[I 2025-06-10 14:46:52,221] Trial 12 finished with value: 13241.0 and parameters: {'n_iter': 2000, 'xi': 0.5000901811624008, 'dt': 0.7695917543118803}. Best is trial 12 with value: 13241.0.
[I 2025-06-10 14:47:00,805] Trial 13 finished with value: 13287.0 and parameters: {'n_iter': 2000, 'xi': 0.24501427912089346, 'dt': 0.09730316419264518}. Best is trial 13 with value: 13287.0.
[I 2025-06-10 14:47:06,599] Trial 14 finished with value: 0.0 and parameters: {'n_iter': 1500, 'xi': 0.1343794192379361, 'dt': 1.443147898698505}. Best is trial 13 with value: 13287.0.
[I 2025-06-10 14:47:10,795] Trial 15 finished with value: 13186.0 and parameters: {'n_iter': 1000, 'xi': 0.35354754708959213, 'dt': 0.048648627578946946}. Best is trial 13 with value: 13287.0.
[I 2025-06-10 14:47:18,560] Trial 16 finished with value: 13223.0 and parameters: {'n_iter': 2000, 'xi': 0.41501193595639063, 'dt': 0.8710262789265769}. Best is trial 13 with value: 13287.0.
[I 2025-06-10 14:47:27,510] Trial 17 finished with value: 13320.0 and parameters: {'n_iter': 2000, 'xi': 0.10962746454226069, 'dt': 0.04327730177800215}. Best is trial 17 with value: 13320.0.
[I 2025-06-10 14:47:36,277] Trial 18 finished with value: 13319.0 and parameters: {'n_iter': 2000, 'xi': 0.20492428842592136, 'dt': 0.07675851169706162}. Best is trial 17 with value: 13320.0.
[I 2025-06-10 14:47:40,353] Trial 19 finished with value: 13092.0 and parameters: {'n_iter': 1000, 'xi': 1.4449821018638078, 'dt': 0.01891161997759272}. Best is trial 17 with value: 13320.0.
[I 2025-06-10 14:47:46,951] Trial 20 finished with value: 13336.0 and parameters: {'n_iter': 1500, 'xi': 0.1032352341871752, 'dt': 0.2749199047871625}. Best is trial 20 with value: 13336.0.
[I 2025-06-10 14:47:53,580] Trial 21 finished with value: 13333.0 and parameters: {'n_iter': 1500, 'xi': 0.18933056261923595, 'dt': 0.2690572699319539}. Best is trial 20 with value: 13336.0.
[I 2025-06-10 14:48:00,416] Trial 22 finished with value: 13350.0 and parameters: {'n_iter': 1500, 'xi': 0.12643971691997044, 'dt': 0.2427101496435709}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:06,374] Trial 23 finished with value: 13170.0 and parameters: {'n_iter': 1500, 'xi': 0.768187969451931, 'dt': 0.27833172283830976}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:12,467] Trial 24 finished with value: 13285.0 and parameters: {'n_iter': 1500, 'xi': 0.37712716123693546, 'dt': 0.6503970389856277}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:19,216] Trial 25 finished with value: 13333.0 and parameters: {'n_iter': 1500, 'xi': 0.11711321639360335, 'dt': 0.25135181974448084}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:25,025] Trial 26 finished with value: 13113.0 and parameters: {'n_iter': 1500, 'xi': 1.3106221351956426, 'dt': 0.6122590372769572}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:31,207] Trial 27 finished with value: 13296.0 and parameters: {'n_iter': 1500, 'xi': 0.314056428843962, 'dt': 0.39524343565408737}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:37,222] Trial 28 finished with value: 13226.0 and parameters: {'n_iter': 1500, 'xi': 0.4811504744246722, 'dt': 0.23460200349669913}. Best is trial 22 with value: 13350.0.
[I 2025-06-10 14:48:43,207] Trial 29 finished with value: 13201.0 and parameters: {'n_iter': 1500, 'xi': 0.7292919802986543, 'dt': 0.5383674375183389}. Best is trial 22 with value: 13350.0.
Best parameters: {'n_iter': 1500, 'xi': 0.12643971691997044, 'dt': 0.2427101496435709}
Best cut: 13350.0

上述样例代码执行30次后,得到最佳参数组合,最大割值为13350

注意,本篇教程只是提供样例代码,优化次数仅为30,调参工具的结果具有一定随机性;在实际应用中结合业务需求可适当放大参数范围。

[8]:
from mindquantum.utils.show_info import InfoTable

InfoTable("mindquantum", "scipy", "numpy")
[8]:
Software Version
mindquantum0.10.0
scipy1.11.3
numpy1.26.1
System Info
Python3.10.13
OSLinux x86_64
Memory810.22 GB
CPU Max Thread96
DateTue Jun 10 14:49:51 2025