我刚学了一下模拟退火,我们机房大佬tx用它做了A+B,程序如下:
#include<bits/stdc++.h>
using namespace std;
const double startt=1e7,endt=1e-4,deltat=0.8;
long long a,b,ans;
int main()
{
srand(int(time(0)));
cin>>a>>b;
int ck=clock();
while(double(clock()-ck)/CLOCKS_PER_SEC<=0.8)
{
int nowans=ans;
double t=startt;
while(t>endt)
{
long long ntans=nowans+((rand()<<1)-RAND_MAX)*t;
if(abs(ntans-a-b)<abs(ans-a-b))
{
ans=ntans;
nowans=ntans;
}
else
if(exp(double(abs(ans-a-b)-abs(ntans-a-b))/t)>double(rand())/RAND_MAX)
{
nowans=ntans;
}
t*=deltat;
}
}
cout<<ans;
return 0;
}
经过激烈的讨论,有一部分我还是不懂:
if(exp(double(abs(ans-a-b)-abs(ntans-a-b))/t)>double(rand())/RAND_MAX)
我以为, 首先ans存全局最优解,ntans存局部最优解,则
abs(ans-a-b)-abs(ntans-a-b)
应表示(ans与a+b的差)与(ntans与a+b的差)两值的差,显然一定是非正数,且温度越低,这个值越大,那么它被接受的概率越大,越会成为可能的最优解。但,为什么要 /t 啊,这样不会使它在无论高温(更小的负数/大分母->数变大)或低温(更大的负数,小分母->数变大)都会增大接受概率(我不知道说得对不对),还有,exp()是什么意思啊
请大家帮帮我,谢谢。