模拟退火

在这里插入图片描述

模拟退火是用来解决上述问题的一种概率搜索算法,如果我们只是用普通的二分的话,那么可能遇到陷入A这个局部极大值的解,而无法找到B这个全局最大值。

而模拟退火的精髓就在于有一定的概率在A这个位置的时候接受D这个位置的解,从而越过了这个局部极大值。

算法模型:

在这里插入图片描述

应用到ACM的时候一般都是解决最优解问题,但是这个是有概率性的,可能AC也可能WA。但是只有退火设置的较好,正确性是特别高的。
在这里插入图片描述
E ( x n e w ) E(x_{new}) E(xnew)为新解的贡献, E ( x o l d ) E(x_{old}) E(xold)为旧解的贡献,他们之差是负的时候,说明新解较差,以一定的概率接受新解。

Metropolis准则表明,在温度为T时,出现能量差为dE的降温的概率为P(dE),表示为:P(dE) = exp( dE/(kT) )。其中k是一个常数,exp表示自然指数,且dE<0。所以P和T正相关。这条公式就表示:温度越高,出现一次能量差为dE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于dE总是小于0(因为退火的过程是温度逐渐下降的过程),因此dE/kT < 0 ,所以P(dE)的函数取值范围是(0,1) 。随着温度T的降低,P(dE)会逐渐降低。

对于新点的产生,在温度特别高的时候左右波动的幅度特别大,之后在温度降低时逐渐变小,最后趋于平衡,这便是最优解。
如下图所示
在这里插入图片描述

普通的模拟退火不会接受差解,这样就不存在错过最优解。
完全的模拟退火会接受差解,这样可能得不到最优解。

降温一般选取0.97~0.99,越高越好,但是时间也会增大。

2018 ACM-ICPC 南京现场赛:最小球覆盖:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
#include<cmath>
#include<algorithm>
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define eps 1e-6
using namespace std;
const int NUM=30;
struct point{
	double x,y,z;
}A[35];
double MAX(double a,double b){
	return a>b?a:b;
}
double MIN(double a,double b){
	return a<b?a:b;
}
double dist(point a,point b){
	return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
 
int main()
{
	int n,i,j,k;
	while(scanf("%d",&n),n){
		for(i=0;i<n;++i){
			scanf("%lf%lf%lf",&A[i].x,&A[i].y,&A[i].z);
		}
		point center;int lm=0;
		center.x=center.y=center.z=0;
		double dmax=100,ans=inf;
		while(dmax>eps){
			for(i=0;i<n;++i){
				if(dist(center,A[i])>dist(center,A[lm]))lm=i;
			}
			double d=dist(center,A[lm]);
			ans=MIN(ans,d);
			center.x+=(A[lm].x-center.x)/d*dmax;//逐步向最远点移动,摆动的幅度随着dmax的减小而减小
			center.y+=(A[lm].y-center.y)/d*dmax;
			center.z+=(A[lm].z-center.z)/d*dmax;
			dmax*=0.98;//0.97都不行至少0.98 , 降温
		}
		printf("%.5lf\n",ans);
	}
	return 0;
}


2019WHU网络赛:https://blog.csdn.net/Link_Ray/article/details/89173222

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值