模拟退火基础题
题目:找出一点,距离所有所有点的最短距离最大
随机化步长
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#define pi acos(-1.0)
using namespace std;
const int M = 1000+10;
const int N = 30+5;
const int NUM = 20;
int x,y,m;
struct point
{
double x;
double y;
double dis;
point(double a,double b):x(a),y(b) {}
point(){}
}p[M],pp[N];
double dist(point a,point b)
{
double ans = 0;
ans+=(a.x-b.x)*(a.x-b.x);
ans+=(a.y-b.y)*(a.y-b.y);
return sqrt(ans);
}
double getDis(point a)
{
double ans = 1e9;
for(int i=1;i<=m;i++)
ans = min(ans,dist(a,p[i]));
return ans;
}
void init()
{
for(int i=1;i<=NUM;i++)
{
int tx = rand()%x ;
int ty = rand()%y ;
pp[i].x = tx;
pp[i].y = ty;
pp[i].dis = getDis(pp[i]);
}
}
int check(double xx,double yy)
{
if(xx>=0&&xx<=x && yy>=0 &&yy<=y)
return 1;
return 0;
}
int main()
{
int t;
cin>>t;
while(t--)
{
scanf("%d%d%d",&x,&y,&m);
for(int i=1;i<=m;i++)
scanf("%lf%lf",&p[i].x,&p[i].y);
init();
double r=0.9;
double T = 1e3;
double Tmin = 0.001;
while(T > Tmin)
{
for(int i=1;i<=NUM;i++)
{
double px = pp[i].x;
double py = pp[i].y;
for(int j=1;j<=30;j++){
double ran = ( rand()%1000 )*1.0 / 1000 *2 * pi;
double tx = px + cos(ran)*T;
double ty = py + sin(ran)*T;
point tmp(tx,ty);
if(check(tx,ty))
{
double dis = getDis(tmp);
double dis0 = pp[i].dis;
if(dis0 < dis){
pp[i]=tmp;
pp[i].dis=dis;
}
}
}
}
T*=r;
}
point ans=pp[1];
for(int i=2;i<=NUM;i++)
if(ans.dis < pp[i].dis)
ans = pp[i];
printf("The safest point is (%.1f, %.1f).\n",ans.x,ans.y);
}
return 0;
}