今天第一次寫模擬退火,只交了兩遍就a了,好凱森啊(/≧▽≦)/
題目描述位址
farmer john有n只奶牛,(4 <= n <= 12,其中n是偶數).
他們建立了一套原生的系統,使得奶牛與他的朋友可以通過由乾草保護的線路來進行對話交流.
每一頭奶牛在這個牧場中正好有3個朋友,並且他們必須把自己安排在一排乾草堆中.
一條長l的線路要占用剛好n堆乾草來保護線路.
比如說,如果有兩頭奶牛分別在草堆4與草堆7中,並且他們是朋友關係,那麼我們就需要用3堆乾草來建造線路,使他們之間能夠聯絡.
假設每一對作為朋友的奶牛都必須用一條單獨的線來連線,並且我們可以隨便地改變奶牛的位置,請計算出我們建造線路所需要的最少的乾草堆.
輸入格式:
第1行:乙個整數n. 為了方便,我們給奶牛用1~n的數字進行編號.
第2..1+n: 每一行都有三個在1~n中的整數. 第i+1行的數字代表著第i頭奶牛的三個朋友的編號。顯然,如果奶牛i是奶牛j的三個朋友之一,那麼奶牛j也是奶牛i的三個朋友之一.
輸出格式:
乙個整數,代表著建造線路需要的乾草堆數量的最小值.
我們先很容易知道,對於乙個已經知道的序列,我們可以在o(n
)o(n)
o(n)
的時間內算出答案,但是不清楚最優解是那個序列,暴力列舉o(n
!)
o(n!)
o(n!
)過不了,但是我們又不會正解假裝不會⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄,那麼就可以使用模擬退火啦!就是乙個隨機化演算法,模擬物理上的金屬加熱退火的過程。
我們最開始設定乙個初始溫度t
tt,然後設定退火因子δ
\delta
δ,其中0≤δ
≤1
0\leq\delta\leq 1
0≤δ≤
1,每次的溫度變化就為t=δ
×t
t=\delta\times t
t=δ×
t,直到t
st ts為止。 然後我們每次基於當前較優序列,隨機交換幾個,然後去計算答案,如果答案更優秀,那麼直接更新最終答案,然後將當前序列設定為當前較優序列,否則我們以eδe kt e^}ek tδe 的概率接受當前的次優解,但不是拿當前的答案去更新最終答案,而是將當前的序列看成當前較優序列,然後我們重複這樣,退個幾次火,就有很大的概率得到正確答案啦!看臉演算法 **如下:#include
#include
#include
#include
#define db double
#define ll long long
using
namespace std;
const ll inf=
0x7fffffffll
;const
int n=15;
const db eps=
1e-4
;int n;
int pf[n]
,rf[n]
,bst[n]
;ll abs
(ll a)
struct edge
edge()
edge
(int a,
int b,
int c):i
(a),
j(b),k
(c)}cow[n]
;db t,delta=
0.995
;//退火因子
ll ans=inf;
void
init()
ll calc_ans()
if(cow[i]
.j>i)
if(cow[i]
.k>i)
}return now;
}void
sim_an()
for(
int i=
1;i<=n;i++
)rf[pf[i]
]=i;
ll now=
calc_ans()
; ll diff=now-ans;
if(diff<0)
elseif(
exp(-(
1.0*diff)
/t)*rand_max>
rand()
) t*
=delta;}}
void
solve()
intmain()
模擬退火演算法
w 模擬退火演算法的基本思想 將乙個優化問題比擬成乙個金屬物體,將優化問題的目標函式比擬成物體的能量,問題的解比擬成物體的狀態,問題的最優解比擬成能量最低的狀態,然後模擬金屬物體的退火過程,從乙個足夠高的溫度開始,逐漸降低溫度,使物體分子從高能量狀態緩慢的過渡到低能量狀態,直至獲得能量最小的理想狀態...
模擬退火合集
首次接觸模擬退火 看來還是挺神奇的。主要參考這篇博文 題意判斷多邊形內部能否容納乙個半徑為r的圓,即在有限的平面內找最優範圍。遺傳演算法的結果難以掌控,爬山演算法又沒法保證跳出區域性最優,所以基於貪心原則的模擬退火演算法還是值得考慮的。然後就是設定每次變化的步長和演化方式。該題可以從每條邊的中點開始...
模擬退火演算法
一些求解極值的問題不能通過函式特性直接求解,只能暴力列舉,但是單純的列舉效率不高,通過模擬退火演算法可以高效的找到答案。學習好博文 最小圓覆蓋 hdu 3007 buried memory 大意 給出一些點,求出能覆蓋他們的最小的圓。輸出圓心和半徑 include include include i...