模擬退火

模擬退火

(很久沒有寫博客,一寫就是這麼玄乎的東西......)html

前言

  • 對於這種十分神奇的近似算法(xjb隨機算法) ,我一貫以爲這十分不靠譜。
  • 然而,只有真正認真學習過這個(極其富有魅力)的算法的人,才知道這個算法是多麼的強 (多麼的不靠譜)
  • 那麼,我就簡單的介紹一下模擬退火。

算法的物理原理 (沒什麼用)

  • PS:如下是摘自百度百科的物理原理介紹:算法

    模擬退火算法來源於固體退火原理,將固體加溫至充分高,再讓其徐徐冷卻,加溫時,固體內部粒子隨溫升變爲無序狀,內能增大,而徐徐冷卻時粒子漸趨有序,在每一個溫度都達到平衡態,最後在常溫時達到基態,內能減爲最小。根據Metropolis準則,粒子在溫度T時趨於平衡的機率爲e(-ΔE/(kT)),其中E爲溫度T時的內能,ΔE爲其改變量,k爲Boltzmann常數。用固體退火模擬組合優化問題,將內能E模擬爲目標函數值f,溫度T演化成控制參數t,即獲得解組合優化問題的模擬退火算法:由初始解i和控制參數初值t開始,對當前解重複「產生新解→計算目標函數差→接受或捨棄」的迭代,並逐步衰減t值,算法終止時的當前解即爲所得近似最優解,這是基於蒙特卡羅迭代求解法的一種啓發式隨機搜索過程。退火過程由冷卻進度表(Cooling Schedule)控制,包括控制參數的初值t及其衰減因子Δt、每一個t值時的迭代次數L和中止條件S。函數

  • 是否是發現,有點看不懂呢?甚至有一點點懵逼呢?
  • 其實,這些內容沒什麼太大意義只是用來看看的。
  • 惟一有點用的,可能就是那個平衡機率吧。學習

算法在oi中的做用

  • oi中存在許多沒法在多項式時間內解決的問題,如經典的TSP問題, 求費馬點等多種問題。這也就是人們所熟知的np難問題。
  • 人們不能忍受在指數時間內達到正確的解。由於即便解是正確的,但可能到世界毀滅,這個解也跑不出。
  • 因此,人們指望有一種時間複雜度低,可是卻能獲得近似解的算法。即便這個算法得出的答案可能不是徹底正確的。
  • 這時,模擬退火,登山,遺傳算法,蟻羣算法就漸漸到了人們的關注中,顯得尤其重要了。
  • 總而言之,模擬退火的做用就是:在較短的時間內,獲得十分接近的答案,或者獲得的就是答案。

算法實現

  • 在知乎仍是哪有一個特別有趣的比喻,在必定程度上說明了登山算法與模擬退火的實現:
  1. 登山算法:兔子朝着比如今高的地方跳去。它找到了不遠處的最高山峯。可是這座山不必定是珠穆朗瑪峯。這就是登山算法,它不能保證局部最優值就是全局最優值。
  2. 模擬退火:兔子喝醉了。它隨機地跳了很長時間。這期間,它可能走向高處,也可能踏入平地。可是,它漸漸清醒了並朝最高方向跳去。這就是模擬退火。
  • 從以上那毫無心義的物理原理,咱們能夠看出,模擬退火的主要步驟有幾個:
  1. 設置初始溫度\(T\),初始符合條件的答案;
  2. 經過某種神奇的方式,找到另外一個符合條件的新狀態;
  3. 分別將兩個狀態的答案計算出來,並做差獲得\(\Delta E\)
  4. 根據題目要求,貪心的決定是否更換答案。即:選擇最優解。
  5. 若是沒法替換答案,則根據必定機率替換答案。即運用到上述的平衡機率\(exp(\Delta E / T)\)隨機的決定是否替換。
  6. 每一次操做後,進行降溫操做。即:將溫度\(T\)乘上某一個係數,通常是\(0.985-0.999\)隨具體題目(隨緣)定。

咱們能夠根據上述過程寫出一段僞代碼:優化

eps=1e-15;
T=初始溫度;
while(T>eps)
{
    now=從當前最優狀態隨機更新的一個狀態;
    delta=calc(now)-calc(ans);
    if(delta與題目要求的知足更優)ans=now;
    else if(exp(delta/T)*RAND_MAX>rand())ans=now;//PS:這裏的delta前面可能要加'-';
    T*=t0;//t0通常在0.985-0.999之間,根據具體題目時間,隨緣調試。。。
}
  • 這就是模擬退火的具體實現方式,應該代碼已經不難實現了。
  • PS:有一點須要注意的是,用平衡條件進行更新答案的時候,要根據題目判斷\(\Delta E\)前要不要加\(-\),若是實在判斷不出,就兩種都試一試。若是其中一種出現特別大的答案,或很奇怪的答案,那就用另外一種吧。要麼就把那一行註釋掉,看看答案的變化大不大。
  • 那麼,模擬退火就講完了。具體的代碼實現,就經過具體的題目來看吧。

例題

( 題目打完了,還沒寫題解。最近一篇篇加進來吧。)spa

[JSOI2004]平衡點

hdu5017 Ellipsoid

相關文章
相關標籤/搜索