加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

poj1379 模拟退火

发布时间:2020-12-13 20:03:59 所属栏目:百科 来源:网络整理
导读:【题意】 地图中有N个陷阱,给出他们的坐标,求一个点,使得这个点到所有陷阱的最小距离最大。 【题解】 乍一看是二分,但没有好方法。 看到题目要求的精度为0.1,则自然想到了模拟退火。 模拟退火的流程大致如下 1、随即生成若干解 2、定下步长d,和降温速

【题意】

地图中有N个陷阱,给出他们的坐标,求一个点,使得这个点到所有陷阱的最小距离最大。

【题解】

乍一看是二分,但没有好方法。

看到题目要求的精度为0.1,则自然想到了模拟退火。

模拟退火的流程大致如下

1、随即生成若干解

2、定下步长d,和降温速度

3、开始模拟退火过程

【代码】

#include <iostream>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cstring>
using namespace std;
const double pi=acos(-1.0);
const double INF=1e20;
const double eps=1e-3;

double px[31],py[31],d[31],x[1005],y[1005];

double dist(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

int main()
{
    freopen("in.txt","r",stdin);
    int cc,X,Y,n,i,j,k;
    double theta,delta,tx,ty,td,dx,dy,ans,qx,qy;
    cin >> cc;
    srand((unsigned)time(NULL));
    while (cc--)
    {
        scanf("%d%d%d",&X,&Y,&n);
        for (i=1;i<=n;i++)
            scanf("%lf%lf",&x[i],&y[i]);
        for (i=1;i<=30;i++)
        {
            px[i]=double(rand()%1000+1)/1000.000*X;
            py[i]=double(rand()%1000+1)/1000.000*Y;
            d[i]=INF;
            for (j=1;j<=n;j++)
                d[i]=min(d[i],dist(px[i],py[i],x[j],y[j]));
        }
        delta=double(max(X,Y))/(sqrt(1.0*n));
        while (delta>eps)
        {
            for (i=1;i<=30;i++)
            {
                qx=px[i];qy=py[i];
                for (j=1;j<=30;j++)
                {
                    theta=double(rand()%1000+1)/1000.000*10*pi;
                    dx=delta*cos(theta);
                    dy=delta*sin(theta);
                    tx=qx+dx;ty=qy+dy;
                    if (tx<0 || tx>X || ty<0 || ty>Y)
                        continue;
                    td=INF;
                    for (k=1;k<=n;k++)
                        td=min(td,dist(tx,x[k],y[k]));
                    if (td>d[i])
                    {
                        d[i]=td;px[i]=tx;py[i]=ty;
                    }
                }
            }
            delta*=0.8;
        }
        ans=0;
        for (i=1;i<=30;i++)
            if (d[i]>ans)
            {
                k=i;
                ans=d[i];
            }
        printf("The safest point is (%.1lf,%.1lf).n",px[k],py[k]);
    }
    return 0;
}


(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读