模擬退火與爬山法

未抑郁的刘大狗發表於2024-10-12

透過向 chatGPT-4o-mini 提問,我注意到所有爬山法可以解決的問題模擬退火都可以解決,所以爬山法死了我不想學爬山法。

具體的,對於一個多峰函式求解最值的題目都可以用模擬退火來做。

如果現在在較優解 \(x\),發現了一個新的解 \(x'\),如果 \(x'\)\(x\) 優那麼 \(x\gets x'\) 否則有一定機率接受 \(x'\),這就是模擬退火的核心思想。

考慮 \(x'\) 沒有 \(x\) 優秀的機率是怎麼計算的:

\(\Delta x=x-x'\),那麼我們就有 \(e^{\frac{\Delta x}{T}}\) 的機率更新 \(x\),其中 \(T\) 是當前的溫度。在進行了一次操作之後就進行降溫操作,即 \(T\gets T\times 0.999\)

下面的內容很重要!!!!!!

我們令新算出的結果為 \(f\),原本的答案為 \(lst\)

對於求解最小值的問題,取 \(\Delta=f-lst\),那麼:

  • 如果 \(\Delta<0\),那麼就直接接受。
  • 否則如果 exp(-del/t)>Rand(),那麼接受。

對於求解最小值的問題,一樣取 \(\Delta=f-lst\),那麼:

  • 如果 \(\Delta>0\),那麼就直接接受。
  • 否則如果 exp(del/t)>Rand(),那麼接受。

需要注意的是 exp(x)\(=e^x\),其中 \(x\) 就是自然函式,其影像如下:

發現對於 \(x>0\) 的情況 epx(x) 始終大於 \(1\),這個機率就是沒有意義的,所以 \(\Delta\) 的值一定是負數才有意義。

所以上面的公式在 epx 中是取 del 還是 -del 就十分好理解了,所以這並不需要死記硬背。

形象的,放一張從 OI-Wiki 偷的圖:

JSOI2004 平衡點 / 吊打XXX

練手題,但是題目太困難了,考慮給一個形式化題意:

找到一個 \((x,y)\) 使 \(\sum\limits_{i=1}^n dis((X_i,Y_i),(x,y))\times Weight_i\) 最小,輸出 \(x,y\)(可以是小數),其中 \(1\le n\le 1000\)

就是模板,按照上面的思路寫就行了。

AHOI2014/JSOI2014 保齡球

考慮每一次隨機交換 \(x,y\) 的位置,跑模擬退火就行了。

JSOI2016 炸彈攻擊

直接隨機放炸彈的位置,因為函式長得奇醜無比所以要求擾動的範圍較大,生成的時候需要使用:

double xx=(rand()*2-RAND_MAX)*t+x;

而不是:

double xx=(2.0*rand()/RAND_MAX-1)*t+x;

HAOI2006 均分資料

考慮先隨機分組,然後模擬退火隨機改變一個元素的分組就行了。

JSOI2008 球形空間產生器

設一個變數 \(r\),表示這個高維球體的半徑,由公式 \(r=\sqrt{\sum_{i=1}^n(a_i-b_i)^2}\) 可得 \(\sum_{i=1}^n(a_i-b_i)^2= r^2\),其中 \(a_i\) 是高維球面上某一個點的座標,\(b_i\) 是球心的座標。

化簡得:

\[\sum_{i=1}^n({a_i}^2-2a_ib_i+{b_i}^2)=r^2 \]

移項得:

\[\sum_{i=1}^n(-2a_ib_i)+\sum_{i=1}^n{b_i}^2-r^2=\sum_{i=1}^n({-a_i}^2) \]

其中 \(\sum_{i=1}^n{b_i}^2-r^2\) 與球面上的點無關,因此我們可以將其看做一個係數為 \(1\) 的變數,右邊是常量。

相關文章