1 条题解
-
0XzyStudio (admin) LV 8 MOD RP++ 机房蒟蒻 tayz @ 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