赞
踩
#include<cstdio> #include<ctime> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> using namespace std; int s,way[1001],ans[1001]; double tem,mop,l[1001][1001]; bool flag[1001]; bool judge(double l)//概率选择 { double op=rand()/(double)RAND_MAX; return exp(l)>op; } int main() { scanf("%d",&s); for(int i=1;i<=s;++i) for(int j=1;j<=s;++j)scanf("%lf",&l[i][j]);//读入距离 srand(time(NULL)); flag[1]=1; way[1]=1; for(int i=2;i<=s;++i) { int k=rand()%(s-1)+2; while(flag[k])k=rand()%(s-1)+2; flag[k]=1; way[i]=k; tem+=l[way[i-1]][way[i]]; }//生成初始解 tem+=l[1][way[s]]; way[s+1]=1; mop=tem; way[s+1]=1; double fir=1000/*初始温度*/,op=0.98/*冷却速度*/; for(int i=1;i<=s+1;++i)ans[i]=way[i]; while(fir>=1e-4) { int o=rand()%(s-1)+2,p=rand()%(s-1)+2;// while(p==o)p=rand()%(s-1)+2;//随机寻找下一步 double add=0; swap(way[o],way[p]); for(int i=1;i<=s;++i)add+=l[way[i]][way[i+1]]; add-=tem; swap(way[o],way[p]); if(add<0)//如果更优,直接转移 { swap(way[o],way[p]); if(mop>tem+add) { mop=(tem+=add); for(int i=1;i<=s+1;++i)ans[i]=way[i]; } } else if(judge(add/fir))//否则根据Metropolis抽样稳定准则概率转移 { tem+=add; swap(way[o],way[p]); } fir*=op; } for(int i=1;i<=s;++i)printf("%d->",way[i]); printf("%d\n%lf\n",way[s+1],mop); return 0; } /* 5 0 3 3 2 6 3 0 7 3 2 3 7 0 2 5 2 3 2 0 3 6 2 5 3 0 */
知识链接:
Metropolis抽样稳定准则:若Δt′<0则接受S′作为新的当前解S,否则以概率exp(-Δt′/T)接受S′作为新的当前解S。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。