日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

【学习笔记】我命由天不由我之随机化庇佑 —— 爬山法 和 模拟退火法

發(fā)布時(shí)間:2023/12/3 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【学习笔记】我命由天不由我之随机化庇佑 —— 爬山法 和 模拟退火法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

以下均假設(shè)最優(yōu)解是在最低點(diǎn)。

爬山法

爬山算法是一種局部擇優(yōu)的方法,采用啟發(fā)式方法,是對(duì)深度優(yōu)先搜索的一種改進(jìn),它利用反饋信息幫助生成解的決策。

直白地講,就是當(dāng)目前無(wú)法直接到達(dá)最優(yōu)解,但是可以判斷兩個(gè)解哪個(gè)更優(yōu)的時(shí)候,根據(jù)一些反饋信息生成一個(gè)新的可能解。

因此,爬山算法每次在當(dāng)前找到的最優(yōu)方案 xxx 附近尋找一個(gè)新方案。如果這個(gè)新的解 x′x'x 更優(yōu),那么轉(zhuǎn)移到 x′x'x,否則不變。

這種算法對(duì)于單峰函數(shù)顯然可行。

Q:既然都知道是單峰函數(shù)了為什么不三分呢?

A:你說(shuō)的對(duì)!直接三分好了。

B:我要是知道是單峰函數(shù),我還在這里騙分???

爬山算法會(huì)引入『溫度參數(shù)』 TTT。

類比的說(shuō),爬山就是一個(gè)醉漢喝得狂醉然后再山上裸奔蹦迪。

他知道該回家了(不然就要跪搓衣板),然后每次會(huì)往他認(rèn)為最低的地方狂奔過(guò)去(中途不剎車)。

顯然他可能一次恰好奔到山腳然后下山回家,也有可能奔過(guò)了到另一座山頂上去了。

不過(guò)沒(méi)關(guān)系,醉漢奔過(guò)頭了還會(huì)存在奔回來(lái)的可能。

但顯然這個(gè)過(guò)程很沒(méi)用。仿佛醉漢回家全靠天公作美。

所以在暴走過(guò)程中,他會(huì)經(jīng)受山頂寒風(fēng)的摧殘,酒精作用漸漸消減,他變得越發(fā)清晰。

他就變得謹(jǐn)慎一點(diǎn),每次少奔一點(diǎn)以達(dá)到山腳最低點(diǎn)位置。

這就要引入『降溫參數(shù)』來(lái)起到緩緩冷靜的作用。

關(guān)于『降溫參數(shù)』,一般是 [0.985,0.999][0.985,0.999][0.985,0.999] 中選,這樣才能做到慢慢消減。

顯然如果存在多個(gè)”轉(zhuǎn)折“時(shí),爬山就很容易進(jìn)入局部最優(yōu)解,而非全局最優(yōu)解。

隨著頭腦逐漸清醒,醉漢蹦出局部最優(yōu)解的期望就會(huì)更小,很有可能一直跳不過(guò)去某個(gè)坡。

模擬退火

為什么會(huì)有上面情況的產(chǎn)生呢?

其實(shí)是因?yàn)榕郎椒ǖ膶懛?#xff0c;只有在新解優(yōu)于當(dāng)前解的時(shí)候,我們才會(huì)接受新解并移動(dòng)到相應(yīng)位置。

根據(jù)這種情況,我們知道其實(shí)偶爾新解不好我們也要去接受,這樣才會(huì)存在跳出這個(gè)坡的可能。

這就是模擬退火了。

模擬退火相較于爬山就只是多了一個(gè)隨機(jī)接受非最優(yōu)解的部分,大大增加了找到全局最優(yōu)解得可能。

以下是追根溯源,由物理和化學(xué)知識(shí)遷移到信息學(xué)上應(yīng)用:

我們知道在分子和原子的世界中,能量越大,意味著分子和原子越不穩(wěn)定,當(dāng)能量越低時(shí),原子越穩(wěn)定。

