爬山算法和模擬退火算法


爬山算法

大體思路

爬山算法即是模擬爬山的過程,隨機選擇一個位置爬山,每次朝着更高的方向移動,直到到達山頂

具體操作

把當前的節點和要走的節點的值進行比較。 如果當前節點是最大的,那么不進行操作;反之就用要走的的節點來替換當前節點,從而實現向山峰的高處攀爬的目的。如此循環直到達到最高點。

缺點

會陷入局部最優解。只適用於計算幾何等局部最優解集中的題目。

例題 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\n",ans);
}
int main(){
	srand(1231435);
	while(~scanf("%d",&n)&&n)work();
	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM