在python中调用双模拟退火算法dual_annealing
迪丽瓦拉
2024-05-02 21:40:40
0

原理

模拟退火算法(CSA)中最重要的概念就是Metrospolis准则,表示的是接收新解的概率,一般表示为

p=e−f(x2)−f(x3)Tp=e^{-\frac{f(x_2)-f(x_3)}{T}} p=e−Tf(x2​)−f(x3​)​

即生成一个随机数,如果这个随机数大于ppp,则接受新解,主要用于最小值求解过程时的新解判定。

例如,对于x1f(x2)f(x_1)>f(x_2)f(x1​)>f(x2​),然后又通过步进的方式,得到了x3x_3x3​,且x1f(x2)f(x_3)>f(x_2)f(x3​)>f(x2​),那么搜解过程就结束了,说明x2x_2x2​就是最小值。

问题是,x2x_2x2​无论怎么看都是个极小值,而非最小值,说不定在原理这三个数的某点,存在比x2x_2x2​更小的值。为了克服这种局部最优解,就要求在步进搜解的过程中,就算得到了极小值x2x_2x2​,也不能认为这就是极小值,而是要有一个几率跳出去,这就是模拟退火算法(Simulated Annealing,SA)的核心思想。

1987年,Szu等人用柯西洛伦兹分布来取代玻尔兹曼函数,提出快速模拟退火算法(FSA),其中柯西洛伦兹分布表示为:

gqv(Δx(t))∝[Tqv(t)]−D3−qv[1+(qv−1)[Δx(t)]2[Tqv(t)]23−qv]1qv+1+D−12g_{q_v}(\Delta x(t))\propto \frac{[T_{q_v}(t)]^{-\frac{D}{3-q_v}}}{[1+(q_v-1)\frac{[\Delta x(t)]^2}{[T_{q_v}(t)]^{\frac{2}{3-q_v}}}]^{\frac{1}{q_v+1}+\frac{D-1}{2}}} gqv​​(Δx(t))∝[1+(qv​−1)[Tqv​​(t)]3−qv​2​[Δx(t)]2​]qv​+11​+2D−1​[Tqv​​(t)]−3−qv​D​​

其中ttt为时间,TqvT_{q_v}Tqv​​为温度,qvq_vqv​用于调整这个分布的参数。

1996年,Stariolo等人结合CSA和FSA, 提出了广义模拟退火算法(GSA),这也是dual_annealing的雏形。

调用

scipy.optimize中所实现的dual_annealing函数,其必要参数有两个,分别是待优化函数func以及参数范围bounds,测试如下

import numpy as np
from scipy.optimize import dual_annealing as dadef test(xs):_sum = 0.0for i in range(len(xs)):_sum = _sum + np.cos((xs[i]*i)/5)*(i+1)return _sumbounds = [[-15,15] for _ in range(5)]
ret = da(test, bounds)
msg = f"全局最小值" + ", ".join([f"{x:.4f}" for x in ret.x])
msg += f"\nf(x)={ret.fun:.4f}"
print(msg)

其结果为

全局最小值-11.4502, -15.0000, 7.8540, -5.2360, -3.9270
f(x)=-12.9800

dual_annealing中,除了必填的funcbounds之外,还有下列几组比较重要的参数

  • args 为参数元组,即func的输入参数除了待优化值之外,还可以包括args
  • maxiter 最大迭代次数,默认1000
  • minimizer_kwargs 局部最优搜素器
  • initial_temp 初始温度

相关内容