社区讨论
萌新求助模拟退火
学术版参与者 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 条回复,欢迎继续交流。
正在加载回复...