P1337 [JSOI2004]平衡点 / 吊打XXX
题目链接
题意分析
这道题正解是啥我不清楚 我只是来联系一下模拟退火
关于模拟退火要注意的几点
1.初始温度\(T\) 以及每一次降温的比例\(ΔT\)
2.如果当前可以取代最优解的话 就取代
否则的话 就按照多项式复杂度\(e^{\frac{Δf}{T}}\)同\(\frac{rand()}{RAND_MAX}\)比较 大于的话 我们就修改
因为这样可以防止我们执着于较优解而忽略了最优解
3.退火的总次数 当然是越多越好了
CODE:
#include
#define eps 1e-3
#define N 2010
using namespace std;
int n;
double ansx,ansy,answ;
const double down=0.995;
struct Node
{
double x,y,w;
}e[N];
double getdis(double ax,double ay,double bx,double by)
{return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));}
double getans(double x,double y)
{
double tmp=0;
for(int i=1;i<=n;++i) tmp+=getdis(x,y,e[i].x,e[i].y)*e[i].w;
return tmp;
}
void SA()
{
double T=3000;
double nowx=ansx,nowy=ansy,noww=answ;
while(T>1e-15)
{
double tx=nowx+(rand()*2-RAND_MAX)*T;
double ty=nowy+(rand()*2-RAND_MAX)*T;
double tw=getans(tx,ty);
if(twrand())
{
nowx=tx;nowy=ty;noww=tw;
}
T*=down;
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%lf%lf%lf",&e[i].x,&e[i].y,&e[i].w);
ansx+=e[i].x;ansy+=e[i].y;
}
ansx/=n;ansy/=n;answ=getans(ansx,ansy);
SA();SA();SA();SA();
printf("%.3lf %.3lf\n",ansx,ansy);
return 0;
}