量子退火算法入门(3):整数分割问题的QUBO建模

整数分割问题:

QUBO建模最重要的就是,把建模对象中的变量映射为binary(0/1 或者 -1/+1)的变量。我先从简单的问题开始说明,让大家有些直观感受。整数分割问题就是一个非常简单,并容易理解的例子。此文参考了日本NTT公司的量子计算指南文档[*1]。

  • 整数分割问题定义:

判断能否将一个N 个整数 a 1 , ・・・ a N a_1,・・・a_N a1,・・・aN 的整数集合分割成两个子集合,并且这两个子集合里的元素之和相等。

  • 例子:
    请添加图片描述
    我们可以看到,上面👆的例子,分割后的两个子集合A和B的元素之和都等于6,所以该集合是可以满足整数分割的。

转化为组合优化问题:

之前讲的QUBO的例子里,用的变量都是0或1。其实,还可以是-1或+1,这时候也叫ising模型。求解变量什么时候用0/1,什么用-1/+1,这个之后用例子给大家解释。
这次的问题,是把求解的两个子集合的标签作为-1/+1的变量。如下图所示。
请添加图片描述
我们的优化目标就成为了,最小化两个子集合的差值的平方和。大家可以思考一下,如果使用0/1作为子集合A和B的标签,我们要怎么定义最小化的目标函数。
请添加图片描述

  • 目标集合为{ 1, 5, 6 }时的目标函数就是:
    请添加图片描述
    我们来枚举一下,所有 x i x_i xi 从-1或+1取值的组合结果:
    请添加图片描述
    我们可以看到,目标函数值为0时,我们得到了正确的整数分割结果。

目标函数转化为QUBO:

因为已经获得了目标函数,那我们先把多项式展开就好了。展开结果如下图所示:

请添加图片描述

因为【 x i x_i xi 从-1或+1取值】这个设定,下面👇的式子是成立的:
・ x i 2 = 1 ・x_i^{2} = 1 xi2=1
所以我们可以得到下面的QUBO结果:
请添加图片描述
最后献上Python代码。

PyQUBO实现Ising模型:

之前的目标函数都是展开后的二次多项式,大家可以直接计算出QUBO矩阵。这次使用PyQUBO直接定义目标函数,大家就不用手动求解QUBO矩阵了。

import pyqubo
import neal
x = pyqubo.Array.create('x', shape=(3), vartype='SPIN') # 'SPIN' 就表示目标变量是从{-1, 1}取值。目标变量需要从{0, 1}中取值时,就设定为 'BINARY' 

objective_function = (1 * x[0] + 5 * x[1] + 6 * x[2]) ** 2

model = objective_function.compile() 
bqm = model.to_bqm()

print("我们可以将bqm转为ising或qubo输出")
print(bqm.to_ising())

sa = neal.SimulatedAnnealingSampler()
sampleset = sa.sample(bqm, num_reads=10)
samples = model.decode_sampleset(sampleset)
best_sample = min(samples, key=lambda s: s.energy)

print("求解时,pyqubo内部已经将ising模型转换为qubo的0或1,所以输出结果为0或1")
print(best_sample.sample) 

运行结果如下:

我们可以将bqm转为ising或qubo输出
({'x[2]': 0.0, 'x[0]': 0.0, 'x[1]': 0.0}, {('x[0]', 'x[2]'): 12.0, ('x[1]', 'x[2]'): 60.0, ('x[1]', 'x[0]'): 10.0}, 62.0)
求解时,pyqubo内部已经将ising模型转换为qubo的01,所以输出结果为01
{'x[2]': 1, 'x[0]': 0, 'x[1]': 0}

以上就是一个简单建模的例子。下篇讲旅行商问题的建模。

  • 参考文献:[*1] : https://www.nttdata.com/jp/ja/-/media/nttdatajapan/files/news/services_info/2021/012800/012800-01.pdf
  • 27
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 18
    评论
您好!您提到了使用Matlab来模拟退火算法求解QUBO(Quadratic Unconstrained Binary Optimization)问题。下面是一个简单的示例代码,用于演示如何在Matlab中实现退火算法来解决QUBO问题: ```matlab % 定义目标函数 Q = [1 -1 2; -1 2 -1; 2 -1 3]; % Q矩阵 f = [1; -2; 3]; % 线性偏置向量 % 模拟退火参数设置 initial_temperature = 100; final_temperature = 0.001; cooling_rate = 0.95; iteration_per_temperature = 100; % 初始化当前解和当前能量 current_solution = randi([0, 1], size(Q, 1), 1); current_energy = current_solution' * Q * current_solution + f' * current_solution; % 模拟退火算法主循环 temperature = initial_temperature; while temperature > final_temperature for i = 1:iteration_per_temperature % 生成一个新的解 new_solution = current_solution; index = randi(length(new_solution)); new_solution(index) = ~new_solution(index); % 计算新解的能量 new_energy = new_solution' * Q * new_solution + f' * new_solution; % 根据Metropolis准则接受或拒绝新解 if new_energy < current_energy || rand < exp((current_energy - new_energy) / temperature) current_solution = new_solution; current_energy = new_energy; end end % 降低温度 temperature = temperature * cooling_rate; end % 输出最优解和最优能量 optimal_solution = current_solution; optimal_energy = current_energy; disp('Optimal Solution:'); disp(optimal_solution); disp('Optimal Energy:'); disp(optimal_energy); ``` 请注意,这只是一个简单的示例代码,用于解决一个具体的QUBO问题需要根据具体情况进行调整和修改。此外,该代码还可以进一步优化,例如通过选择更合适的初始温度、冷却速率和迭代次数来改进算法的性能。 希望这个示例能对您有所帮助!如果您有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值