zoukankan      html  css  js  c++  java
  • 爬山算法和模拟退火算法

    爬山算法

    大体思路

    爬山算法即是模拟爬山的过程,随机选择一个位置爬山,每次朝着更高的方向移动,直到到达山顶

    具体操作

    把当前的节点和要走的节点的值进行比较。 如果当前节点是最大的,那么不进行操作;反之就用要走的的节点来替换当前节点,从而实现向山峰的高处攀爬的目的。如此循环直到达到最高点。

    缺点

    会陷入局部最优解。只适用于计算几何等局部最优解集中的题目。

    例题 POJ2420

    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define maxn 105
    int n,go[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    double x[maxn],y[maxn],sx,sy;
    double calc(double x1,double y1){
    	double ans=0;
    	for(int i=0;i<n;i++){
    		ans+=sqrt((x1-x[i])*(x1-x[i])+(y1-y[i])*(y1-y[i]));
    	}
    	return ans;
    }
    int main(){
    	scanf("%d",&n);
    	for(int i=0;i<n;i++){
    		scanf("%lf%lf",x+i,y+i),sx+=x[i],sy+=y[i];
    	}
    	sx/=n,sy/=n;
    	double ans=calc(sx,sy),x1,y1,k;
    	for(double i=1e4;i>1e-3;i*=0.9){
    		for(int i=0;i<4;i++){
    			x1=sx+go[i][0]*i,y1=sy+go[i][1]*i;
    			k=calc(x1,y1);
    			if(k<ans){//如果x1,y1比sx,sy更优,就更新sx,sy,ans 
    				ans=k,sx=x1,sy=y1;
    			}
    		} 
    	}
    	printf("%.0lf",ans);
    	return 0;
    }

    模拟退火

    模拟退火和爬山只有一点不同:

    如果当前节点比要走的节点更优,则爬山一定不会跳到要走的节点
    但模拟退火有一定的几率会跳到要走的节点,并且这个几率越来越小

    例题:POJ2069 Super Star

    #include<cstdio>
    #include<cmath>
    #include<cstdlib>
    using namespace std;
    #define maxn 50
    int n,id;
    double x[maxn],y[maxn],z[maxn];
    inline double dis(double x1,double y1,double z1,double x2,double y2,double z2){
    	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
    }
    double calc(double x1,double y1,double z1){
    	double ans=dis(x1,y1,z1,x[0],y[0],z[0]),k;
    	id=0;
    	for(int i=1;i<n;i++){
    		if(ans<(k=dis(x1,y1,z1,x[i],y[i],z[i]))){
    			ans=k,id=i;
    		}
    	}
    	return ans;
    }
    void work(){
    	double sx=0,sy=0,sz=0,ans,k,x1,y1,z1;
    	for(int i=0;i<n;i++)scanf("%lf%lf%lf",x+i,y+i,z+i),sx+=x[i],sy+=y[i],sz+=z[i];
    	x1=sx/=n,y1=sy/=n,z1=sz/=n;
    	ans=k=calc(sx,sy,sz);
    	int si=0;
    	for(double i=1e2;i>1e-7;i*=0.98){
    		x1=sx+(x[id]-sx)/k*i;
    		y1=sy+(y[id]-sy)/k*i;
    		z1=sz+(z[id]-sz)/k*i;
    		k=calc(x1,y1,z1);
    		if(k<ans)ans=k;
    		if(k<ans||(1ll*rand()*rand()%100000)>++si)sx=x1,sy=y1,sz=z1;//如果不比原先优,则有一定几率去走 
    	}
    	printf("%.5lf
    ",ans);
    }
    int main(){
    	srand(1231435);
    	while(~scanf("%d",&n)&&n)work();
    	return 0;
    }
  • 相关阅读:
    JavaScript 、ECMAScript、commonJS 发展历史 与标准化发展
    jquey的 ajax请求的几种方式
    Flask web开发 处理Ajax请求
    Python 2.7 学习笔记 面向对象的编程
    Python 2.7 学习笔记 访问mysql数据库
    UI基础七:给普通其他界面的PRODUCT 添加标准的搜索帮助
    函数使用十二:BAPI_MATERIAL_BOM_GROUP_CREATE(CS61)
    ABAP游标
    UI基础六:UI报弹窗确认
    WDA基础十四:ALV字段属性配置表
  • 原文地址:https://www.cnblogs.com/bennettz/p/8565801.html
Copyright © 2011-2022 走看看