Pentium.Labs

System全家桶:https://zhuanlan.zhihu.com/c_1238468913098731520

导航

hdu 5017 模拟退火

题意:给出椭球面的立体解析式,要求椭球面上距离原点最近的点的距离

 

sol:这题要想推公式就😶😶😶。。。【可以试试二元函数求极值

一种比较普遍的解法是模拟退火

模拟退火的解释可以参考这儿:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

 

模拟退火模板get:

 1 double sa()         //Simulated_Annealing
 2 {
 3     double x = 0,y = 0,z = sqrt(1.0/C);  //当前最优解
 4     double step = 1.0, rate = 0.99;      //step:系统温度    rate:控制降温的速度
 5     while(step > eps)
 6     {
 7         for(int k=0;k<8;k++)            //(x,y)可以向8个方向扩散,z直接用解析式算出,这样就保证了(x,y,z)一定在椭球面上
 8         {
 9             double kx = x + step*dx[k];
10             double ky = y + step*dy[k];
11             double kz = calc(kx,ky);
12             if(kz >= Mod) continue;     //不符合要求的筛掉
13             if(dis(kx,ky,kz) < dis(x,y,z))
14             {
15                 x = kx,y = ky,z = kz;
16             }
17         }
18         step *= rate;
19     }
20     return dis(x,y,z);
21 }

 

 

AC Code:

 1 #include<iostream>
 2 #include<cmath>
 3 using namespace std;
 4 int dx[10]={-1, 0, 1,1,1,0,-1,-1};
 5 int dy[10]={-1,-1,-1,0,1,1, 1, 0};
 6 double A,B,C,D,E,F;
 7 #define Mod 1000000007
 8 #define eps 1e-8
 9 
10 double dis(double x,double y,double z)
11 {
12     return(sqrt(x*x+y*y+z*z));
13 }
14 
15 double calc(double x,double y)
16 {
17     double tb=(D*y+E*x)*(D*y+E*x)-4*C*(A*x*x+B*y*y+F*x*y-1);
18     double ta=-D*y-E*x;
19     tb=sqrt(tb);
20     double tx=(ta+tb)/(2*C),ty=(ta-tb)/(2*C);
21     if(dis(x,y,tx)<dis(x,y,ty)) return tx;  else return ty;
22 }
23 
24 double sa()         //Simulated_Annealing
25 {
26     double x = 0,y = 0,z = sqrt(1.0/C);  //当前最优解
27     double step = 1.0, rate = 0.99;      //step:系统温度    rate:控制降温的速度
28     while(step > eps)
29     {
30         for(int k=0;k<8;k++)            //(x,y)可以向8个方向扩散,z直接用解析式算出,这样就保证了(x,y,z)一定在椭球面上
31         {
32             double kx = x + step*dx[k];
33             double ky = y + step*dy[k];
34             double kz = calc(kx,ky);
35             if(kz >= Mod) continue;     //不符合要求的筛掉
36             if(dis(kx,ky,kz) < dis(x,y,z))
37             {
38                 x = kx,y = ky,z = kz;
39             }
40         }
41         step *= rate;
42     }
43     return dis(x,y,z);
44 }
45 
46 
47 int main()
48 {
49     while(cin>>A>>B>>C>>D>>E>>F)
50     {
51         printf("%.7f\n",sa());
52     }
53     return 0;
54 }
View Code

 

 

Reference:

http://www.cnblogs.com/whatbeg/p/3975624.html

http://blog.csdn.net/zz_1215/article/details/40923313(zz大神的奇怪做法,orz)

 

posted on 2015-05-28 18:01  Pentium.Labs  阅读(174)  评论(0编辑  收藏  举报



Pentium.Lab Since 1998