社区讨论

萌新求助模拟退火

学术版参与者 4已保存回复 7

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
7 条
当前快照
1 份
快照标识符
@lo8at85j
此快照首次捕获于
2023/10/27 15:35
2 年前
此快照最后确认于
2023/10/27 15:35
2 年前
查看原帖
本人想求出平均半径和每个点到目前的圆心的距离之差的和,根据和来判断答案的优劣,但运行结果非常离谱,求调。
CPP
#include <bits/stdc++.h>
#include <time.h>
#define d 0.996
using namespace std;
int n;
double ans, ansx[20];
struct node {
	double a[20];
} p[20];
double getans(double r,double x[]){
	double res=0;
	for (int i = 1; i <= n + 1; i++) {
		double nx = 0;
		for (int j = 1; j <= n; j++) {
			double tmp = x[j] - p[i].a[j];
			nx += tmp * tmp;
		}
		res += abs(sqrt(nx)-r);
	}
	return res;
}
double cal(double x[]) {
	double res = 0;
	for (int i = 1; i <= n + 1; i++) {
		double nx = 0;
		for (int j = 1; j <= n; j++) {
			double tmp = x[j] - p[i].a[j];
			nx += tmp * tmp;
		}
		res += sqrt(nx);
	}
	return res / (n + 1.0);
}

void SA() {
	double x[20];
	for (int i = 1; i <= n; i++) {
		x[i] = ansx[i];
	}
	double t = 2000;
	while (t > 1e-15) {
		double X[20];
		for(int i=1;i<=n;i++){
			X[i]=x[i]+((rand()<<1)-RAND_MAX)*t;
		}
		double r= cal(X);
		double now=getans(r,X);
		double delta=now-ans;
		if(delta<0){
			ans=now;
			for(int i=1;i<=n;i++){
				x[i]=ansx[i]=X[i];
			}
		}
		else if(exp(-delta/t)*RAND_MAX>rand()){
			for(int i=1;i<=n;i++){
				x[i]=X[i];
			}
		}
		t *= d;
	}
}

int main() {
	srand(time(0));
	scanf("%d", &n);
	for (int i = 1; i <= n + 1; i++) {
		for (int j = 1; j <= n; j++) {
			scanf("%lf", &p[i].a[j]);
			ansx[j] += p[i].a[j];
		}
	}
	ans = 1e8;
	for (int i = 1; i <= n; i++) {
		ansx[i] /= (n + 1);
	}
	SA();
	SA();
	SA();
	SA();
	SA();
	SA();
	SA();
	for (int i = 1; i <= n; i++) {
		printf("%0.3lf ", ansx[i]);
	}
	return 0;
}

回复

7 条回复,欢迎继续交流。

正在加载回复...