『退火』是物理學(xué)術(shù)語(yǔ),指對(duì)物體加溫在冷卻的過(guò)程。

模擬退火算法來(lái)源于晶體冷卻的過(guò)程,如果固體不處于最低能量狀態(tài),給固體加熱再冷卻,隨著溫度緩慢下降,固體中的原子按照一定形狀排列,形成高密度、低能量的有規(guī)則晶體(即全局最優(yōu)解)。

而如果溫度下降過(guò)快,可能導(dǎo)致原子缺少足夠的時(shí)間排列成晶體的結(jié)構(gòu),結(jié)果產(chǎn)生了具有較高能量的非晶體(即局部最優(yōu)解)。

因此就可以根據(jù)退火的過(guò)程,給其再增加一點(diǎn)能量,然后再冷卻,如果增加能量,跳出了局部最優(yōu)解,那么本次退火就是成功的。

模擬退火由兩個(gè)部分組成:Metropolis\text{Metropolis}Metropolis 算法和退火過(guò)程。

Metropolis\text{Metropolis}Metropolis 算法就是如何在局部最優(yōu)解的情況下讓其跳出來(lái),是退火的基礎(chǔ)。

Metropolis\text{Metropolis}Metropolis 提出的以概率來(lái)接受新?tīng)顟B(tài)的重要性采樣方法,而非使用完全確定的規(guī)則,稱為Metropolis\text{Metropolis}Metropolis 準(zhǔn)則,計(jì)算量較低。

假設(shè)我們從 AAA 開(kāi)始求解。先跳到 BBB,然后發(fā)現(xiàn) BBB 更優(yōu),絕對(duì)接受。BBB 又跳到 CCC,絕對(duì)接受。CCC 跳到 DDD ,哎呀更差了呢!此時(shí)我們以一定的概率選擇是否接受;假設(shè)接受,DDD 又跳到 EEE 發(fā)現(xiàn)比之前跳到的所有位置都優(yōu),直接接受,EEE 繼續(xù)跳……\dots\dots ;不接受,就還停在 CCC 又開(kāi)始隨機(jī)下一個(gè)解。

