模拟退火求救
查看原帖
模拟退火求救
428690
Astatinear楼主2022/4/24 17:17

模拟退火,对着题解调了很久,但不知道哪里挂了。

#include<bits/stdc++.h>
using namespace std;
int n;
struct node
{
	int x,y,w;
}arr[1005];
double energy(double x,double y)
{
	double p=0;
	for(int i=1;i<=n;++i)
	{
		double dx=x-arr[i].x;
		double dy=y-arr[i].y;
		p+=sqrt(dx*dx+dy*dy)*arr[i].w;
	}
	return p;
}
double ansx,ansy,ans;
#define end 1e-9
#define delta 0.996
#define times 10
void init()
{
	srand(time(0));
	for(int i=1;i<=n;++i)
	ansx+=arr[i].x,ansy+=arr[i].y;
	ansx/=n,ansy/=n;
	ans=energy(ansx,ansy);
}
void sa()
{
	double tem=3000;
	while(tem>end)
	{
		double nowx=ansx+(rand()*2-RAND_MAX)*tem;
		double nowy=ansy+(rand()*2-RAND_MAX)*tem;
		double now=energy(nowx,nowy);
		double dnow=now-ans;
		if(dnow<0)
		{
			ans=now;
			ansx=nowx;
			ansy=nowy;
		}
		else if(exp(-delta/tem)*RAND_MAX>rand())
		{
			ansx=nowx;
			ansy=nowy;	
		}
		tem*=delta;
	}
}
void solve()
{
	init();
	sa();
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	{
		scanf("%d %d %d",&arr[i].x,&arr[i].y,&arr[i].w);
	}
	solve();
	printf("%.3lf %.3lf\n",ansx,ansy);
	return 0;
}
2022/4/24 17:17
加载中...