模拟退火 11 pts 求助!
查看原帖
模拟退火 11 pts 求助!
436107
Creeper_l楼主2023/10/15 16:09

交了好多发,一直 11 pts。

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define inf 0x3f
#define inf_db 127
#define ls id << 1
#define rs id << 1 | 1
#define re register
#define endl '\n'
typedef pair <int,int> pii;
const int MAXN = 1e3 + 10;
int n,x[MAXN],y[MAXN],w[MAXN];
double ansx,ansy,dis;
double calc(double nx,double ny)
{
	double res = 0;
	for(int i = 1;i <= n;++i)
	{
		double dx = x[i] - nx,dy = y[i] - ny;
		res += sqrt(dx * dx + dy * dy) * w[i];
	}
	if(res < dis) dis = res,ansx = nx,ansy = ny;
	return res;
} 
void SimulateAnneal()
{
	double t = 3000;
	double nowx = ansx,nowy = ansy;
	while(t > 1e-15)
	{
		double nxtx = nowx + t * ((rand() / RAND_MAX) * 2 - 1);
		double nxty = nowy + t * ((rand() / RAND_MAX) * 2 - 1);
		double delta = calc(nxtx,nxty) - calc(nowx,nowy);
		if(delta < 0 || exp(-delta / t) * RAND_MAX > rand()) nowx = nxtx,nowy = nxty;
		t *= 0.997;
	}
	for(int i = 1;i <= 1000;i++)
	{
		int nxtx = nowx + t * ((rand() / RAND_MAX) * 2 - 1);
		int nxty = nowy + t * ((rand() / RAND_MAX) * 2 - 1);
		calc(nxtx,nxty);
	}
} 
signed main()
{
	srand(time(0));
	cin >> n;
	for(int i = 1;i <= n;i++)
	{
		cin >> x[i] >> y[i] >> w[i];
		ansx += x[i],ansy += y[i];
	}
	ansx /= n,ansy /= n,dis = calc(ansx,ansy);
	SimulateAnneal();
	SimulateAnneal();
	SimulateAnneal();
	SimulateAnneal();
	printf("%.3lf %.3lf",ansx,ansy);
    return 0;
}



2023/10/15 16:09
加载中...