模拟退火学习笔记

longdie

2020-12-31 14:53:01

Personal

# 模拟退火学习笔记 --- #### [学习链接](https://www.luogu.com.cn/blog/Darth-Che/mu-ni-tui-huo-xue-xi-bi-ji) 这一篇讲的很详细,但是前面似乎没啥用,主要看一遍他给的代码就够了。 还有就是看一看他给的注意点。 然后推荐一道例题(板子题) #### [题目链接](https://www.luogu.com.cn/problem/P1337) 这题建议直接看题解,就当板子题学习,不要管其他的计算几何。 然后是代码 : ``` #include <bits/stdc++.h> #define down 0.996 #define Max RAND_MAX using namespace std; int n; struct node { int x, y, w; } object[2005]; double ansx, ansy, answ; double suan(double x, double y) { double ans = 0, dx, dy; for(int i = 1; i <= n; ++i) { dx = x - object[i].x, dy = y - object[i].y; ans += sqrt(dx*dx + dy*dy) * object[i].w; } return ans; } void monituihuo() { double t = 10000; while(t > 1e-15) { double ex = ansx + (rand()*2 - Max)*t; double ey = ansy + (rand()*2 - Max)*t; double ew = suan(ex, ey); double cha = ew - answ; if(cha < 0) { ansx = ex, ansy = ey, answ = ew; } else if(exp(-cha / t) * Max > rand()) { ansx = ex, ansy = ey; } t *= down; } } void solve() { monituihuo(); monituihuo(); monituihuo(); monituihuo(); monituihuo(); } int main() { srand(0); cin >> n; for(int i = 1; i <= n; ++i) { cin >> object[i].x >> object[i].y >> object[i].w; ansx += object[i].x, ansy += object[i].y; } ansx /= n, ansy /= n, answ = suan(ansx, ansy); solve(); printf("%.3lf %.3lf", ansx, ansy); return 0; } ```