學習筆記 模擬退火

2022-09-09 14:48:32 字數 1751 閱讀 6560

什麼是模擬退火?(選自 oi wiki )

模擬退火是一種隨機化演算法。當乙個問題的方案數量極大(甚至是無窮的)而且不是乙個單峰函式時,我們常使用模擬退火求解。

模擬退火,顧名思義,是模擬「退火」的過程。當我們使用爬山演算法的時候,對於非單峰函式的情形容易陷入次優解。爬山演算法省略了最優解附近的非最優解從而想得到更優的答案,但是模擬退火試圖以一定概率接受這個解。這個事情的實現即為「模擬退火」演算法。(胡扯)

由於退火的過程有更多隨機的選擇因素,我們得到最優解的概率也會增加。

得到一組新解,我們有兩種選擇:接受或不接受。貪心告訴我們如果新狀態更優就接受,否則不接受。然而模擬退火演算法表示,如果新狀態更優,一定接受;否則以一定概率接受。

具體來說,如果當前溫度假設為 \(t\) ,新狀態(由舊狀態隨機得到,比如交換兩個數)與舊狀態能量之差為 \(\delta e \ge 0\) ,我們接受這個狀態的概率為:

\[p(\delta e)=\begin1\quad\quad\; 新狀態更優\\e^}\quad 新狀態更劣\end

\]模擬退火中有 \(3\) 個引數:初始溫度 \(t\) ,降溫係數 \(d\) ,終止溫度 \(t'\) 。

c++裡面自帶乙個函式clock(),返回的是程式執行時間(單位是微秒),除以clocks_per_sec就是執行秒數。所以我們可以這樣:

while (clock() / (1.0 * clocks_per_sec) <= 0.98) solve();
void solve() 

}res >>= 1;

if (res < ans) ans = res;

else if (exp(ans - res) / tp < double(rand()) / rand_max) swap(p[x], p[y]);

tp *= d;

}}

int chk(int x) 

void solve() else if (exp((ans - res) / tp) < double(rand()) / rand_max)

tp *= d;

}}

#include using namespace std;

const int maxn = 1010;

double tot, f[maxn][maxn], ans[maxn], cnt[maxn], dis[maxn];

int n;

void check()

tot /= n + 1;

for (int i = 1; i <= n + 1; i++) }}

int main()

} for (int i = 1; i <= n; i++) ans[i] /= n + 1;

for (double t = 1919.810; t >= 0.0001; t *= 0.99995)

for (int i = 1; i <= n; i++) printf("%.3f ", ans[i]);

return 0;

}

模擬退火真™是個玄學東西。

有興趣的可以做做 這個題單 。

祝你在考場上寫的退火都拿 \(\color}\)!(

模擬退火學習筆記

博主這個暴力騙分選手get到了 人生的本質 有一類函式,我們要求其的最低點 最高點 二分?三分?四五六七 分?哦涼涼了 先介紹乙個爬山 我們隨機撒點,然後讓這些點去做類似現實的爬山 即右邊優就去右邊,左邊優就去左邊 直到沒有比他更優秀的了!也就是相當於到山峰了吧 那麼這個貪心的演算法顯然非常容易卡在...

模擬退火學習筆記

網上的絕大部分部落格,包括洛谷題解原來都是錯的寫法 具體看轉移部分qwq 終於成為了少數派,這是好的 模擬退火演算法 simulate anneal,sa 是一種通用概率演演算法,用來在乙個大的搜尋空間內找尋命題的最優解。模擬退火是由s.kirkpatrick,c.d.gelatt和m.p.vecc...

學習筆記 模擬退火

一談到模擬退火,大家都知道是玄學演算法,但是他是如何 a 題的呢?模擬退火,即模擬金屬退火這一過程,來實現最優解的尋找。金屬退火,對於我們似乎很遙遠了,那我們舉個實際點的例子吧。學過化學的都知道,在蒸發結晶時,我們會在蒸發皿還有部分溶劑時停止加熱,用餘熱蒸乾剩餘液體。這就是乙個退火過程,它的實質就是...