模拟退火算法可以看做是对于爬山算法的一种改进。爬山算法的最致命的缺点就是只能找到局部的最优解,对于平滑的曲线或者是想要寻找全局最优解是没有办法的。
这个时候就有人先要改善这个缺点。铁匠的打铁行为中会对高温的材料进行敲打,因为在高温的时候,分子更活跃也就更容易运动,因此可以更轻松的让分子充新排列,据此,创造了模拟退火的算法。和铁匠的行为一样,在算法中增加一个变量,这个变量就代表着温度,关键点就在于当温度很高的时候,我们的算法有很高的概率接受比当前点的值还差的点,也就是说在初始的时候,我们的点回来的走走看看,就像看看全世界一样,而我们的温度在这个过程中会不断的下降,当温度下降之后,接收差的值的比例就会降的很低,这个时候就回到了之前的爬山算法的过程。
模拟退火算法的步骤
Current_solution = generate initial candidate solution randomly (首先随便找一个值作为解)
T = 初始温度
-
Repeat(循环)
generate neighbour solutions(differ from current solution by a single element) (找到所有和当前点(步骤1中生成点的位置)相邻的点)
Rand_neighbour = get random neighbour of current_solution (获得一个随机的邻居点的值)
-
if quality(rand_neighbour) <=quality(current_sulution){(如果这个邻居点的值小于当前点的值)
-
with some probability(
),(这里就像掷骰子来决定是否来接受这个差值)
current_solution = rand_neighbour(如果掷骰子的结果是接受那么就会接受这个差的值)
}else current_solution = rand_neigjhbour(当然如果邻居点的值比当前点大,肯定要接受)
-
T = 降低后的T(这里就进行降温)
这个循环结束的条件一般是达到一个温度值,或者是当前的结果不再改变
决定是否接受的比例值
这个值的来源是热力学,这里只要记住就可以了
= 邻居点对应的值 - 当前点对应的值
T是当前温度
T的降温策略是怎么样的
降温的速度约慢,我们的算法越有机会找到全局最优解,也就是更有时间瞎逛。
因此一般来说T会取一个接近但是小于1的值,比如0.96