模擬退火法是針對爬山法只能求出局部最優解提出來的。模擬退火法其實也是一種貪心法,但是他搜尋最優解的過程中引入了隨機因素,允許在中間的計算過程中按照一定的概率來接受相對較差的中間結果,因此它有可能調出局部最優解尋找到全局的最優解。
模擬退火法算法描述:
若J(Y(I+1)) >= J(Y(I)) (即移動後得到更優解)則總是接受該移動
若J(Y(I+1)) < J(Y(I)) (即移動後得到的解比當前解要差) 則以一定的概率接受該移動,並且這個概率隨着時間的推移逐漸降低
上行中一定的概率參考了冶金中的退火過程,其計算公式如下:
p= exp(-(highcost-lowcost)/temperture) 因爲溫度(接收較差的解的意願)開始非常高,指數總是接近於0,所以概率接近於1,隨着溫度的降低,高成本和低成本之間的差異越來越大,概率越低。因此該算法只傾向於稍微差的解而不會是非常差的解。
關鍵代碼實現:
def annealingoptimize(domain,costf,T=10000.0,cool=0.95,step=1):
#隨機初始化值
vec= [float(random.randint(domain[i][0],domain[i][1]))
for i in range(len(domain))]
while T>0.1:
#選擇一個索引值
i = random.randint(0,len(domain)-1)
#選擇一個改變索引的方向
dir = random.randint(-step,step)
#創建一個代表題解的新列表,改變其中的一個值
vecb = vec[:]
vecb[i] += dir
if vecb[i] < domain[i][0]:
vecb[i] = domain[i][0]
elif vecb[i] > domain[i][1]:
vech[i] = domain[i][1]
#計算當前新成本和當前
ea = costf(vec)
eb = costf(vecb)
#是更好的解或者按照概率被接收
if (eb<ea or random.random()<pow(math.e,-(eb-ea)/T))
vec = vecb
#降低溫度
T = T*cool
return vec
爲了退火,函數需要創建一個合適長度的隨機數,在每個屬性的上下限閾值範圍內。維度T和冷卻率cool是兩個可選的參數,函數每次迭代的時候將i設定爲一個隨機索引,並將dir設爲介於-step和step之間的某個隨機數。該函數會持續計算直到設定的溫度退出條件。