• POJ 1379Run Away解题报告


    模拟退火,第一次做模拟退火,搞了好几天才明白原理是怎么回事,启发式算法,运行时程序不稳定,会有一定的概率性,这些启发式算法有很多共同的特点,百度百科里有对启发式算法的简单介绍,数学中国网有很多模拟退火和其他启发式算法的很多资料,主要是数学建模方面的,但是知识都是互通的,学一学也很好,http://baike.baidu.com/view/476038.htm

    其实看程序就比较好理解启发式算法的思想了,但是我找了很多解题报告,发现都没有出现概率性选择并不是最优解的解决办法,有的利用了同时产生好几个点,利用并发性,这也不能算是概率性选择,还是搞不太明白怎么办。但是就这道题说还是比较简单的,确定步长,减小速度为0.9,因为精度比较低,所以就比较好办了。保存一个当前最优解集,利用随机性,步长和最优解集产生新的最优解集,最后得到的解有很大程度上不是最优解,但是对于这道题这个精度来说还是可以做到的。

    View Code
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<string>
     6 #include<ctime>
     7 #include<cstdlib>
     8 #define inf 1e50
     9 using namespace std;
    10 const int NUM=20;
    11 const int RAD=1000;
    12 struct point
    13 {
    14     double x,y,val;
    15     point(){}
    16     point(double _x,double _y)
    17     {
    18         x=_x;
    19         y=_y;
    20     }
    21 };
    22 point p[10001],May[NUM],e1,e2;
    23 int n;
    24 double X,Y;
    25 double dis(point a,point b)
    26 {
    27     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
    28 }
    29 double judge(point t)//评价函数,得到点t的评价值val
    30 {
    31     double len=inf;
    32     for(int i=0;i<n;i++)
    33     len=min(len,dis(t,p[i]));
    34     return len;
    35 }
    36 double Rand(){return rand()%(RAD+1)/(1.0*RAD);}//随机产生0-1的浮点数
    37 point Rand_point(point a,point b)//在a,b框定的四边形内随机生成点
    38 {
    39     double xx=a.x+(b.x-a.x)*Rand();
    40     double  yy=a.y+(b.y-a.y)*Rand();
    41     point tmp=point(xx,yy);
    42     tmp.val=judge(tmp);
    43     return tmp;
    44 }
    45 void solve(double D)
    46 {
    47     May[0]=point(0,0);
    48     May[1]=point(X,Y);
    49     May[2]=point(0,Y);
    50     May[3]=point(X,0);
    51     //4个顶点的可能行较大,所以特殊构造
    52     for(int i=4;i<NUM;i++)
    53     May[i]=Rand_point(May[0],May[1]);//步骤2
    54     while(D>0.01)//步骤 3
    55     {
    56         for(int i=0;i<NUM;i++)
    57         for(int j=0;j<NUM;j++)
    58         {
    59             point tmp=Rand_point(point(max(0.0,May[i].x-D),max(0.0,May[i].y-D)),point(min(X,May[i].x+D),min(Y,May[i].y+D)));
    60             if(tmp.val>May[i].val)
    61             {
    62                 May[i]=tmp;
    63             }
    64         }
    65         D*=0.9;
    66     }
    67     point ans;
    68     ans.val=0;
    69     for(int i=0;i<NUM;i++)
    70     if(May[i].val>ans.val)
    71     ans=May[i];
    72     printf("The safest point is (%.1f, %.1f).\n",ans.x,ans.y);
    73 }
    74 int main()
    75 {
    76     srand(time(0));
    77     e2=point(0,0);
    78     int Case;
    79     int i;
    80     scanf("%d",&Case);
    81     while(Case--)
    82     {
    83         scanf("%lf%lf%d",&X,&Y,&n);
    84         for(i=0;i<n;i++)
    85         {
    86             scanf("%lf%lf",&p[i].x,&p[i].y);
    87         }
    88         solve(max(Y,X));
    89     }
    90     return 0;
    91 }
  • 相关阅读:
    案例分析:从一则笑话分析需求的陷阱
    2019寒假培训第二天
    2019寒假培训第一天
    牛客网国庆集训派对Day6 题目 2018年
    unique STL讲解和模板
    SPFA 模板
    ACM Shenyang Onsite 2016 题目
    牛客网国庆集训派对Day5 题目 2018年
    The North American Invitational Programming Contest 2017 题目
    牛客网国庆集训派对Day4题目 2018年
  • 原文地址:https://www.cnblogs.com/caozhenhai/p/2713280.html
Copyright © 2020-2023  润新知