机房最菜求助模拟退火
查看原帖
机房最菜求助模拟退火
567054
Catium楼主2022/5/18 22:13

刚学模拟退火,觉得写的挺对的( 降温什么的也都调过了,不知道咋就wa了,也没数据


#include <cmath>
#include <iostream>
using namespace std;

#define DEBUG(A) cout << A << endl

#define N 10100
#define eps 1e-15
#define down 0.9999

struct point {
    double x, y;
};
point p[N];
int n;
double dis(point p1, point p2) {
    return sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y));
}
double ans;
point ansp;
void sa() {
    for (double T = 3000; T > eps; T *= down) {
        point np;
        np.x = (rand() * 2 - RAND_MAX) * T;
        np.y = (rand() * 2 - RAND_MAX) * T;
        double nans = 0;
        for (int i = 1; i <= n; i++) {
            nans += dis(np, p[i]);
        }
        double dans = nans - ans;
        // DEBUG(dans);
        if (dans < eps) {
            ans = nans;
            ansp = np;
        } else {
            if (exp(-dans / T) * RAND_MAX > rand()) {
                ans = nans;
                ansp = np;
            }
        }
    }
}

signed main() {
    /*code here*/
    int T;
    cin >> T;
    while (T--) {
        cin >> n;
        ans = 0;
        ansp.x = 0;
        ansp.y = 0;
        for (int i = 1; i <= n; i++) {
            cin >> p[i].x >> p[i].y;
            ansp.x += p[i].x;
            ansp.y += p[i].y;
        }
        ansp.x /= n;
        ansp.y /= n;
        for (int i = 1; i <= n; i++) {
            ans += dis(ansp, p[i]);
        }
        sa();
        sa();
        sa();
        sa();
        printf("%0.0lf\n", ans);
        if (T) {
            printf("\n");
        }
    }
    return 0;
}

2022/5/18 22:13
加载中...