至于這個(gè)接受概率是多少呢?已經(jīng)有前人計(jì)算出來(lái)了。x:x:x: 當(dāng)前最優(yōu)解,x′:x':x: 產(chǎn)生的新解
P={1E(x′)<E(x)e?E(x′)?E(x)TE(x′)≥E(x)P=\begin{cases}1\quad\quad\quad\quad\quad\quad E(x')<E(x)\\e^{-\frac{E(x')-E(x)}{T}}\quad\quad\ E(x')\ge E(x)\end{cases} P={1E(x)<E(x)e?TE(x)?E(x)??E(x)E(x)?
從這個(gè)式子我們可以看出,如果新解更優(yōu),那么百分之百絕對(duì)接受;否則我們會(huì)以 PPP 的概率接受。

Metropolis\text{Metropolis}Metropolis 算法雖然說(shuō)是模擬退火算法的基礎(chǔ),但直接使用的話可能導(dǎo)致尋找解得速度太慢,以至于無(wú)法過(guò)題。

為了確保在有限的時(shí)間收斂,必須設(shè)定控制算法收斂的參數(shù)。

在上面的公式中,可以調(diào)節(jié)的參數(shù)就是『溫度參數(shù)』TTT。

  • TTT 如果過(guò)大,就會(huì)導(dǎo)致退火太快,迭代次數(shù)不夠,最后停留在局部最優(yōu)值就會(huì)結(jié)束迭代。
  • TTT 如果較小,則計(jì)算時(shí)間會(huì)增加。

實(shí)際應(yīng)用中采用退火溫度表,在退火初期采用較大的 TTT 值,隨著退火的進(jìn)行,逐步降低:

  • 初始的溫度 T0T_0T0? 應(yīng)選的足夠高,使的所有轉(zhuǎn)移狀態(tài)都被接受。初始溫度越高,獲得高質(zhì)量的解的概率越大,但耗費(fèi)的時(shí)間也越長(zhǎng)。

  • 退火速率。

    • 指數(shù)式下降:Tn=λTn,n=1,2,3,...T_n=\lambda T_n,n=1,2,3,...Tn?=λTn?,n=1,2,3,...。λ\lambdaλ 即是爬山算法里面的『降溫參數(shù)』,選取的值同樣遵守 <1<1<1 又逼近 111 原則。

      這種方式最常見(jiàn),且對(duì)每一溫度,有足夠的轉(zhuǎn)移嘗試,但其收斂速度比較慢。

    • 其它方式:

      • Tn=T0log?(1+t)T_n=\frac{T_0}{\log(1+t)}Tn?=log(1+t)T0??
      • Tn=T01+tT_n=\frac{T_0}{1+t}Tn?=1+tT0??。
  • 終止溫度。當(dāng) T0T_0T0? 迭代到終止溫度時(shí)就會(huì)結(jié)束退火。一般設(shè)為 eps=1e-k(k∈Z+k\in \Z^+kZ+)。

一般針對(duì)數(shù)據(jù)進(jìn)行『溫度參數(shù)』TTT,『降溫參數(shù)』Δ\DeltaΔ 的調(diào)參,在本地手造大數(shù)據(jù)跑,自己抉擇。

對(duì)時(shí)間和正確性的平衡選取。

有的時(shí)候可以用 #include <ctime> 庫(kù)里面自帶的 clock() 函數(shù)計(jì)時(shí),也可以自己定一個(gè)跑的次數(shù)。

( clock() / (1.0 * CLOCKS_PER_SEC) ) <= TIME //返回的是多少秒 所以TIME是個(gè) <1 的浮點(diǎn)數(shù)

需要注意是:

  • 初始溫度 T0T_0T0? 的選取對(duì)算法結(jié)果有一定的影響,最好是多次運(yùn)行對(duì)結(jié)果進(jìn)行綜合判斷。
  • 在算法運(yùn)行初期,溫度下降快,避免接受過(guò)多的差結(jié)果。當(dāng)運(yùn)行時(shí)間增加,溫度下降減緩,以便于更快穩(wěn)定結(jié)果。
  • 當(dāng)?shù)螖?shù)增加到一定次數(shù)時(shí),結(jié)果可能已經(jīng)達(dá)到穩(wěn)定,但是距離算法結(jié)束還有一段時(shí)間。在設(shè)計(jì)程序時(shí)應(yīng)該加入適當(dāng)?shù)妮敵鰲l件,滿足輸出條件即可結(jié)束程序。

最后給出流程圖總結(jié):又淘了一張好圖

顯然,模擬退火也不一定是對(duì)的,這個(gè)概率接受就很概率。但對(duì)比爬山得到最優(yōu)解的概率肯定是大大增加的。

例題

Strange function

hdu2899

TTT 次詢問(wèn),每次給定 yyy

f(x)=6x7+8x6+7x3+5x2?yx(0≤x≤100)f(x)=6x^7+8x^6+7x^3+5x^2-yx\quad(0\le x\le 100)f(x)=6x7+8x6+7x3+5x2?yx(0x100) 的最小值。

#include <bits/stdc++.h> using namespace std; double y; const double eps = 1e-8; //終止溫度 const double delta = 0.997; //溫度變化率 mt19937 wwl(time(0)); uniform_real_distribution < double > range( 0, 100 );double f( double x ) {return 6 * pow(x, 7) + 8 * pow(x, 6) + 7 * pow(x, 3) + 5 * pow(x, 2) - y * x; }double solve() {double T = 100, x = range( wwl ); //初始溫度 以及初始隨機(jī)解double now = f(x), ans = now;int Time = 8e5; //防止超時(shí)的卡點(diǎn)次數(shù)while( T > eps and Time -- ) { //要么降溫完成 要么被卡時(shí)double tx = x + (rand() * 2 - RAND_MAX) * T; //隨機(jī)擾動(dòng)產(chǎn)生新解if( 0 <= tx and tx <= 100 ) {double nxt = f(tx);ans = min( ans, nxt );if( nxt < now ) //新?tīng)顟B(tài)更小 直接接受x = tx, now = nxt;else if( rand() < exp( ( now - nxt ) / T ) * RAND_MAX ) //在一定概率內(nèi)仍接受這個(gè)解x = tx, now = nxt;}T *= delta; //降溫}return ans; }int main() {int T;scanf( "%d", &T );while( T -- ) {scanf( "%lf", &y );printf( "%.4f\n", solve() );}return 0; }

