POJ 2420

退火 爬山 实验田

爬山

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>


using namespace std;
const int maxn = 20000;
int n;
double x[maxn],y[maxn];

double dist(double x1,double x2,double y1,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double getsum(double x1,double y1){
	double ret = 0;
	for(int i = 1;i <= n;i++)
		ret+=dist(x1,x[i],y1,y[i]);
	return ret;
}

int main()
{
	scanf("%d",&n);
	double ans,ansx,ansy;
	ansx = 0;ansy = 0.0;
	for(int i = 1;i <= n;i++){
		scanf("%lf%lf",&x[i],&y[i]);
		ansx+=x[i];
		ansy+=y[i];
	}
	ansx/=n;ansy/=n;
	ans = getsum(ansx,ansy);
	double T = 1000.0;
	while(T >= 0.01){
		double xx = 0.0,yy = 0.0;
		for(int i = 1;i <= n;i++){
			xx += (x[i]-ansx)/dist(ansx,x[i],ansy,y[i]);
			yy += (y[i]-ansy)/dist(ansx,x[i],ansy,y[i]);
		}
		double tmp = getsum(ansx+xx*T,ansy+yy*T);
		if(tmp < ans){
			ans = tmp;
			ansx += xx*T;
			ansy += yy*T;
		}
		T*=0.9;
	}
	printf("%d\n",(int)(ans+0.5));
	return 0;
}

爬山是只接受更好的,所以可能会鼠目寸光,然而,可以选择一个关于温度的函数来随机选择为了更长远的利益变成个傻逼,温度越低就越不冒险,
其实就加一句话

		if(tmp < ans){ans = tmp;ansx += xx*T;ansy += yy*T;}
		else if(log((tmp-ans)/T) > (rand()%10000)/10000.0){
			ans = tmp;ansx += xx*T;ansy += yy*T;
		}

所有就能保证得到最优。

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>


using namespace std;
const int maxn = 20000;
int n;
double x[maxn],y[maxn];

double dist(double x1,double x2,double y1,double y2)
{
	return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}

double getsum(double x1,double y1){
	double ret = 0;
	for(int i = 1;i <= n;i++)
		ret+=dist(x1,x[i],y1,y[i]);
	return ret;
}

int main()
{
	scanf("%d",&n);
	double ans,ansx,ansy;
	ansx = 0;ansy = 0.0;
	for(int i = 1;i <= n;i++){
		scanf("%lf%lf",&x[i],&y[i]);
		ansx+=x[i];
		ansy+=y[i];
	}
	ansx/=n;ansy/=n;
	ans = getsum(ansx,ansy);
	double T = 1000.0;
	while(T >= 0.01){
		double xx = 0.0,yy = 0.0;
		for(int i = 1;i <= n;i++){
			xx += (x[i]-ansx)/dist(ansx,x[i],ansy,y[i]);
			yy += (y[i]-ansy)/dist(ansx,x[i],ansy,y[i]);
		}
		double tmp = getsum(ansx+xx*T,ansy+yy*T);
		if(tmp < ans){ans = tmp;ansx += xx*T;ansy += yy*T;}
		else if(log((tmp-ans)/T) > (rand()%10000)/10000.0){
			ans = tmp;ansx += xx*T;ansy += yy*T;
		}
		T*=0.9;
	}
	printf("%d\n",(int)(ans+0.5));
	return 0;
}
posted @ 2017-07-29 21:54  rsqppp  阅读(81)  评论(0)    收藏  举报