poj 2069 Super Star——模拟退火(收敛)

题目:http://poj.org/problem?id=2069

不是随机走,而是每次向最远的点逼近。而且也不是向该点逼近随意值,而是按那个比例;这样就总是接受,但答案还是要取min更新。

不知那个比例是怎么算。不过如果直接随机走或者向那个方向随机走的话,就过不了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<ctime>
#include<cmath>
#include<cstdlib>
#define db double
#define ll long long
using namespace std;
const int N=35;
const db dc=0.997,eps=1e-17,INF=105;
int n;
db nx[N],ny[N],nz[N],px,py,pz,ans;
db dis(db x0,db y0,db z0,db x1,db y1,db z1)
{
  return sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1)+(z0-z1)*(z0-z1));
}
void SA(db T)
{
  db x=px,y=py,z=pz,pr=ans;int id;
  while(T>eps)
    {
      db d=0;
      for(int i=1;i<=n;i++)
    {
      db tmp=dis(x,y,z,nx[i],ny[i],nz[i]);
      if(tmp>d)d=tmp,id=i;
    }
      ans=min(ans,d);
      x=x+(nx[id]-x)/d*T;y=y+(ny[id]-y)/d*T;z=z+(nz[id]-z)/d*T;
      T*=dc;
    }
}
int main()
{
  srand(time(0));
  while(1)
    {
      scanf("%d",&n);if(!n)return 0;
      for(int i=1;i<=n;i++)
    scanf("%lf%lf%lf",&nx[i],&ny[i],&nz[i]),px+=nx[i],py+=ny[i],pz+=nz[i];
      px/=n;py/=n;pz/=n;
      for(int i=1;i<=n;i++)
      ans=max(ans,dis(px,py,pz,nx[i],ny[i],nz[i]));
      SA(10000);
      printf("%.5lf\n",ans);
    }
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/Narh/p/9878974.html
今日推荐