模拟退火算法
来源:互联网 发布:虚拟机网络上有重名 编辑:程序博客网 时间:2024/06/14 07:01
一些求解极值的问题不能通过函数特性直接求解,只能暴力枚举,但是单纯的枚举效率不高,通过模拟退火算法可以高效的找到答案。
学习好博文:
http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html
相关题目:
最小圆覆盖:
hdu 3007 Buried memory
http://acm.hdu.edu.cn/showproblem.php?pid=3007
大意:给出一些点,求出能覆盖他们的最小的圆。输出圆心和半径
本想尝试做三分题,zoj 3421 Error Curves,但是发现不是超时,就是WA。
#include <iostream>#include <cstdio>#include <algorithm>#include <cmath>using namespace std;const double eps=1e-7,INF=1e99; // T: 初始温度 delta:下降速率const double T=10,delta=0.88; //一般地,T=100, delta=0.98const int N=5e2+10;struct point{ double x,y;}p[N],s;double dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));}double solve(int n){ s=p[0]; double t=T; double r=INF; while(t>eps){ int k=0; double d=0; for(int i=0;i<n;i++){ double f=dis(s,p[i]); if(f>d){ d=f; k=i; } } s.x+=(p[k].x-s.x)/d*t; s.y+=(p[k].y-s.y)/d*t; r=min(r,d); t*=delta; } return r;}int main(){ int n; while(~scanf("%d",&n)&&n){ for(int i=0;i<n;i++){ scanf("%lf %lf",&p[i].x,&p[i].y); } double r=solve(n); printf("%.2lf %.2lf %.2lf\n",s.x,s.y,r); } return 0;}
最小球包含
POJ 2069 Super Star
http://poj.org/problem?id=2069
大意:给出一些三维空间的点,求最小的包含他们的球的半径
#include <iostream>#include <cstdio>#include <cmath>using namespace std;const double T=100,delta=0.98; //下降速度一般设成0.98const double eps=1e-7,INF=1e99;struct point{ double x,y,z;}p[35],s;double dis(point a,point b){ return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));}double solve(int n){ s=p[0]; double t=T; double ans=INF; while(t>eps){ int k=0; for(int i=0;i<n;i++){ if(dis(s,p[i])>dis(s,p[k])){ k=i; } } double d=dis(s,p[k]); ans=min(ans,d); s.x+=(p[k].x-s.x)/d*t; //向量 s.y+=(p[k].y-s.y)/d*t; s.z+=(p[k].z-s.z)/d*t; t*=delta; } return ans;}int main(){ int n; while(cin>>n&&n){ for(int i=0;i<n;i++){ scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].z); } printf("%.5lf\n",solve(n)); } return 0;}
查找函数极值:
hdu 2899 Strange fuction
http://acm.hdu.edu.cn/showproblem.php?pid=2899
求解: F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) 的最小值
#include <iostream>#include <cstdio>#include <cmath>#include <stdlib.h>#include <algorithm>using namespace std;const double eps=1e-7,INF=1e99;const double T=100,delta=0.88; // 0.98 太慢了const int N=10;double x[N];double random(){ double x=rand()*1.0/RAND_MAX; if(rand()&1) x=-x; return x;}int jud(double a,double b){ if(fabs(a-b)<eps) return 0; if(a-b<-eps) return -1; return 1;}double calc(double x,double y){ return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*x*x-y*x;}double solve(double y){ for(int i=0;i<N;i++) x[i]=fabs(random()*100); double ans=INF; double t=T; while(t>eps){ for(int i=0;i<N;i++){ // change x[i] double temp=calc(x[i],y); for(int j=0;j<N;j++){ //times double xx=x[i]+random()*t; if(jud(xx,0)>=0 && jud(xx,100)<=0){ if(jud(temp,calc(xx,y))>0){ x[i]=xx; break; } } } } t=t*delta; } for(int i=0;i<N;i++) ans=min(ans,calc(x[i],y)); return ans;}int main(){ int t; double y; cin>>t; while(t--){ scanf("%lf",&y); printf("%.4lf\n",solve(y)); } return 0;}/*%.4lf\n2100-74.4291200-178.8534-------------%lf\n2100-74.429122200-178.853367*/
本想尝试做三分题,zoj 3421 Error Curves,但是发现不是超时,就是WA。
0 0
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火,遗传算法
- 模拟退火算法概述
- 模拟退火算法
- 遗传模拟退火算法
- 模拟退火遗传算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 解析模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- 模拟退火算法
- HDOJ 2041 超级楼梯
- HDU 3765 Celebrity Split(dfs走平分问题--递推)
- noj 1073 成绩排名
- 学习笔记
- 发表项目博客的格式要求
- 模拟退火算法
- 智能指针(一):STL auto_ptr实现原理
- 例题8-11 10954 - Add All全部相加
- 浅析postgresql数据库事务及行锁特征
- (有码)UI页面之间跳转方法
- PAT_乙级1002
- Meegopad、计算棒、光棍一号等,连接大容量移动硬盘的专用7*24小时资源共享经验
- 杂
- BZOJ 2038 小Z的袜子(莫队算法)