前言
爬山法和模拟退火都为随机化算法,考场想不到正解时可用来骗分,通常效果较好。模拟退火是基于爬山法的优化。
一、爬山法
爬山法是一种贪心算法,在有限时间内很快找到局部最优解,可用来求解单峰函数极值。
1.算法步骤
随机选出一个点,每次向最大(最小)方向更新,直到找到极值位置。
Q:为什么单峰函数不用三分?
A:在多维问题中需要三分套三分求解,复杂度过高。
2.算法局限性
如下图所示:图片来源
若当前问题的函数不是单峰,则爬山法只能寻找到局部最优解,不一定能寻找到全局最优解
下面的模拟退火能更好地解决此类问题 。
二、模拟退火
模拟退火来源于物理模型———固体退火原理,是一种基于概率的算法。物理模型详细解释
通过赋予搜索过程一种时变且最终趋于零的概率突跳性,从而可有效避免陷入局部极小并最终趋于全局最优的串行结构的优化算法,能快速在有限集合中以较大的概率找到全局最优解。
1.算法步骤
(1).定义温度T使之指数级别衰减(有些题可理解为步长)
初始温度T0 终止温度TE
衰减系数(0,1)一般取接近1的数
衰减系数越接近1,衰减越慢
(2).随机选择一个点P,并计算出此点函数值
(3).每次迭代时在当前范围内随机选出一个新点NP,计算出NP函数值并与P函数值比较,定义 Δ \Delta ΔE=f (NP)-f ( P ),若满足要求则由旧点跳到新点,否则以一定概率跳过去
上图以求最小值为例
(4).随着温度降至终止温度,算法结束,找到全局最优解
(5).为提高准确率,将以上过程重复若干次
下图为算法运行过程
2.注意点
(1).局限性:1.有时运行效率较低
2.有一定概率出错
(2).要求:方案或函数空间具有一定连续性
3.例题
求费马点
题面:平面内有 n 个点,给出 n 个点的坐标,请你找出一个点,使得该点到这 n 个点的距离之和最小,答案四舍五入取整。
板子题,核心代码如下:
void simulate_anneal(){
node now;
now.x=randd(0,10000);//坐标范围边界
now.y=randd(0,10000);
for(double t=1e4;t>=1e-4;t*=0.99){
//温度
//初始温度:1e4 终止温度1e-4 衰减系数0.99
node np;
np.x=randd(now.x-t,now.x+t);
np.y=randd(now.y-t,now.y+t);
double delta=getans(np)-getans(now);//求解距离
if(exp(-delta/t)>randd(0</