模拟退火小结

先扔个题
无法暴力枚举点,又不知道别的什么高级算法,怎么办呢?
欸嘿嘿,退火来咯
模拟退火,是用来解决一些寻找最优解的情况的,有的时候可以将问题转化成一个多峰函数求最值,然后模拟退火就派上用场了。
过程模拟了金属退火,先将金属炼至高温然后徐徐降温。
具体过程就是设一个初温\(T\),末温\(T_0\),以及每次温度下降的幅度\(\alpha\)
每次随机选取一个点,如果这个点比当前点的结果更优,就无条件接受这个点,否则以一定概率接受这个点。
概率一般用的是\(e^{\frac{-| \Delta |}{T} }\),可以理解成温度越低,接受这个较劣解的概率越小。
大概板子长这样(db->double):

inline void SA(){
	db x=stx,y=sty;
	db T=初温;
	while(T>T0){
		db X=x+(rand()*2-RAND_MAX)*T;
		db Y=y+(rand()*2-RAND_MAX)*T;
		db now=calc(X,Y),deta=now-ans;
		if(较优(deta<0\deta>0)){
			接受;(x=X,y=Y,ans=now);
		}else if(exp(-deta/T)*RAND_MAX>=rand())接受;
		T*=alp;
	}
}

一般模拟退火搭配卡时食用:

while(1.0*clock()/CLOCKS_PER_SEC<=MAX_TIME)SA();

但是,有的时候退火不能乱用,比如2.16T2用退火可以得到10pts的高分(或许退火处理这种问题范围比较小?),考试还是不能只依赖退火,该想的暴力还是要自己想!

posted @ 2022-02-16 19:14  letitdown  阅读(79)  评论(0编辑  收藏  举报