爬山演算法與模擬退火演算法

2021-10-04 00:09:24 字數 3341 閱讀 3023

模擬退火演算法

爬山演算法是一種基於貪心的搜尋方法,其原理是每次前往最佳的相鄰狀態。由於一般的搜尋問題無法看作結點數有限的圖,因此這裡的相鄰其實不是圖的那種相鄰。

以搜尋二維平面上的乙個點為例。設 f(x

,y

)f(x, y)

f(x,y)

表示座標為 (x,

y)

(x, y)

(x,y

) 的點的權值,現在要找到乙個 (x,

y)

(x, y)

(x,y

) 使得 f(x

,y

)f(x, y)

f(x,y)

最大。使用爬山演算法解決這個問題的方法如下:

隨機乙個點 (x0

,y0)

(x_0, y_0)

(x0​,y

0​) 作為起始點;

找到與當前點的距離為 l

il_i

li​ 的點中 f

ff 最大的點,如果它的權值不及當前點,則把當前點作為答案返回;

重複步驟 2,直到在步驟 2 中返回。

這裡有幾個問題:

距某點 l

il_i

li​ 的點有無窮多個,怎麼找呢?事實上,應該將「找乙個圓周上的點」換成「在八個方向中找乙個點」;

l

il_i

li​ 取多少?一般而言,一開始 l

il_i

li​ 比較大,越到後面 l

il_i

li​ 越小;

爬山演算法通常會陷入區域性最優解,無法找到真正的全域性最優解。

上面的例子中,我們給定了乙個 f(x

,y

)f(x, y)

f(x,y)

,這是乙個顯式的評估函式。但很多問題中沒有給乙個顯式地評估函式,這時需要我們自己去構造。

例如,我們要使用爬山演算法解決 n

nn 皇后問題,我們就得自己設定乙個對局面的評估函式,比如可以設 h(x

)h(x)

h(x)

表示局面 x

xx 下能夠相互攻擊的皇后對的數量。顯然,若 h(x

)=

0h(x) = 0

h(x)=0

,則 x

xx 就是乙個解,我們可以使用爬山法去找估價函式的最小值點。

可見,與樸素的 dfs、bfs 不同,爬山演算法只保留當前局面,因此它能切實有效地節省記憶體。

往往,這意味著我們需要動態維護一些資訊,例如上面的 n

nn 皇后問題,我們能在放下皇后和移開皇后時用 o(1

)o(1)

o(1)

的時間複雜度計算估價函式的該變數,前提是我們要額外維護一些資訊。

對於上面說的 n

nn 皇后問題,考慮這樣的情況:假設我們定義「相鄰」為上下移動某一列的皇后進入的局面,完全有可能所有相鄰的局面都不滿足 h(x

)=

0h(x) = 0

h(x)=0

,這就是陷入了區域性最優解。可以在這時隨機移動幾個皇后,但這樣就有可能因為不斷進入區域性最優解而死迴圈,所以需要設定乙個這種操作的次數上限。

下面介紹幾種變種的爬山法。

從更好的相鄰局面中以優秀程度為概率隨便選乙個。這種方法可能會緩解陷入區域性最優解的問題。

隨機找鄰居,轉移到第乙個遇到的更好的鄰居。這種方法適用於兒子(鄰居)太多的情況。

如果失敗了就再來一次。這種方法好,它幾乎是完備的(如果目標總能被找到,則稱演算法是完備的)。

相比隨機重啟爬山法,我們選擇一開始就讓 k

kk 個爬山演算法同時執行,並且它們相互之間還能傳遞資訊。假設這 k

kk 個當前局面共有 m

mm 個鄰居,我們就在這 m

mm 個鄰居中選 k

kk 個最好的作為這 k

kk 個爬山演算法的新局面。這個方法看上去能很快找到最優解,但它很容易一起陷入區域性最優解,並不太好。在此基礎上可以引出遺傳演算法。由於遺傳演算法好像暫時不太實用,所以這裡就不記了。

