题解到底是退火还是爬山?
查看原帖
题解到底是退火还是爬山?
104278
tyin楼主2021/7/14 13:22

初学模拟退火,开始按自己的思路写,调参WA了两页,得分在20到70不等

随后绷不住了 去看题解,开始逐字符调试 发现

if(rand() > exp(-del/T)*RAND_MAX) {
	//...
}

这部分我始终没法理解 感觉反过来了?

几乎每一篇题解,这里的del都为负,exp的结果大于1,这个判断条件应该是恒不成立的

然后我把自己的这部分删了 交

过了

。。。。。?


void SA(){
    double nx = bstx, ny = bsty;
    double Tem = 2625;
    while(Tem > 1e-15){
        double tx = nx + Tem * (rand()*2 - RAND_MAX);
        double ty = ny + Tem * (rand()*2 - RAND_MAX);
        double cnt = getAns(tx,ty);
        double del = cnt - ans;
        if(del > 0){
            nx = tx;
            ny = ty;
            bstx = tx;
            bsty = ty;
            ans = cnt;
        }else{
//            double p = exp(-del/Tem );
//            if(rand() > p*RAND_MAX){
//                nx = tx;
//                ny = ty;
//            }
        }
        Tem *= 0.9972;
    }
}

提交记录

愣住了

想知道把这个地方反过来写是基于什么样的思路

是我有问题还是题解有问题?

完整ac代码

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <stack>
#include <list>
#include <time.h>
using namespace std;
#define ll long long
#ifdef ACM_LOCAL
const ll maxn = 1005;
#else
const ll maxn = 2000;
#endif
double eps=0.000000001;
ll mode=998244353;
ll INF = 1e18;
void swap(ll *a, ll *b){ll ins=*a;*a=*b;*b=ins;}
bool equal(double x,double y){return x-y<eps && x-y>-eps;}

struct node{
    double x,y,r;
}h[maxn],p[maxn];

double Mxr;
double bstx,bsty;
int n,m;
double ans = 0;
double dis(double x,double y,node hs){
    return sqrt((hs.x-x)*(hs.x-x) + (hs.y-y)*(hs.y-y));
}

double getAns(double x,double y){
    double r = Mxr;
    for(int i=1;i<=n;i++){
        r = min(r, dis(x,y,h[i]) - h[i].r);
    }
    double cnt = 0;
    for(int i=1;i<=m;i++){
        if(dis(x,y,p[i]) <= r) cnt++;
    }
    return cnt;
}

void SA(){
    double nx = bstx, ny = bsty;
    double Tem = 2625;
    while(Tem > 1e-15){
        double tx = nx + Tem * (rand()*2 - RAND_MAX);
        double ty = ny + Tem * (rand()*2 - RAND_MAX);
        double cnt = getAns(tx,ty);
        if(cnt > ans){
            nx = tx;
            ny = ty;
            bstx = tx;
            bsty = ty;
            ans = cnt;
        }else{
//            double p = exp((ans - cnt)/Tem );
//            if(rand() > p*RAND_MAX){
//                nx = tx;
//                ny = ty;
//            }
        }
        Tem *= 0.9972;
    }
}

void solve(){
    scanf("%d%d%lf",&n,&m,&Mxr);
    for(int i=1;i<=n;i++){
        scanf("%lf%lf%lf",&h[i].x,&h[i].y,&h[i].r);
    }
    bstx = bsty = 0;
    for(int i=1;i<=m;i++){
        scanf("%lf%lf",&p[i].x,&p[i].y);
        bstx += p[i].x;
        bsty += p[i].y;
    }
    bstx/=m;
    bsty/=m;
    while((double)clock()/CLOCKS_PER_SEC < 0.85)
        SA();
    printf("%.0lf\n",ans);
}

signed main() {
#ifdef ACM_LOCAL
    freopen("x.txt","r",stdin);
#endif
    srand((int)time(0));
    ll T = 1;
//    scanf("%lld",&T);
    while(T--){
        solve();
    }
    return 0;
}
2021/7/14 13:22
加载中...