其他分享
首页 > 其他分享> > 模拟退火

模拟退火

作者:互联网

模拟退火

我觉得这是个 useless 的算法,只能说正解肯定和这算法毫无关系,你用这算法也别想拿满分,顶多是个不会做的题浪费你时间去赌这么些运气,而且是真的看脸。。。

先看张 oi-wiki 的图:

简单点想:

我们模拟分子运动的过程,随机选取答案,每次令答案跳跃一个距离,也就是随机移动,温度越高,跳的距离就可能越 浮躁 也就是大,温度越低,随机移动的距离就会慢慢减小,不断更新答案得到 “可能” 的最优解。

显然你开始的温度越高你就越可能得到答案,但是相对应的是时间的代价。

算法流程:

然后就是有一个小优化,为了防止TLE,可以直接判断当前运行的时间,也就是 while((double)clock() / CLOCKS_PER_SEC <= 0.997)(以题目时限自定义的时间) 然后如果不超时就继续退火,否则结束程序。

PS:模拟退火看脸,所以如果觉得分不够可以申请重测,会有惊喜也会有惊吓/qd

例题

这里就向量分解一下,然后直接按刚才的流程走就好了,注意 \(e^{x}\) 可以用 \(exp(x)\) 来得到。

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(int i=(a);i<(b);++i)
#define rrep(i,a,b) for(int i=(a);i>=(b);--i)
using namespace std;
template <typename T>
inline void read(T &x){
    x=0;char ch=getchar();bool f=0;
    while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    if(f)x=-x;
}
template <typename T,typename ...Args>
inline void read(T &tmp,Args &...tmps){read(tmp);read(tmps...);}
const double down = 0.996;
const int N = 2005;
const double eps = 1e-15;
int n;
struct qwq{
    int x,y,w;
}a[N];
mt19937 rnd(time(0));
double sx,sy,sw;
double energy(double x,double y){//代价
    double res = 0,dx ,dy;
    rep(i,1,n){
        dx = x - a[i].x;
        dy = y - a[i].y;
        res +=  sqrt(dx * dx + dy * dy) * a[i].w;
    }
    return res;
}
void tuihuo(){
    double t = 3000;
    while(t > eps){
        double ex = sx + (rand() * 2 - RAND_MAX) * t;
        double ey = sy + (rand() * 2 - RAND_MAX) * t;
        double ew = energy(ex,ey);
        double d = ew - sw;
        if(d < 0)sx = ex,sy = ey,sw = ew;//优
        else if(exp(-d / t) * RAND_MAX > rand())sx = ex,sy = ey;//劣则概率更新答案
        t *= down;
    }
}
void solve(){
    rep(i,1,4)tuihuo();
}
signed main(){
    srand(time(0));
    read(n);
    rep(i,1,n)read(a[i].x,a[i].y,a[i].w),sx += a[i].x,sy += a[i].y;
    sx /= n;sy /= n;sw = energy(sx,sy);
    solve();
    printf("%.3lf %.3lf\n",sx,sy);
}

标签:sy,ch,read,double,sx,模拟退火,答案
来源: https://www.cnblogs.com/wsxxs/p/16669002.html