模擬退火演算法可以看作是爬山演算法的改進,也可以看作是受退火的啟發而發明的演算法。退火:加熱金屬然後使其慢慢冷卻,讓金屬原子重排使得能量最低。如果貿然降低溫度,可能重排得不好,能量不是最低的,所以要緩緩降溫。(這個解釋不具專業性,不保證正確性)

考慮這樣的事情:每次我們都隨機遊走,這樣,我們的演算法總是完備的,但不能在有限時間內得出解。將隨機遊走與爬山演算法相結合,我們就能得到模擬退火演算法。

隨機乙個局面 x

0x_0

x0​ 作為起始局面;

隨機乙個鄰居 xi+

1x_

xi+1

​。這個鄰居與 x

ix_i

xi​ 的「距離」應該隨著「時間」(操作次數)的推移而減小。當這個鄰居已經是最優解,或者時間過長,則退出;

如果鄰居比當前局面更優,則跳到鄰居,否則,以一定概率跳到鄰居。然後回到步驟 2。

這裡有幾個問題:

距離是什麼?距離可能可以很抽象,這裡只舉乙個形象的位置,就是二維平面上兩點的歐幾里得距離;

距離減少應該服從什麼規律?可以選擇每次乘以 ρ(0

<

ρ<1)

\rho \pod

ρ(0<

ρ<1)

;「一定概率」是多少?

這裡的一定概率一般不亂設定。我們可以設估價函式,假設我們要找估價函式的最小值點,則可以注意到 h(x

i)−h

(xi+

1)

<

0h(x_i) - h(x_) < 0

h(xi​)

−h(x

i+1​

)<

0,我們取概率為:

p

(即使鄰居更差也跳到鄰居)=

eh(x

i)−h

(xi+

1)

tp(\text) = \mathrm e^)}}

p(即使鄰居更差也跳到鄰居)=

eth(

xi​)

−h(x

i+1​

)​其中,t

tt 是「溫度」,隨著時間的推移會越來越小,可以就取跳躍步長。可以發現,隨著 t

tt 的不斷減小,我們越來越不可能跳到更差的鄰居,也就是說溫度越低,我們的狀態也就越穩定了。而在開始時,溫度很高,我們有很多機會跳離區域性最優解。具體實現時,可以使用 c++ 的二項分布std::binomial_distribution來生成決策,比較方便。

與爬山演算法相比,模擬退火演算法的隨機體現在兩方面。一是隨機選鄰居,二是隨機跳到更差的鄰居。

與爬山法類似,使用隨機重啟模擬退火使得演算法近乎完備。甚至可以嘗試使用多執行緒同時跑,只可惜 oj 不支援。注意使用多執行緒時的執行緒安全問題。

模擬退火 爬山演算法 模板

學習部落格 題目鏈結 玄學演算法。一開始不知道調參wa到懷疑人生 後來嘗試改一下delta竟然過了。退火和爬山的區別其實就是當沒有更優解的時候退火會以乙個概率來接收,爬山就不接受。所以把else if exp res temp t rand max rand 注釋掉就是爬山了。pragma gcc ...

演算法 模擬退火演算法

模擬退火演算法 一 簡單介紹 於固體退火原理,是一種基於概率的演算法。物理學解釋 將固體加溫至充分高,再讓其徐徐冷卻,加溫時,固體內部粒子隨 溫公升變為無序狀,內能增大,而徐徐冷卻時粒子漸趨有序,在每個溫度都達到 平衡態,最後在 常溫時達到基態,內能減為最小。模擬退火演算法從某一較高初溫出發,伴隨溫...

模擬退火演算法

w 模擬退火演算法的基本思想 將乙個優化問題比擬成乙個金屬物體,將優化問題的目標函式比擬成物體的能量,問題的解比擬成物體的狀態,問題的最優解比擬成能量最低的狀態,然後模擬金屬物體的退火過程,從乙個足夠高的溫度開始,逐漸降低溫度,使物體分子從高能量狀態緩慢的過渡到低能量狀態,直至獲得能量最小的理想狀態...