本篇參考了一下Chhokmah小姐姐的博客
概念:
其實基於爬山,爬山是一個非常笨的貪心,爬山本質是按照一個方向找最高點,不過找到一個比兩邊都高的點就會停下,這顯然是錯的,結果卻由此誕生了一個模擬退火。
模擬退火\((Simulate\ Anneal,SA)\)是一種通用概率演算法,用來在一個大的搜尋空間內找尋命題最優解,是解決\(TSP\)問題的有效方法之一。其出發點基於物理中固體物質的退火過程。模擬退火是一種通用的優化算法,其物理退火過程由加溫過程、等溫過程、冷卻過程三部分組成。
基本上就是選一個初解,然后簡單變化得到新解,如果可以更新就更新,不能就按概率更新,然后持續操作,最后收斂到最優解。
來自\(Chhokmah\)的解釋:
我們還是爬山算法,還是判斷當前答案是不是更優,但是我們加的操作是:如果不是更優,那么我們就來一個繼續迭代的概率,這個概率會隨着整體的程序越變越小。
做一個比喻:
爬山算法是一個瞎的兔子,要跳到最高的山峰,他跳着跳着發現路開始向下了,他就不跳了。
模擬退火是一個喝醉的兔子,要跳到最高的山峰,他一直在跳,越跳越清醒,最后調到了最高的地方。
參數:
- \(T_0\):冷卻初始溫度
- \(T\):當前的溫度
- \(T_k\):冷卻目標溫度
- \(\alpha\):表示溫度的降低后相對原溫度的比值,一般是\(0.95\sim0.99\),讓物體慢慢降溫
- \(x\):當前解
- \(x'\):當前的解
- \(\Delta\):表示答案的變化值
每次比較差值隨機出來的答案是不是在范圍內,越到后面隨機的答案就越小。
陷入局部最優增大\(T_0\)和\(\alpha\),精度不夠減小\(T_k\)。有的時候也會采取在\(T\)降至\(T_k\)以下時多次尋找新答案,感覺上會提高正確性,這一點感性理解一下,畢竟都是玄學。
實現:
- 由一個產生函數從當前解中產生一個位於解空間的新解,然后由當前解通過簡單變換產生新解。
偽代碼:
生成初解x
while(T>Tk)
隨機生成新解x'
delta=f(x')-f(x)
if 答案更優
更新最優答案
else if exp(-delta/T)>rand(0,1)
更新當前答案
T=T*alpha
例題:
正解是個物理題。不過模擬退火也能做,算一下勢能,如果平衡的話勢能會最小,如果沒到最小那么向勢能指向方向移動更優,然后模擬退火一波,不斷調整即可。
兩部分的話默認前一半是第一部分的,后面是第二部分,然后算一下兩個的差,隨機再修改交換,退火就完事了。雖說折半搜索好像也可以。
這個題似乎用退火最容易過,隨機拿出來一個放到其他地方,開始可以找最低的位置放,其次可以隨機調整其他的,復雜度很低,一發就過了。