基本模型
模擬退貨算法可以分解爲解空間、目標函數和初始解三部分
基本思想
求一個函數的最優解可以通過貪心算法獲得其最優解,但有可能是局部最有解,而不是全局最優解。爲了解決這一問題,產生了模擬退火算法,該算法是在搜索的過程中加入了隨機的因素,以一定的概率接受比當前解要差的解,因此有可能會跳出這個局部最優解,達到全局最優解。
基本步驟
- 初始化:初始溫度 , 溫度變化率 (通常取值),初始解狀態 ,每個值的迭代次數 ;
- 對 做第 3 至第 6 步;
- 產生新解 ;
- 計算增量 ,其中 爲評價函數;
- 若 則接受 作爲新的當前解,否則以概率 準則接受 作爲當前解;
- 如果滿足終止條件則輸出當前解作爲最優解,結束程序;
- 根據 逐漸減少,且 ,然後轉向第二步。
Metropolis準則
其中,T爲當前的溫度,在 時,求出的 在 之間,以此概率接受比當前解要差的解。
參數設置
初始溫度:初始溫度的確定可以隨機產生數據來粗略的估計一下,比如可以先進行100個迭代,計算出目標函數的平均差值或者最大差值,再根據你希望的初始溫度下由當前解轉換爲較差的解的概率和Metropolis準則計算出初始溫度。
最小溫度:可以設置的很小,進行很多次的迭代,找到全局最優解。
溫度變化率:一般設置爲 之間的值,一般使用 來衰減溫度,當然也可以根據自己想要的衰減速率選取合適的公式。
目標函數:要求解的函數。
生成新解:可以在當前解的基礎上進行部分或者全部值的改動,根據自己解的需求限定當前解的範圍。
Python實現(部分)
# -*- coding: utf-8 -*-
import math
import random
ITERS = 100 # 每個溫度下的迭代次數
T = 100 # 初始溫度
T_min = 0.002 # 溫度最小值
delta_t = 0.98 # 溫度變化率
class SA:
'''
求最小值
'''
def __init__(self):
self.t = T
self.iters = ITERS
self.t_min = T_min
self.delta_t = delta_t
def sa(self, fun):
'''
模擬退火算法
:param fun: 目標函數
:return:
'''
x_old = self._init_x()
y_old = fun(x_old)
while self.t > self.t_min:
for i in range(self.iters):
x_new = self._update_x(x_old)
y_new = fun(x_new)
loss = y_new - y_old
if loss <= 0: # 替換比當前解好的解
x_old = x_new
y_old = y_new
else:
random_p = random.random()
if self.metropolis(loss) > random_p: # 以一定概率替換比當前解差的解
x_old = x_new
y_old = y_new
# 是否滿足條件, 滿足則結束, 不滿足則更新溫度繼續
self.t *= self. delta_t
# 最終保存或者輸出最優解
print("x {}, y {}".format(x_old, y_old))
def metropolis(self, loss):
return math.e ** (loss / self.t)
def _update_x(self, x_old):
'''
生成新解
:return:
'''
pass
def _init_x(self):
'''
設置初始解
:return:
'''
pass