社区讨论

模拟退火求调❤

SP34RUNAWAY - Run Away参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lo15ejul
此快照首次捕获于
2023/10/22 15:29
2 年前
此快照最后确认于
2023/11/02 15:01
2 年前
查看原帖
CPP
#include<bits/stdc++.h>
#define int long long 
using namespace std;
namespace Testify{
    inline int read(){
        int f(1),x(0);
        char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
        for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
        return f*x;
    }
    inline void WritE(int x){
        if(x<0) putchar('-'),x=-x;
        if(x>9) WritE(x/10);
        putchar(x%10+48);
    }
    inline void write(int x){
        WritE(x);
        puts("");
    }
    inline void Write(int x){
        WritE(x);
        putchar(' ');
    }
}
using namespace Testify;
mt19937 rd(chrono::system_clock::now().time_since_epoch().count());
inline int radom(int l,int r){
    return rd()%(r-l+1)+l;
}
const int N=1005;
struct node{
    double x,y;
}point[N];
int T,X,Y,M;
double ansx,ansy,ans;
inline double energy(double x,double y){
    double Mn=1e18;
    for(register int i=1;i<=M;i++){
        Mn=min(Mn,sqrt((x-point[i].x)*(x-point[i].x)+(y-point[i].y)*(y-point[i].y)));
    }
    return Mn;
}
double nowx,nowy,now;
inline void SA(){
    double t=100;
    nowx=ansx,nowy=ansy,now=energy(nowx,nowy);
    while(t>1e-15){
        double ra=nowx+radom(-RAND_MAX,RAND_MAX)*t;
        double rb=nowy+radom(-RAND_MAX,RAND_MAX)*t;
        if(ra>X||ra<1||rb>Y||rb<1){
            t*=0.995;
            continue;
        }
        double e=energy(ra,rb);
        double delta=e-now;
        if(delta>0){
            now=e;
            nowx=ansx,nowy=ansy;
            if(e-ans>0){
                ans=e;
                ansx=ra,ansy=rb;
            }
        }
        else if(exp(delta/t)*RAND_MAX>radom(0,RAND_MAX)){
            nowx=ra,nowy=rb;
        }
        t*=0.995;
    }
}
signed main(void){
    T=read();
    while(T--){
        X=read(),Y=read(),M=read();
        for(register int i=1;i<=M;i++){
            point[i].x=1.0*read(),point[i].y=1.0*read();
        }
        ansx=radom(1,X),ansy=radom(1,Y);
        ans=energy(ansx,ansy);
        for(register int i=1;i<=504;i++){
            SA();
        }
        printf("The safest point is (%.1lf, %.1lf).\n",ansx,ansy);
    }
    return 0;
}
感觉挺板子的退火,但是不知道为什么WA了???

回复

3 条回复,欢迎继续交流。

正在加载回复...