首页 > 代码库 > POJ 1379 模拟退火算法
POJ 1379 模拟退火算法
求规定平面上一点到已知点的最小距离最大的点。
模拟退火的流程是,随机构造几组解作为初始解空间,每次对当前解空间进行随机扩展,若发现更优解则替换。
进行的次数由参数人为控制,而随机扩展的幅度也是随着次数逐渐减小的。
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<string> #include<vector> #include<algorithm> #include<map> #include<set> #include<ctime> using namespace std; #define eps 1e-2 double pi=acos(-1.0); double x[10004],y[10004]; double qx[10004],qy[10004]; double X,Y; int n; const int num=15; //初始解空间大小 const int numf=30; //扩展解空间大小 double dist(double x,double y,double xx,double yy) { return sqrt((x-xx)*(x-xx)+(y-yy)*(y-yy)); } double get(double xx,double yy) { double mins=1111111111; for(int i=1;i<=n;i++) mins=min(mins,dist(xx,yy,x[i],y[i])); return mins; } double getr() //返回[0,1]的浮点数 { return (rand()%10000+1.0)/10000.0; } int main() { srand(time(NULL)); //多次提交= =防RP差 int ca; scanf("%d",&ca); while(ca--) { scanf("%lf%lf%d",&X,&Y,&n); for(int i=1;i<=n;i++) { scanf("%lf%lf",&x[i],&y[i]); } for(int i=1;i<=num;i++) //构造初始解空间 { qx[i]=X*getr(); qy[i]=Y*getr(); } double dd=max(Y,X); //最大温度 while(dd>eps) { for(int i=1;i<=num;i++) { double now=get(qx[i],qy[i]),t; for(int j=1;j<=numf;j++) { double dt=getr()*2*pi; //随机角度 double tmpx=qx[i]+dd*cos(dt); double tmpy=qy[i]+dd*sin(dt); if(tmpx<0||tmpx>X||tmpy<0||tmpy>Y) continue; if((t=get(tmpx,tmpy))>now) //扩展新解 { qx[i]=tmpx; qy[i]=tmpy; now=t; } } } dd*=0.9; //冷却速度 } double mins=0; int k; for(int i=1;i<=num;i++) { double tmp=get(qx[i],qy[i]); if(tmp>mins) {mins=tmp;k=i;} } printf("The safest point is (%.1lf, %.1lf).\n",qx[k],qy[k]); } return 0; } /* 3 1000 50 1 10 10 100 100 4 10 10 10 90 90 10 90 90 3000 3000 4 1200 85 63 2500 2700 2650 2990 100 */
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。