zoukankan      html  css  js  c++  java
  • poj 1379 模拟退火法

    /*
    模拟退火法:
      找到一些随机点,从这些点出发,随机的方向坐标向外搜索;
      最后找到这些随机点的最大值;
      坑://if(xx>-eps&&xx<x+eps&&yy>-eps&&yy<eps+y) {不知道为什么这个判断方式错误??????
    */
    #include<iostream>
    #include<cstdio>
    #include<math.h>
    #include<algorithm>
    #define pi acos(-1.0)
    #define N  1100
    #define inf  1000000000000
    #define eps  1e-8
    using namespace std;
    double  x,y;
    int n;
    struct node {
    double  u,v,dis;
    }f[N],endd,ff[N];
    double diss(double x,double y,int i) {
      return sqrt((x-f[i].u)*(x-f[i].u)+(y-f[i].v)*(y-f[i].v));
    }
    double Mindis(double x,double y) {
      double  minn=1.0*inf,ss;
      int i;
      for(i=1;i<=n;i++) {
            ss=diss(x,y,i);
        if(minn>ss)
            minn=ss;
      }
      return minn;
    }
    void compute() {
      int i,j;
      double xx,yy;
      for(i=1;i<=20;i++) {//先随机出来一些点
        ff[i].u=(rand()%1000+1)/1000.0*x;
        ff[i].v=(rand()%1000+1)/1000.0*y;
        ff[i].dis=Mindis(ff[i].u,ff[i].v);
      }
      double T=sqrt(1.0*x*x+1.0*y*y);
      double rate=0.9;
      while(T>eps) {
        for(i=1;i<=20;i++)//对于这些点分别向外搜
        for(j=1;j<=30;j++) {//随机30个半径来搜索,更新,得到每个点可以到达的最远距离
            double ran=(rand()%1000+1)/1000.0*pi*10;
            xx=ff[i].u+cos(ran)*T;
            yy=ff[i].v+sin(ran)*T;
         //if(xx>-eps&&xx<x+eps&&yy>-eps&&yy<eps+y) {不知道为什么这个判断方式错误??????
         if(xx<0.0||xx>x||yy<0.0||yy>y)continue;
            double di=Mindis(xx,yy);
            if(ff[i].dis<di) {
            ff[i].dis=di;
            ff[i].u=xx;
            ff[i].v=yy;
             }
         }
        T*=rate;//退火率
      }
      for(i=1;i<=20;i++)//找到最大的一个
        if(endd.dis<ff[i].dis)
        endd=ff[i];
      return ;
    }
    int main() {
       //  printf("%d
    ",(rand()%1000+1)/1000.0*2*pi);
         int m,i,j,k,t;
         scanf("%d",&t);
         while(t--) {
            scanf("%lf%lf%d",&x,&y,&n);
            for(i=1;i<=n;i++)
                scanf("%lf%lf",&f[i].u,&f[i].v);
                endd.dis=-1;
                compute();
                printf("The safest point is (%.1f, %.1f).
    ",endd.u,endd.v);
         }
    return 0;
    }
    

  • 相关阅读:
    线程中测试getName方法和getId方法
    编写一个线程改变窗体的颜色
    创建两个线程分别输出1-100
    输出一个目录中的内容
    file占用字节
    MAP集合选出最大值
    使用增强for循环遍历集合
    数据框中的基本操作
    列表的基本操作
    因子的基本操作
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410615.html
Copyright © 2011-2022 走看看