优化模型---001-模拟退火模型

模拟退火模型

模仿了自然界退火现象得到 利用了物理中固体物质的退火过程和一般优化问题的相似性,从某一温度开始 伴随温度的不断下降 结合概率突跳特性 在解空间随机寻找全局最优解

算法要求: 初始温度足够高 降温过程足够满 终止温度足够低

什么是退火

将固体加热到足够高的温度 使分子呈随机排列状态 然后逐步降温使之冷却 最后分子以低能状态排列 固体达到稳定状态

物理退火过程

1. 加热过程 增强粒子的热运动 消除系统原先存在的非均匀态
2. 等温过程 对于与环境换热而温度不变的封闭系统 系统自由能逐渐减少 自由能最小时 到达平衡态
3. 冷却过程 粒子热运动减弱 能量逐渐下降 从而得到低能晶体结构

算法推导

image
能量越低的状态概率越高
温度越低的状态概率越低
image

Ck约掉

image
温度很大的情况下 各状态的几率几乎相同
温度降低 各状态概率开始有差别
Tk很小时 最小能量状态的概率大概为1

算法实现

1. 初始化 任选初始解 给定初始温度T0 终止温度Tf 令迭代指标 k=0 Tk=T0,注意出初始温度要足够高 满足 Ei/Tk-->0

2. 产生一个邻域解 j from N(i)
计算目标增量: df = f(j) - f(i)

3. 若df < 0 令i = j 到4 否则

image

4. 若达到热平衡(内循环次数大于n(Tk)) 则到5 否则到2

5. k = k+1 降低Tk   若 Tk <Tf 小于设置的温度 就停止 否则继续降温
Tk+1 = Tk * r  r(0.95,0.99)

总体来看 模拟退火算法从某一高温出发,在高温状态下计算初始解,然后以预设的邻域函数产生一个扰动量,从而得到新的状态,即模拟粒子的无序运动,比较新旧状态下的能量,即目标函数的解。如果新状态的能量小于旧状态,则状态发生转化;如果新状态的能量大于旧状态,则以一定的概率准则发生转化。当状态稳定后,便可以看作达到了当前状态的最优解,便可以开始降温,在下一个温度继续迭代,最终达到低温的稳定状态,便得到了模拟退火算法产生的结果。

状态转移概率

image

案例

利用模拟退火求解函数在范围内的最小值问题

image

实现

import matplotlib.pyplot as plt
import numpy as np
import math


# 本例目标函数 就是函数的解
def aim_function(x):
	y = x ** 3 - 60 * x ** 2 + 4 * x + 6
	return y


# 计算x(0,100)的最小值 精度为 0.1


# 先用蛮力法 看一下大概的图像
x = [i / 10 for i in range(1000)]
y = [0 for i in range(1000)]
for i in range(1000):
	y[i] = aim_function(x[i])

plt.plot(x, y)
plt.show()


def annealing_function(t, tmin, x, k, times):
	# 温度大于最低温度前
	while t > tmin:
		# 内循环 反复更新 x 通过x和x邻域的能量 进行比较 找到该温度下 能量的低点
		for i in range(k):
			# 输入状态 和 得到能量
			y = aim_function(x)
			# 在x的邻域得到一个新的x 并且根据新的x的能量判断是否改变状态
			# 利用均匀分布 得到x邻域内的x 邻域函数应尽可能满足产生的候选解遍布全部状态空间。
			# 其通常由产生候选解的方式和候选解产生的概率分布组成。
			xNew = x + np.random.uniform(-0.055, 0.055) * t
			# 计算该温度下的能量
			if 0 <= xNew and xNew <= 100:
				yNew = aim_function(xNew)
				if yNew - y < 0:
					# 更新状态
					x = xNew
				else:
					# 若xNew状态的能量大于x状态的能量 也有可能更新状态
					# 利用metropolis准则 可以计算出 当前转换状态的概率
					p = math.exp(-(yNew - y) / t)
					# 利用均匀分布得到一个随机值 在跟概率进行比较
					r = np.random.uniform(0, 1)
					# 在(0,p) 内则 更新
					if r < p:
						x = xNew
		# 退火温度变化的次数
		times += 1
		print(times)
		# 温度下降
		t = 1000 / (1 + times)

	# 输出近似解的状态 和 值
	print(x, aim_function(x))


def simulated_annealing():
	# 定义初始温度 低温阈值 初始x 内循环次数 降温函数
	# 先定义初始温度t
	t = 1000
	# 低温阈值tmin
	tmin = 10
	# 初始的状态
	x = np.random.uniform(0, 100)
	# 定义内循环次数
	k = 50
	# 定义当前能量
	y = 0
	# 定义时间
	times = 0
	annealing_function(t, tmin, x, k, times)


simulated_annealing()
print('精确解:', min(y))
posted @ 2022-04-19 09:34  cc学习之路  阅读(557)  评论(0)    收藏  举报