[JSOI2004]平衡點(diǎn) / 吊打XXX

洛谷鏈接

#include <bits/stdc++.h> using namespace std; #define delta 0.996 #define maxn 1005 #define eps 1e-15 struct node { int x, y, w; }g[maxn]; int n;double energy( double x, double y ) {double ans = 0, dx, dy;for( int i = 1;i <= n;i ++ ) {dx = x - g[i].x, dy = y - g[i].y;ans += sqrt( dx * dx + dy * dy ) * g[i].w;}return ans; }double ansx, ansy, ans, x, y, now; void Simulate_Anneal() {double T = 5e4;while( T > eps ) {double tx = x + (rand() * 2 - RAND_MAX) * T;double ty = y + (rand() * 2 - RAND_MAX) * T;double tw = energy( tx, ty );if( tw < ans ) ans = tw, ansx = tx, ansy = ty;if( tw < now ) x = tx, y = ty, now = tw;else if( rand() < exp( ( now - tw ) / T ) * RAND_MAX )x = tx, y = ty;T *= delta;} }signed main() {scanf( "%d", &n );for( int i = 1;i <= n;i ++ )scanf( "%d %d %d", &g[i].x, &g[i].y, &g[i].w );for( int i = 1;i <= n;i ++ ) x += g[i].x, y += g[i].y;x /= n, y /= n;ansx = x, ansy = y;now = ans = energy( x, y );Simulate_Anneal();Simulate_Anneal();Simulate_Anneal();Simulate_Anneal();printf( "%.3f %.3f\n", ansx, ansy );return 0; }

Haywire

洛谷鏈接

#include <bits/stdc++.h> using namespace std; #define TIME 0.9 #define eps 1e-10 #define delta 0.998 #define maxn 15 int n; int p[maxn]; int f[maxn][5];int energy() {int ans = 0;for( int i = 1;i <= n;i ++ )for( int j = 1;j <= 3;j ++ )ans += fabs( p[i] - p[f[i][j]] );return ans; }int main() {mt19937 wwl(time(NULL));scanf( "%d", &n );uniform_int_distribution < int > id( 1, n );for( int i = 1;i <= n;i ++ )for( int j = 1;j <= 3;j ++ )scanf( "%d", &f[i][j] );iota( p + 1, p + n + 1, 1 );int ans = energy();while( ( clock() / (1.0 * CLOCKS_PER_SEC) ) <= TIME ) {for( int i = 1;i <= n;i ++ ) p[i] = i;double T = 1e5; int x, y;while( T > eps ) {do { x = id( wwl ), y = id( wwl ); }while( x == y );swap( p[x], p[y] );int now = energy();if( now < ans ) ans = now;else if( rand() > exp( ( now - ans ) / T ) * RAND_MAX )swap( p[x], p[y] );T *= delta;}}printf( "%d\n", ans / 2 );return 0; }

學(xué)習(xí)參考博客:

https://www.cnblogs.com/flashhu/p/8884132.html

https://blog.csdn.net/weixin_42398658/article/details/84031235

https://zhuanlan.zhihu.com/p/266874840?utm_source=qq

總結(jié)

以上是生活随笔為你收集整理的【学习笔记】我命由天不由我之随机化庇佑 —— 爬山法 和 模拟退火法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。