模拟退火

为什么叫退火请自行百度


过程

首先我们要知道爬山算法是什么:爬山就是单纯的贪心,遇到更优的解时才更新答案,但这样一来就可能陷入局部最优解中

模拟退火就通过一定概率取非最优值,尝试跳出这个坑

模拟退火有三个重要的参数:\(T_0\)(初始温度,要足够高),\(T_E\)(结束温度,略略大于 \(0\) 的正数)和 \(d\)(降温系数,略略小于 \(1\) 的数)

我们让初始温度为 \(T=T_0\),每次退火后 \(T\times d\),直到 \(T<T_E\) 结束

根据我们现在的 \(T\),我们得到一个解 \(E\),设它与目前最优解 \(E_0\) 的差为 \(\Delta\),如果 \(\Delta<0\),那么我们就接受这个解;否则,我们就有 \(e^{\frac{-\Delta}{T}}\)概率接受这个解(通过随机数实现)


例题

P1337 [JSOI2004]平衡点 / 吊打XXX

本题正解是计算几何,我不会

一个体系中,其能量越小,就越稳定

计算能量的方法为:\(dist\times w\),其中 \(dist\) 是物体到结点的距离,\(w\) 是物体的重量

这样我们就可以开始退火,亲测 \(T_0=3000,T_E=1e-14,down=0.997\),随机数种子为 \(time(0)+52071\),初始能量取 \(1e18\) 更大几率能过

#include<bits/stdc++.h>
#define down 0.997
#define LL long long
inline int reads()
{
    int sign = 1, re = 0; char c = getchar();
    while(c < '0' || c > '9'){if(c == '-') sign = -1; c = getchar();}
    while('0' <= c && c <= '9'){re = re * 10 + (c - '0'); c = getchar();}
    return sign * re;
}
int n;
struct thing
{
    int x, y, w;
}a[1005];
double ansx, ansy, answ;
inline double energy(double x, double y)
{
    double re = 0;
    for(int i = 1; i <= n; i++)
    {
        double dx = x - a[i].x, dy = y - a[i].y;
        re += sqrt(dx * dx + dy * dy) * a[i].w;
    }
    return re;
}
inline void anneal()
{
    double t = 3000, rx = ansx, ry = ansy;
    while(t > 1e-14)
    {
        double nx = rx + ((rand() << 1) - RAND_MAX) * t, ny = ry + ((rand() << 1) - RAND_MAX) * t;
        double nw = energy(nx, ny);
        double delta = nw - answ;
        if(delta < 0) ansx = rx = nx, ansy = ry = ny, answ = nw;
        else if(exp(-delta / t) * RAND_MAX > rand()) rx = nx, ry = ny;
        t *= down;
    }
}
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    srand(time(0) + 52071);
    n = reads();
    for(int i = 1; i <= n; i++) a[i] = (thing){reads(), reads(), reads()}, ansx += a[i].x, ansy += a[i].y;
    ansx /= n, ansy /= n; answ = 1e18;
    anneal(); anneal(); anneal();
    printf("%.3lf %.3lf", ansx, ansy);
    return 0;
}
posted @ 2022-04-15 08:18  zuytong  阅读(45)  评论(0编辑  收藏  举报