求问关于模拟退火的正确率
查看原帖
求问关于模拟退火的正确率
798144
SukiYuri楼主2024/10/24 21:44

进来一看错题,SA,启动!

不过可以看到 SA 酱面对如此庞大的决策树还是比较吃力的,我调了一个小时参也没有AC,所以比较好奇这个算法的正确率是多少,求解答,玄关。

#include "bits/stdc++.h"

using namespace std;
using db=double;

const db eps=1e-16,mul=0.99913;
int d[105][105],c[105],ord[105];
bitset<105> ex[105],cu;
const int inf=0x3f3f3f3f;
int n,m,k,s,t,ans=inf;

inline int calc() {
    cu.reset();
    cu[c[s]]=1;
    int res=1e9,now=0,u=s;
    if(!ex[c[t]][c[s]]) res=d[t][s];
    for(int i=2;i<n;++i) {
        if((ex[c[ord[i]]]&cu).count()) {continue;}
        if(ex[c[t]][c[ord[i]]]) {continue;}
        if(d[u][ord[i]]==inf) {continue;}
        cu[c[ord[i]]]=1;
        now+=d[u][ord[i]];
        u=ord[i];
        if(d[u][t]!=inf)res=min(res,d[u][t]+now);
    }
    return res;
}
inline void SA() {
    for(db T=10000;T>eps;T*=mul) {
        int x=rand()%(n-2)+2,
            y=rand()%(n-2)+2;
        // if(x==y) continue;
        swap(ord[x],ord[y]);
        int now=calc();
        if(now<ans) ans=now;
        else if(exp(1.0*(ans-now)/T)<1.0*rand()/RAND_MAX)
            swap(ord[x],ord[y]);
    }
}
int main() {
    ios::sync_with_stdio(0);
    srand(114);
    cin>>n>>k>>m>>s>>t;
    memset(d,0x3f,sizeof(d));
    for(int i=1;i<=n;++i) {
        cin>>c[i];
        ord[i]=i;
    }
    swap(ord[s],ord[1]);
    swap(ord[t],ord[n]);
    for(int i=1;i<=k;++i) {
	    for(int j=1;j<=k;++j) {
	        bool x; cin>>x;
	        ex[i][j]=x;
	    }
	    ex[i][i]=1;
    }
    for(int i=1;i<=m;++i) {
        int u,v,w;
        cin>>u>>v>>w;
        d[u][v]=d[v][u]=min(d[u][v],w);
    }
    if(ex[c[t]][c[s]]) {
        cout<<-1;
        return 0;
    }
    if(n==2) {
    	if(d[s][t]==inf||
    	ex[c[t]][c[s]]) cout<<-1;
    	else cout<<d[s][t];
    	return 0;
    }
    while(1.0*clock()/CLOCKS_PER_SEC<0.9)SA();
    if(ans==inf) cout<<-1;
    else  cout<<ans;
    return 0;
}
2024/10/24 21:44
加载中...