模擬退火
模擬降溫的過程:溫度越高時溫度下降越多,溫度越低(穩定)時,溫度下降越少
首先由爬山算法開始
爬山算法:即完完全全的貪心算法,只找到眼前的山峯最高值。
但從c點開始時,我們發現找到的A點不是全局最優解,這也是貪心的缺點。
模擬退火是在爬山算法上做的改進:
其核心是:即使找到的不是最優解,也有概率選擇它
這樣就能跳出貪心的局部最優,搜索到全局最優
概率符合退火規律:範圍越不確定時,跳出概率越大;隨着範圍縮小,跳出概率越低
很合理了。
上圖山坡的例子,當找到A點後,再找E點,有概率選擇到E點。
以下是網上他人的僞代碼,我認爲很好理解: http://www.cnblogs.com/heaad/
/*
* 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 ++ ;
}
關於火候的把握
理解了上述退火的思想,我們也應該發現:
找到全局最優解只是個概率事件!!!
而決定概率的一共有三個變量:
- 溫度的初始值
- 退火速度
- 模擬次數(溫度管理)
聰明的你也應該會發現:
- 如果退火速度太慢\次數太高\範圍太大 會導致tle
- 如果退火速度太快\次數太低\範圍太小 會導致wa
- 使用的rand函數若取的運氣不好,會出現一樣的代碼一次wa,一次ac的神奇現象
一般的做題步驟:
求到n個點最短距離的點座標
隨機生成幾個點(看題目給的點個數差不多一樣就行)rand函數;
對每個點模擬30~50次不等rand函數(具體模擬就是從該點走隨機個步數到一個新點,比較一下最近的距離是不是最優,若是,更新)
輸出最後更新的那個點就是解。
退火思想:每個點模擬時,範圍越大,rand函數走出的步長越長,範圍越小時,rand越小,結果越接近。找一個起始點(零點吧);在給定點中找出最近的點和其距離;更新起始點,向最近點靠近
s.x+=(P[k].x-s.x)/d*T;
s.y+=(P[k].y-s.y)/d*T;
退火思想:範圍越大靠近的距離越多,範圍越小時,靠近的距離越小