1. 程式人生 > >模擬退火算法

模擬退火算法

nbsp .com AS 常數 htm width color 取值 算法

參考博客:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

引入:

爬山算法:這是一種簡單的貪心搜索算法,該算法每次從當前解的臨近解空間中選擇一個最優解作為當前解,直到達到一個局部最優解。

爬山算法實現很簡單,其主要缺點是會陷入局部最優解,而不一定能搜索到全局最優解。如圖1所示:假設C點為當前解,爬山算法搜索到A點這個局部最優解就會停止搜索,因為在A點無論向那個方向小幅度移動都不能得到更優的解。有人會說遍歷所有解空間不就可以嗎,但是通常情況我們會碰到解空間比較大,解十分密集,這樣我們就無法快速的獲得一個最優解,所以爬山法找到了一個局部最優解就將它設為最優解。

技術分享圖片

模擬退火算法:

爬山法是完完全全的貪心法,每次都鼠目寸光的選擇一個當前最優解,因此只能搜索到局部的最優值。模擬退火其實也是一種貪心算法,但是它的搜索過程引入了隨機因素。模擬退火算法以一定的概率來接受一個比當前解要差的解,因此有可能會跳出這個局部的最優解,達到全局的最優解。以圖1為例,模擬退火算法在搜索到局部最優解A後,會以一定的概率接受到E的移動。也許經過幾次這樣的不是局部最優的移動後會到達D點,於是就跳出了局部最大值A。

模擬退火算法描述:(ps:這裏的解空間我認為應該是在某個隨機解的鄰域尋找,而不是每個新解都隨機賦,具體看偽代碼)

若J( Y(i+1) )>= J( Y(i) ) (即移動後得到更優解),則總是接受該移動

若J( Y(i+1) )< J( Y(i) ) (即移動後的解比當前解要差),則以一定的概率接受移動,而且這個概率隨著時間推移逐漸降低(逐漸降低才能趨向穩定)

  這裏的“一定的概率”的計算參考了金屬冶煉的退火過程,這也是模擬退火算法名稱的由來。

  根據熱力學的原理,在溫度為T時,出現能量差為dE的降溫的概率為P(dE),表示為:

    P(dE) = exp( dE/(kT) )

  其中k是一個常數,exp表示自然指數,且dE<0。這條公式說白了就是:溫度越高,出現一次能量差為dE的降溫的概率就越大;溫度越低,則出現降溫的概率就越小。又由於dE總是小於0(否則就不叫退火了),因此dE/kT < 0 ,所以P(dE)的函數取值範圍是(0,1) 。

  隨著溫度T的降低,P(dE)會逐漸降低。

  我們將一次向較差解的移動看做一次溫度跳變過程,我們以概率P(dE)來接受這樣的移動。

 關於爬山算法與模擬退火,有一個有趣的比喻:

  爬山算法:兔子朝著比現在高的地方跳去。它找到了不遠處的最高山峰。但是這座山不一定是珠穆朗瑪峰。這就是爬山算法,它不能保證局部最優值就是全局最優值。

  模擬退火:兔子喝醉了。它隨機地跳了很長時間。這期間,它可能走向高處,也可能踏入平地。但是,它漸漸清醒了並朝最高方向跳去。這就是模擬退火。(有一定概率能跳到最高的山峰)

技術分享圖片

退火算法偽代碼:

/*
* J(y):在狀態y時的評價函數值
* Y(i):表示當前狀態
* Y(i+1):表示新的狀態
* r: 用於控制降溫的快慢
* T: 系統的溫度,系統初始應該要處於一個高溫的狀態
* T_min :溫度的下限,若溫度T達到T_min,則停止搜索
*/
while( T > T_min )
{
     for(int i=0;i<1000;i++) //退火次數1000次即從T的鄰域的一千個解中尋找最優解,這個地方可以不用從領域找,只不過這樣概率就大了。
    {
       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過小,則搜索的過程會很快,但最終可能會達到一個局部最優值
  */
}

模擬退火算法