1 条题解

  • 0
    @ 2024-03-06 20:10:58

    模拟退火具体内容在这里不过多解释,这里只给出自己的模拟退火代码供大家参考。

    您可以提交本代码,看看多少次能AC本题

    #include<bits/stdc++.h>
    #define MAXN 1010
    using namespace std;
    
    struct Object{
        int x, y, w;
    }obj[MAXN];
    int n;
    double aw, ax, ay;
    
    double t = 5000, td=0.998, t0 = 1e-15, c=3; // t为温度(初始),td为每次退火,t0为结束温度,c为值域常量
    
    double energy(double x, double y){ // 计算动能
        double ret=0;
        for(int i=0; i<n; i++){
            ret += sqrt((x-obj[i].x) * (x-obj[i].x) + (y-obj[i].y) * (y-obj[i].y))*obj[i].w;
        }
        return ret;
    }
    
    void sa(){
        while(t >= t0) {
            double ex = ax + (rand()*c - RAND_MAX) * t; // 通过更改c来控制值域
            double ey = ay + (rand()*c - RAND_MAX) * t;
            double ew = energy(ex, ey);
            double de = ew - aw; // 计算随机跳的这个与当前最优解的差
            if (de < 0 || exp(-de/t)*RAND_MAX > rand()){ // 答案更优或以一定概率接受
                ax = ex, ay = ey;
                if (de < 0) aw = ew; // 注意只有在答案更优时更新最优答案
            }
            t *= td; // 降温
        }
    }
    
    int main(){
        srand(time(0));
        
        cin>>n;
        for(int i=0; i<n; i++){
            cin>>obj[i].x>>obj[i].y>>obj[i].w;
            ax += obj[i].x;
            ay += obj[i].y;
        }
        ax /= n; ay /= n;
        aw = energy(ax, ay);
        sa();
        printf("%.3lf %.3lf", ax, ay);
        return 0;
    }
    
  • 1

平衡点 / 【模版】模拟退火

信息

ID
1045
难度
9
分类
模拟退火搜索 | 概率论 | NPC 点击显示
标签
递交数
107
已通过
1
通过率
1%
上传者