模拟退火 + nth_element求助
查看原帖
模拟退火 + nth_element求助
701221
Chr0n1CleC楼主2022/8/25 12:34

麻烦回复我的时候@我一下,不然我可能看不见

#include<stdio.h>
#define N 2009
#include<algorithm>
#include<stdlib.h>
#include<time.h>
#include<math.h>
using namespace std;

int n, m;

double ansx, ansy, ans, nowx, nowy, nx, ny, nowans;

struct node
{
	double x, y;
	inline bool operator < (const node& a)const
	{
		return ((nx - x) * (nx - x) + (ny - y) * (ny - y)) < ((nx - a.x) * (nx - a.x) + (ny - a.y) * (ny - a.y));
	}
}a[N];

inline double Rand() {return 1.0 * rand() / RAND_MAX;}

inline double calc()
{
	nth_element(a + 1, a + 1 + n, a + 1 + m);
	double ret = sqrt((a[m].x - nx) * (a[m].x - nx) + (a[m].y - ny) * (a[m].y - ny));
	if (ret < ans)
		ans = ret, ansx = nx, ansy = ny;
	return ret;
}

int main()
{
	srand(time(0));
	scanf("%d%d", &n, &m);
	for (int i = 1;i <= n;i ++)
		scanf("%lf%lf", &a[i].x, &a[i].y), ansx += a[i].x, ansy += a[i].y;
	ansx /= n, ansy /= n;
	nx = ansx, ny = ansy;
	ans = calc();
	while (1.0 * clock() / CLOCKS_PER_SEC < 0.95)
	{
		nowx = ansx, nowy = ansy, nowans = ans;
		double T = 1e3;
		while (T > 1e-9)
		{
			nx = nowx + (Rand() * 2 - 1), ny = nowy + (Rand() * 2 -  1);
			double sum = calc();
			double f = sum - nowans;
			if (exp(-f / T) > Rand())
				nowans = sum, ansx = nx, ansy = ny;
			T *= 0.999975;
		}
	}
	printf("%.7lf", ans);
	
	return 0;
}
2022/8/25 12:34
加载中...