感觉本题第一篇题解有问题
查看原帖
感觉本题第一篇题解有问题
704840
limuy楼主2023/12/3 10:27

1.我提交该题解100%ac,但是这是因为该题解没有加随机种子,加上就会使分数在60-100之间跳动 2.模拟退火应当设置一个全局最优解在每次sa后更新一次,如题解的做法,退火多次意义会变小,容易丢失最优解,我加上全局最优解后几乎可以做到全部ac

最后,如果该题解真的有问题,请求管理员撤下,否则会误导学习模拟退火的同学

附代码:

#include <bits/stdc++.h>
using namespace std;

//mt19937 myrand(time(0));
int n;
double globalx, globaly, globalenergy;
int xx[100000], yy[100000], w[100000];

double energy(double x, double y) {
	double r = 0;
	for(int i = 1; i <= n; ++i) {
		double dx = x - xx[i], dy = y - yy[i];
		r += sqrt(dx * dx + dy * dy) * w[i];
	}
	return r;
}

double ansx, ansy, answ;

void sa() {
	double t = 3000;
	while(t > 1e-15) {
		double ex = ansx + (rand() * 2 - RAND_MAX) * t;
		double ey = ansy + (rand() * 2 - RAND_MAX) * t;
		auto ew = energy(ex, ey);
		auto de = ew - answ;
		if(de < 0) {
			answ = ew;
			ansx = ex;
			ansy = ey;
		} else if(exp(-de / t) * RAND_MAX > rand()) {
			ansx = ex;
			ansy = ey;
		}
		t *= 0.996;
	}
}

int main() {
//	srand((unsigned)time(0));
	scanf("%d", &n);
	for(int i = 1; i <= n; ++i) {
		scanf("%d %d %d", &xx[i], &yy[i], &w[i]);
		ansx += xx[i];
		ansy += yy[i];
	}
	ansx /= n;
	ansy /= n;
    globalx = ansx;
    globaly = ansy;
	globalenergy = answ = energy(ansx, ansy);
    for(int i = 1; i <=4; ++i) {
        sa();
        if(answ < globalenergy) {
            globalx = ansx;
            globaly = ansy;
            globalenergy = answ;
        }
    }
	printf("%.3lf %.3lf", globalx, globaly);
	return 0;
}
2023/12/3 10:27
加载中...