標籤:hive 計算 code random 技術 log html ++ 就會
一、什麼是類比退火演算法1、爬山演算法
在瞭解類比退火演算法之前,先來看一下爬山演算法:爬山演算法是一種貪心演算法,該演算法每次從當前的解空間中選取一個解作為最優解,直到達到一個局部最優解。假設函數f(x)的映像如:
現在使用爬山演算法來求f(x)的最大值,若C為當前最優解,則爬山演算法搜尋到A就會停止搜尋,這會獲得一個局部最優解,而不是全域最優解。
2、類比退火演算法
繼續考慮尋找f(x)最大值的問題,爬山演算法搜尋到A點時就會停止搜尋,原因是A點左右的值均小於A點的值。類比退火演算法採用的解決辦法是以一定的機率選擇A兩邊的點,儘管A兩邊的點並不是局部最優解,這樣就有一定的機率搜尋到D點,從而搜尋到B點,最終獲得了全域最優解。
上文中的一定機率來自於固體退火原理:當固體溫度較高時,物質內能較大,固體內部分子運動劇烈;當溫度逐漸降低時,物體內能也隨之降低,分子運動趨於平穩;當固體溫度降到常溫時,固體內部分子運動最終平穩。根據Metropolis準則,粒子在溫度T時趨於平衡的機率為e^(-ΔE/(kT)),其中E為溫度T時的內能,ΔE為其改變數,k為Boltzmann常數。
二、類比退火演算法流程圖
三、類比退火演算法虛擬碼
/** J(y):在狀態y時的評價函數值* Y(i):表示目前狀態* Y(i+1):表示新的狀態* r: 用於控制降溫的快慢* T: 系統的溫度,系統初始應該要處於一個高溫的狀態* T_min :溫度的下限,若溫度T達到T_min,則停止搜尋*/while( T > T_min ){ dE = J( Y(i+1) ) - J( Y(i) ) ; if ( dE >=0 ) //表達移動後得到更優解,則總是接受移動 Y(i+1) = Y(i) ; //接受從Y(i)到Y(i+1)的移動 else { // 函數exp( dE/T )的取值範圍是(0,1) ,dE/T越大,則exp( dE/T )也 if ( exp( dE/T ) > random( 0 , 1 ) ) Y(i+1) = Y(i) ; //接受從Y(i)到Y(i+1)的移動 } T = r * T ; //降溫退火 ,0<r<1 。r越大,降溫越慢;r越小,降溫越快 /* * 若r過大,則搜尋到全域最優解的可能會較高,但搜尋的過程也就較長。若r過小,則搜尋的過程會很快,但最終可能會達到一個局部最優值 */ i ++ ;}
四、例子
當x∈[-5, 5]時,求函數f(x) = x^4+x^3-x^2-x的最小值。
代碼如下(Python版本):
import mathimport random# 起始溫度,x的上限T = 5# 常溫,x的下限T_MIN = -5# 迭代次數k = 100# 溫度的下降率delta = 0.9def f(x): return x**4 + x**3 - x**2 -xdef saa(): t = T #先產生k個初始解 px = [random.uniform(-5, 5) for i in range(0, k)] while(t>=T_MIN): for i in range(len(px)): fx = f(i) x_next = i + (random.random() * 2 - 1) * t #計算i周圍的函數值 if x_next>=-5 and x_next<=5: fx_next = f(x_next) if fx > fx_next: #找到更小的值則更新 px[i] = x_next else: p = math.e ** ((fx_next-fx)/T) #否則按機率更新 if p>random.random(): px[i] = x_next t-=t*delta ans = [f(x) for x in px] #計算f(x) return min(ans) #返回ans的最小值saa()
輸出:
-0.6063902871880511
由該函數的映像可以看出,該函數在[-5, 5]上的最小值為-0.6左右。
五、參考
1、http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html
2、45395257
類比退火演算法