HDU 5017 Ellipsoid 模拟退火第一题
为了补这题,特意学了下模拟退火算法,感觉算法本身不是很难,就是可能降温系数,步长等参数不好设置。
具体学习可以参见: http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html 我认为讲的很不错,通俗易懂。
这题设置一个step为1,降温系数为0.99,因为系数越大,得到最优解的概率越大,虽然可能会慢一点。因为是三维的,所以往八个方向扩展找邻域解,然后遇到比他优的解一定接受。
代码:(参照网上代码)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #define Mod 1000000007 #define eps 1e-8 using namespace std; int dx[8] = {0,0,1,-1,1,-1,1,-1}; int dy[8] = {1,-1,0,0,1,1,-1,-1}; double a,b,c,d,e,f; double dis(double x,double y,double z) { return sqrt(x*x + y*y + z*z); } double calc(double x,double y) { double A = c; double B = d*y+e*x; double C = f*x*y + a*x*x + b*y*y - 1.0; double delta = B*B-4.0*A*C; if(delta < 0.0) return Mod+10.0; //不在椭球上 delta = sqrt(delta); double soz1 = (-B + delta)/(2.0*A); double soz2 = (-B - delta)/(2.0*A); if(dis(x,y,soz1) < dis(x,y,soz2)) return soz1; return soz2; } double Simulated_Annealing() { double x = 0,y = 0,z = sqrt(1.0/c); //当前最优解 double step = 1.0, rate = 0.99; while(step > eps) { for(int k=0;k<8;k++) { double kx = x + step*dx[k]; double ky = y + step*dy[k]; double kz = calc(kx,ky); if(kz >= Mod) continue; if(dis(kx,ky,kz) < dis(x,y,z)) { x = kx,y = ky,z = kz; } } step *= rate; } return dis(x,y,z); } int main() { while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&e,&f)!=EOF) { printf("%.7f\n",Simulated_Annealing()); } return 0; }
作者:whatbeg
出处1:http://whatbeg.com/
出处2:http://www.cnblogs.com/whatbeg/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
更多精彩文章抢先看?详见我的独立博客: whatbeg.com