爬山算法/A Star not a Tree?

爬山算法是用来解决一个不规律函数的最值问题的一个算法,其基本算法是每一次向周围走一步,并比对一下是否更优,如果更优的话就更改目前的位置,如果不是的话就不进行更改。

但是爬山算法的劣势也是比较显然的,由于达到局部最优解之后就很难跳出这个区间最低点,所以很容易陷入局部最优解,盗一张图:

 

那么爬山算法就一点用也没有吗,不是的,我们为了提高正确性,我们可以随机的取几个点,分别进行该操作,最后取一个最好的结果,那么在很大概率下他是正确的,所以爬山算法的参数选择性是很重要的,而且一般只能解决函数分布比较均匀的题目。

例题:

A Star not a Tree?

题目大意:

 

给定一个N边形所有顶点坐标x,y,求其费马点到所有顶点距离和

 

费马点是指到多边形所有顶点距离和最小的点

这道题我们可以用爬山算法解决,考虑到正确率,我们可以随机选择多个点进行测试,我选择了五个,然后对于他们进行比较,取最优的一个。

对于每一个点,我们设定一个初始步数step,一般开的最好大一点,然后我们每一次向上下左右走这个步数,如果遇到更优的点就替换,没有就继续执行原来的点,并且步数要不断减小,当步数小于一定值的时候就停止操作。

尽管我们会陷入局部最优解,但是我们用多个点比对,还是很有可能找到最优解的。

最后,附上本题代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cstdlib>
 4 #include<algorithm>
 5 #include<ctime>
 6 using namespace std;
 7 
 8 struct node
 9 {
10     double x,y,d;
11 } a[110];
12 int n,T;
13 const int dtx[4]={0,1,0,-1},dty[4]={1,0,-1,0};
14 double ans;
15 
16 inline double pow2(double x)
17 {
18     return x*x;
19 }
20 inline double getdis(node u)
21 {
22     double dis=0;
23     for(int i=1;i<=n;i++) dis+=sqrt(pow2(u.x-a[i].x)+pow2(u.y-a[i].y));
24     return dis;
25 }
26 double solve()
27 {
28     node u;
29     u.x=rand()%10001,u.y=rand()%10001;
30     u.d=getdis(u);
31     double step=1e4;
32     while(step>1e-3)
33     {
34         node next,v;
35         next.x=u.x+dtx[0]*step;
36         next.y=u.y+dty[0]*step;
37         next.d=getdis(next);
38         for(int i=1;i<=3;i++)
39         {
40             v.x=u.x+dtx[i]*step;
41             v.y=u.y+dty[i]*step;
42             v.d=getdis(v);
43             if(v.d<next.d) next=v;
44         }
45         if(next.d<u.d) u=next;
46         step*=0.5;
47     }
48     return u.d;
49 }
50 int main()
51 {
52     srand(time(NULL));
53     scanf("%d",&T);
54     for(int Ti=1;Ti<=T;Ti++)
55     {
56         scanf("%d",&n);
57         for(int i=1; i<=n; i++) scanf("%lf%lf",&a[i].x,&a[i].y);
58         ans=1e16;
59         for(int i=1;i<=5;i++) ans=min(ans,solve());
60         printf("%.0lf\n",ans);
61         if(T!=Ti) printf("\n");
62     }
63     return 0;
64 }

 

posted @ 2019-03-23 14:31  于丰林  阅读(537)  评论(0编辑  收藏  举报